0

first timer here.

I am attempting to code an arm assembly morse code translator on my raspberry pi 3. The program should read the string literal (x), take the corresponding morse code string (h) and scan through the string (".... ") and output a dot on the LED set up on my breadboard for every period in the string.

My original code involved actually having a whole word to be scanned character by character and translated. My LED would just light up way before a function for lighting up the LED was even called and the program would stall. So I made this side program to try and translate only a single letter [in this case "H"] and have it output correctly on my LED.

My issue here is that I cannot get the code to loop back to LED_lp: (via exit_if:) after it branches into the dot: function in order to output the dots in the ".... " string out on the LED.

I've tried numerous things, including

  • pushing {lr} / popping {pc} in different areas of the labels in case it had something to do with the stack
  • moving away from the primary registers (r0, r1, etc.) in case it was conflicting with the wiringPi commands

[which I came to the conclusion that it does conflict, even if you are not trying to load a pin number or calling pinMode, it seemed that loading registers r0, r1 with values like 0 and 1 caused premature and unwanted changes to the pin modes / LED outputs.] Please let me know if I am incorrect about that conclusion.

Even my assembly professor was unsure of what was wrong with my code or why my LED output was not behaving properly when reviewing my original.

Apologies for the wall of text, but I assumed that a little extra backstory would save some time and avoid vagueness. I hope someone is able to assist, as I need to implement this to my final project.

Thanks in advance

  .equ MY_PIN, 25
  .equ OUTPUT, 1
  .equ INPUT, 0
  .equ LOW, 0
  .equ HIGH, 1

  .data
  x:  .asciz "H"

  h:  .asciz "...."

  .text
  .global main

  main:
  push {lr}

  bl wiringPiSetup

  ldr r4, =x
  mov r5, #0

  lp: 
  mov r6, r4        // mov r4 [x] into r6
  cmp r6, #72       // check if r6 = H ascii code
  beq _do_H         // if equal branch to _do_H


  _do_H:
  ldr r4, =h
  bl LED

  LED:
  push {lr}
  mov r5, #0

  LED_lp:
  ldrb r6, [r4, +r5]  // scan for first char in r6
  cmp r6, #0        // cmp , if string done branch to exit_if
  beq exit_LED
  cmp r6, #46       // cmp, if first char is dash, branch to dash_check
  bne check_dash
  bl dot        // else branch to dot


  check_dash:
  cmp r6, #45
  beq dash

  exit_if:
  add r5, #1    // increment index for string scan
  bal LED_lp

  exit_LED:
  pop {pc}

  dot:   
  push {r0, r1,r2}

  mov r0, #MY_PIN
  mov r1, #HIGH
  bl digitalWrite

  mov r0, #100       
  bl delay

  mov r0, #MY_PIN
  mov r1, #LOW
  bl digitalWrite

  // bl exit_if   $$ having this line BEFORE the pop causes LED to stay on
  // for more than 100 ms, but seems to terminate the program after it
  // lights up


  pop {r0, r1,r2}

  // bl exit_if $$ having this line AFTER the pop causes the led to stay on
  // $$ for longer than 100 ms, and gets the program stuck running? after
  // $$   execution

  dash:      // commented out dash to work on dot, left here for reference
  //  push {lr}
  push {r0,r1,r2}

   //   mov r0, #MY_PIN
   //   mov r1, #HIGH
   //   bl digitalWrite

  //    mov r0, #1000
  //    bl delay

  //    mov r0, #MY_PIN
  //    mov r1, #LOW
  //    bl digitalWrite
  pop {r0,r1,r2}
   //   pop {pc}

   /////////end
  • This code has plenty of obvious bugs in it - the completely redundant `beq _do_H`, the infinite loop started by `bl LED`, the lack of any return from `main` anyway, etc. - but it isn't at all clear whether those are issues present in the original code you're trying to debug. As it stands this seems to fail the M and V of [mcve]. – Notlikethat Dec 10 '16 at 15:27
  • @Notlikethat Could you elaborate on how an infinite loop is started by `bl LED` ? The `LED:` and `LED_lp:` labels were essentially my loops to scan thru the string and check for each character, and I _ideally_ wanted the loop to end when the scan reached the null terminator - hence the `cmp r6, #0` and `beq exit_LED` . My original code included having the morse code string `".... "` be printed out by printf as well as having it output on LED, but the code that I posted here was supposed to be only the stuff that I thought was necessary to fix my LED output. – Decypherous Dec 10 '16 at 18:37
  • Condensed: `bl . + 4; push {lr}; pop {pc}` - consider what address is in LR when the push executes, and thus where the pop returns to. I'm assuming there was originally some more code in between the call and the label. – Notlikethat Dec 13 '16 at 00:22

0 Answers0