f4nt4st1ck
Posts: 4
Joined: Mon Dec 02, 2019 3:44 pm

i created a Led assembly that makes ON/OFF in a loop, but how can i create an SOS code in assembly?

Tue Dec 03, 2019 3:38 pm

Hello Guys
i created a Led assembly that makes ON/OFF in a loop, but how can i create an SOS code in assembly?

Can someone help me?
Last edited by f4nt4st1ck on Wed Dec 04, 2019 1:29 am, edited 1 time in total.

LdB
Posts: 1311
Joined: Wed Dec 07, 2016 2:29 pm

Re: How can i create S.O.S morse code @ Assembly

Tue Dec 03, 2019 4:12 pm

Turn the on off into a subroutine with a delay time (long and short) carry the delay value in R0

So an S is

Code: Select all

Flash led(short)
Fixed_Delay
Flash led(short)
Fixed_Delay
Flash led(short)
Fixed_Delay
An O is

Code: Select all

Flash led(long)
Fixed_Delay
Flash led(long)
Fixed_Delay
Flash led(long)
Fixed_Delay

f4nt4st1ck
Posts: 4
Joined: Mon Dec 02, 2019 3:44 pm

Re: How can i create S.O.S morse code @ Assembly

Tue Dec 03, 2019 4:34 pm

Hi LdB

how exactly do you mean it?

LdB
Posts: 1311
Joined: Wed Dec 07, 2016 2:29 pm

Re: How can i create S.O.S morse code @ Assembly

Wed Dec 04, 2019 12:50 am

Just refactor your code with subroutines, let me do it long form

The hint there is you can refactor it even smaller by simply adding more functions, I added just two
LED_ON_FOR_DELAY_LOOP, LED_OFF_FOR_DELAY_LOOP
You could actually bring them down to a single function with a more complex entry

Code: Select all

.section .init
.global _start

.equ BASE,  0x3f200000 @Base address
.equ GPFSEL2, 0x08			@FSEL2 register offset
.equ GPSET0,  0x1c			@GPSET0 register offset
.equ GPCLR0,0x28			@GPCLR0 register offset
.equ SET_BIT3,   0x08		@sets bit three b1000
.equ SET_BIT21,  0x200000 	@sets bit 21
.equ COUNTER, 0xf0000

.equ OFF_DELAY, 0xf0000
.equ LONG_DELAY, 0xf0000
.equ SHORT_DELAY, 0x40000

_start:

ldr r0,=BASE
ldr r2,=COUNTER
ldr r1,=SET_BIT3
str r1,[r0,#GPFSEL2]
ldr r1,=SET_BIT21
str r1,[r0,#GPSET0]

ldr r3,=SET_BIT3
str r3,[r0,#GPFSEL2]

Infinite_loop:

    ;@ >>>> send S which is 3 short ons <<<<< 
    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 


    ;@ >>>> send O which is 3 long ons <<<<< 
    ldr r2, LONG_DELAY  ;@ long delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, LONG_DELAY  ;@ long delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, LONG_DELAY  ;@ long delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ;@ >>>> send S which is 3 short ons <<<<< 
    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ;@ >>>>  OUTPUT EXTRA LONG OFF BETWEEN WORDS <<<<< 

    ldr r2, OFF_DELAY *4      ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 
b Infinite_loop

;@"========================================================================="
@#		LED_ON_FOR_DELAY FUNCTION
@#		Entry: Set R0 base,   R1 carries the port value to set,  R2 carries delay count
@#          Trashed: R10
;@"========================================================================="
LED_ON_FOR_DELAY_LOOP:
    str r1,[r0,#GPSET0]  ;[email protected] turn the LED ON
    mov r10,#0
    delay:@loop to large number
      add r10,r10,#1
      cmp r10,r2      ;@ Remember R2 is carrying the delay count
      bne delay
      bx  lr	

;@"========================================================================="
@#		LED_OFF_FOR_DELAY FUNCTION
@#		Entry: Set R0 base,   R1 carries the port value to clear,  R2 carries delay count
@#          Trashed: R10
;@"========================================================================="
LED_OFF_FOR_DELAY_LOOP:
    str r1,[r0,#GPCLR0]  ;[email protected] turn the LED OFF
    mov r10,#0
    delay1:@loop to large number
      add r10,r10,#1
      cmp r10,r2      ;@ Remember R2 is carrying the delay count
      bne delay1
      bx  lr	

f4nt4st1ck
Posts: 4
Joined: Mon Dec 02, 2019 3:44 pm

Re:

Wed Dec 04, 2019 1:30 am

LdB wrote:
Wed Dec 04, 2019 12:50 am
Just refactor your code with subroutines, let me do it long form

The hint there is you can refactor it even smaller by simply adding more functions, I added just two
LED_ON_FOR_DELAY_LOOP, LED_OFF_FOR_DELAY_LOOP
You could actually bring them down to a single function with a more complex entry

Code: Select all

.section .init
.global _start

.equ BASE,  0x3f200000 @Base address
.equ GPFSEL2, 0x08			@FSEL2 register offset
.equ GPSET0,  0x1c			@GPSET0 register offset
.equ GPCLR0,0x28			@GPCLR0 register offset
.equ SET_BIT3,   0x08		@sets bit three b1000
.equ SET_BIT21,  0x200000 	@sets bit 21
.equ COUNTER, 0xf0000

.equ OFF_DELAY, 0xf0000
.equ LONG_DELAY, 0xf0000
.equ SHORT_DELAY, 0x40000

_start:

ldr r0,=BASE
ldr r2,=COUNTER
ldr r1,=SET_BIT3
str r1,[r0,#GPFSEL2]
ldr r1,=SET_BIT21
str r1,[r0,#GPSET0]

ldr r3,=SET_BIT3
str r3,[r0,#GPFSEL2]

Infinite_loop:

    ;@ >>>> send S which is 3 short ons <<<<< 
    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 


    ;@ >>>> send O which is 3 long ons <<<<< 
    ldr r2, LONG_DELAY  ;@ long delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, LONG_DELAY  ;@ long delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, LONG_DELAY  ;@ long delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ;@ >>>> send S which is 3 short ons <<<<< 
    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ldr r2, SHORT_DELAY  ;@ short delay
    ldr r1,=SET_BIT3          ;@ port to turn on
    bl  LED_ON_FOR_DELAY_LOOP  ;@ call function
    ldr r2, OFF_DELAY       ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 

    ;@ >>>>  OUTPUT EXTRA LONG OFF BETWEEN WORDS <<<<< 

    ldr r2, OFF_DELAY *4      ;@ normal off delay
    ldr r1,=SET_BIT3         ;@ port to turn off
    bl  LED_OFF_FOR_DELAY_LOOP ;@ call function 
b Infinite_loop

;@"========================================================================="
@#		LED_ON_FOR_DELAY FUNCTION
@#		Entry: Set R0 base,   R1 carries the port value to set,  R2 carries delay count
@#          Trashed: R10
;@"========================================================================="
LED_ON_FOR_DELAY_LOOP:
    str r1,[r0,#GPSET0]  ;[email protected] turn the LED ON
    mov r10,#0
    delay:@loop to large number
      add r10,r10,#1
      cmp r10,r2      ;@ Remember R2 is carrying the delay count
      bne delay
      bx  lr	

;@"========================================================================="
@#		LED_OFF_FOR_DELAY FUNCTION
@#		Entry: Set R0 base,   R1 carries the port value to clear,  R2 carries delay count
@#          Trashed: R10
;@"========================================================================="
LED_OFF_FOR_DELAY_LOOP:
    str r1,[r0,#GPCLR0]  ;[email protected] turn the LED OFF
    mov r10,#0
    delay1:@loop to large number
      add r10,r10,#1
      cmp r10,r2      ;@ Remember R2 is carrying the delay count
      bne delay1
      bx  lr	
Ah now i got it, make a simple function end of a loop and use wir "bl" - thank u mate!

Return to “Bare metal, Assembly language”