How do I display on the 8-segment display when I presses a certain number on the keyboard lets say its in the 12th place - arm

I need to show an E on the 8-segment display, I have the E ready but I can't get it to show when someone hits certain numbers on the keypad.
THIS IS FOR ARMSIM
swi 0x203
cmp r3, #2
BEQ fwd
cmp r0, #7
BEQ fwd
cmp r0, #11
BEQ fwd
cmp r0, #12
BEQ fwd
cmp r0, #14
BEQ fwd
cmp r0, #15
BEQ fwd
B Done
fwd:
mov r0, #E
swi 0x200
Done:
;second attempt
cmp r0, #0x04
moveq r1,#0x04
BEQ fwd
cmp r0, #0x08
moveq r1,#0x08
BEQ fwd
cmp r0, #0x12
moveq r1,#0x12
BEQ fwd
cmp r0, #0x13
moveq r1,#0x13
BEQ fwd
cmp r0, #0x15
moveq r1,#0x15
BEQ fwd
cmp r0, #0x16
moveq r1,#0x16
BEQ fwd
B Done
fwd:
mov r0, #E
swi 0x200
Done:
;I tried 2 ways but none of them work!

Related

ARM assembly output isn't functioning correctly

This is supposed to output the contents of each line in arm assembly. Though line 18 add r4, r5, r4, lsl #1 isn't being outputted correctly and I am not sure why.
.data
str1: .asciz "%d and %d are the results \n"
n: .word word 1
.text
.global main
main: stmfd sp!, {lr}
ldr r4,=n
ldr r4, [r4]
add r4,r4, #1
mov r1, r4
ldr r0, =str1
bl printf
mov r5, r4
mov r1, r4
mov r2, r5
ldr r0, =str1
bl printf
add r4, r5, r4, lsl #1
mov r1, r4
ldr r0, = str1
bl printf
ldmfd sp!, {lr}
mov r0, #0
mov PC, or
.end

How to produce double digits numbers LC3

Having trouble printing any number past 10 in my LC3 program to multiply 2 input numbers to get a area. It works for any numbers below 10 so I know my multiplication is right. The problem is it produces weird symbols or nonsense anywhere higher then 10. So confused why. Here is my code:
.ORIG x3000
AND R3, R3, #0
AND R4, R4, #0
LD R5, INVERSE_ASCII_OFFSET
LD R6, DECIMAL_OFFSET
;---------------------
;receiving length
LEA R0, PROMPT1 ;load the address of the 'PROMPT1' message string
PUTS ;Prints PROMPT1
GETC ;get length
ADD R1, R0, #0
ADD R1, R1, R5
;receving width
LEA R0, PROMPT2 ;load the address of the 'PROMPT2' message string
PUTS ;Prints PROMPT2
GETC ;get width
ADD R2, R0, #0
ADD R2, R2, R5
;----------------------
;MULTIPLICATION to find AREA
ADD R4, R2, #0
FINDAREA:
ADD R3, R3, R1
ADD R4, R4, #-1
BRp FINDAREA
LEA R0, PROMPT3
PUTS
ADD R0, R3, R6
OUT
HALT
PROMPT1 .STRINGZ "ENTER LENGTH OF THE RECTANGLE:"
PROMPT2 .STRINGZ "ENTER WIDTH OF THE RECTANGLE:"
PROMPT3 .STRINGZ "AREA OF THE RECTANGLE:"
INVERSE_ASCII_OFFSET .fill xFFD0
DECIMAL_OFFSET .fill #48
.END```

Debugging ARM Assembly Context Switch

I'm working on a context switch in ARM v6 assembly. I posted about writing the switch in C, but assembly seems to be safer and more reliable. I've spent a while checking all the offsets and being careful not to delete data from registers, but the context switch just doesn't seem to work properly. I have set up and tested timer interrupts without switching context.
Here's my code:
interrupt_asm:
//store basic interrupt stuff
sub lr, lr, #4
//call the interrupt vector
push { r0-r12 }
mov r0, lr # Pass old pc
bl interrupt_vector # C function
pop { r0-r12 }
# save_current_thread:
//remember r1 so you can use it for r0
push {r1}
mov r1, r0 //store r0 so it can be restored
push {r2, r3}
bl get_current_thread //r0 now has the address of CURRENT_THREAD
pop {r2, r3}
add r0, r0, #4 // r0 = &CURRENT_THREAD.r0
str r1, [r0] // save what the r0 was
pop {r1} // restore r1
add r0, r0, #4 // r0 = &CURRENT_THREAD.r1
str r1, [r0] // save r1
//r2
add r0, r0, #4
str r2, [r0]
//r3
add r0, r0, #4
str r3, [r0]
//r4
add r0, r0, #4
str r4, [r0]
//r5
add r0, r0, #4
str r5, [r0]
//r6
add r0, r0, #4
str r6, [r0]
//r7
add r0, r0, #4
str r7, [r0]
//r8
add r0, r0, #4
str r8, [r0]
//r9
add r0, r0, #4
str r9, [r0]
//r10
add r0, r0, #4
str r10, [r0]
//r11
add r0, r0, #4
str r11, [r0]
//r12
add r0, r0, #4
str r12, [r0]
//store SVC sp, lr, and pc
mrs r1, cpsr
bic r1, r1, #0x1F
orr r1, r1, #0x13
msr cpsr_c, r1
//sp
add r0, r0, #4
str sp, [r0]
//lr
add r0, r0, #4
str lr, [r0]
//back to IRQ land
mrs r1, cpsr
bic r1, r1, #0x1F
orr r1, r1, #0x12
msr cpsr_c, r1
//pc THIS NEEDS TO BE LR
add r0, r0, #4
str lr, [r0]
//cpsr
add r0, r0, #4
mrs r1, cpsr
str r1, [r0]
//spsr
add r0, r0, #4
mrs r1, spsr
str r1, [r0]
push {r2, r3}
bl increment_thread //r0 now has the address of our next thread
pop {r2, r3}
# restore_thread:
//were pushing in order, so from the bottom up our stack is: r0, ... r12, sp, lr, pc, spsr
add r0, r0, #4 //r0 = &CURRENT_THREAD.r0
ldr r1, [r0] //r1 = thread.r0
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r1
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r2
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r3
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r4
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r5
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r6
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r7
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r8
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r9
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r10
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r11
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.r12
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.sp
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.lr
push {r1}
add r0, r0, #4
ldr r1, [r0] //r1 = thread.pc
push {r1}
add r0, r0, #8 //skip cpsr - agreed
ldr r1, [r0] //r1 = thread.spsr
push {r1}
//Our stack now looks like spsr, pc, lr, sp, r12, ... r0 (in order of popping)
pop {r1} //this was the spsr - SPSR
pop {lr} //this was the pc - PC (from thread)
pop {r2} //this was the lr - LR (from thread)
pop {r3} //this was the sp - SP (from thread)
//switch to SVC
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0x13
msr cpsr_c, r0
msr spsr, r1 //restore spsr
mov lr, r2 //restore lr to be old lr
mov sp, r3 //restore sp
//switch to IRQ
// mrs r0, cpsr
// bic r0, r0, #0x1F
// orr r0, r0, #0x12
// msr cpsr_c, r0
cps #0x12
//our stack now just has the normal registers in it. Restore them
pop {r12}
pop {r11}
pop {r10}
pop {r9}
pop {r8}
pop {r7}
pop {r6}
pop {r5}
pop {r4}
pop {r3}
pop {r2}
pop {r2}
pop {r1}
pop {r0}
push {lr}
ldm sp!, {pc}^
A thread looks like this:
typedef struct __attribute__((packed, aligned(8))) {
void (*run)();
unsigned r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc;
unsigned cpsr, spsr;
unsigned id;
unsigned priority;
thread_status status;
wait_event wait_status;
} thread_t;
Do you have any advice about what's going on? An interrupt occurs and it never goes back to a new thread. I've debugged with GDB simulator but can't seem to nail down the issue.
The C function interrupt_vector just does this:
void interrupt_vector(unsigned pc) {
CURRENT_THREAD.pc = pc;
printf(" interrupt vector (pc = 0x%08x | thread.r0 = 0x%08x)\n", pc, CURRENT_THREAD.r0);
armtimer_clear_interrupt();
}
My other C functions are literally one line, and I've looked at their disassembly:
void increment_thread(){
// Not trying to actually increment yet
__asm__ volatile("mov r0, %0" : : "r" ((unsigned) &CURRENT_THREAD));
}
void get_current_thread(){
__asm__ volatile("mov r0, %0" : : "r" ((unsigned) &CURRENT_THREAD));
}

Symmetric difference in ARM

I am trying to make a program on ARM that finds the symmetric difference between two sets and stores it in a separate set and I am not sure what I am doing wrong, can somebody help?
Here is what I have:
start
LDR R0, = ASize ;load number of elements in A
LDR R0, [R0]
LDR R1, = BSize ;load number of elements in B
LDR R1, [R1]
LDR R2, = CSize ;load number of elements in C
LDR R2, [R2]
LDR R3, = AElems ;load elements in A
LDR R4, = BElems ;load elements in B
LDR R5, = CElems ;load elements in C
LDR R8, = '?'
while
CMP R0,#0
BEQ endwh
while2
CMP R1,#0
BEQ endwh
LDR R6, [R3]
LDR R7, [R4]
CMP R6,R7
BEQ endwh
STR R7, [R5]
ADD R2,R2,#1
ADD R4,R4,#4
STR R8, [R4]
SUB R1,R1,#1
B while
STR R6, [R5]
ADD R2,R2,#1
STR R8, [R3]
SUB R0,R0,#1
ADD R3,R3,#4
B while2
endwh
stop B stop
I managed to figure it out thanks for the help!
here is the solution I came up with
start
LDR R0, = ASize
LDR R0, [R0]
LDR R1, = BSize
LDR R1, [R1]
LDR R2, = CSize
LDR R2, [R2]
LDR R3, = AElems
LDR R4, = BElems
LDR R5, = CElems
LDR R8, = '?'
while
CMP R0,#0
BEQ endwh1
LDR R6, [R3]
LDR R7, [R4]
CMP R6,R7
BNE endwh2
STR R8, [R3]
STR R8, [R4]
ADD R3,R3,#4
SUB R0,R0,#1
B while
endwh2
CMP R1,#0
BEQ endwh3
ADD R4,R4,#4
SUB R1,R1,#1
B while
endwh3
STR R6, [R5]
ADD R5,R5,#4
ADD R2,R2,#1
ADD R3,R3,#4
SUB R0,R0,#1
LDR R4, = BElems
LDR R1, = BSize
LDR R1, [R1]
B while
endwh1
while2
CMP R1,#0
BEQ endwh
LDR R7, [R4]
CMP R7,#'?'
BEQ endwh4
STR R7, [R5]
ADD R2,R2,#1
ADD R5,R5,#4
ADD R4,R4,#4
SUB R1,R1,#1
B while2
endwh4
ADD R4,R4,#4
SUB R1,R1,#1
B while2
endwh
stop B stop

ARM Assembler - Loop getting stuck

I'm currently writing some basic ARM assembler. The idea is to control a theoretical furnace and it's cooling/heating system on the LPC2378 development board with an application board attached.
I'm getting there as far as recognising input from the devices is concerned. However, i'm having trouble getting my loop right and I was hoping you guys may be able to point out why my loop is getting stuck, and even after button 1 has been pressed, the fan is not turning on. I previously had the fan working, but when I started trying to control the fan by the temperature of the heater it does not seem to ever start up, and the heater stays on, getting hotter and hotter without the fan to cool it down.
I'm guessing it could come down to the way i'm reading the temperature from the ADC controller.
Please don't hesitate to ask if you need any more information to answer the question.
;=========================================================================
; MotorControl_1
;
; BUT1 turns motor ON and BUT2 turns motor OFF
;
; No interrupt support (except for Reset) - as simple as it gets!
;
; WDH, November 2008
;==========================================================================
; Set-up interrupt vectors and stack support
$ LPC2378InterruptVectors.s
; After a reset exception, execution starts here - the processor is in ARM
; mode and supervisor state with interrupts disabled
SECTION .text:CODE:NOROOT(2)
REQUIRE __vector ; Forces reference to this symbol - required by linker
ARM
; __iar_program_start - defined start symbol.
__iar_program_start:
; Include lpc2378 IO register definitions
#include "iolpc2378.h"
; Include Olimex LPC-2378-STK IO definitions
#include "OlimexLPC2378BoardDefs.h"
; Main entry point - required by debugger
;=========================================================================
; main starts here
;=========================================================================
main
;=========================================================================
; Stack setup
;
; Stack pointer (r13 or SP) is assigned the highest address in a 32kB
; section of on-chip SRAM - assumes a FULL descending stack convention
;=========================================================================
ldr r13, = 0x40008000
ldr r2, = 0x000050 ;Load the delay value
ldr r3, = 0x028 ;Start set point at 40
ldr r4, = 0x000 ;Start temp difference as 0
; ldr r6, = 0x0f ;Temp High Value (15)
; ldr r7, = -0xF ;Set r7 to -15.
; Initialise IO
BL InitialiseARM_IO
BL InitialiseApplicationsBoard_IO
; Initialise the devices and display
BL FanOff
BL errorLedOff
BL systemLedOff
BL heaterOff
LoopStart
BL WaitBUT1
BL heaterOn
BL systemLedOn
BL readTemp
BL checkTemp
CMP r0, #5
BGT errorVal
SUBS r7, r6, r4 ;Performs r7 = r6 - r4 and sets condition register
BLT LoopStart ;Branches to label_bar if r7 < 0 (in which case r6 < r4)
BGT heaterOff
BGT errorLedOn
BGT FanOn
BGT LoopStart
BL WaitBUT2
BL FanOff
BL errorLedOff
BL systemLedOff
BL heaterOff
B LoopStart
;=========================================================================
; InitialiseARM_IO
;
; Initialise the ARM interface, as follows:
;
; Port0(13..14} GPIO Output to on-board LEDs
; bit 13: USB_LINK LED
; bit 14: USB_CONNECT LED
; Port0{18,29} GPIO Input from BUT1 and BUT2
; bit 18: BUT2 pressbutton input
; bit 29: BUT1 pressbutton input
; Port1{18,19} GPIO Inputs from joystick UP and DOWN
; bit 18: UP joystick inout
; bit 19: DOWN joystick input
;=========================================================================
InitialiseARM_IO
; Define data direction for LEDs - the LEDs are connected
; to P0.13 and P0.14
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
;LEDs on ARM board:
; Assign GPIO on P0.13 and P0.14
LDR R5, =PINSEL0 ; Address of PINSEL0
LDR R0, [R5] ; Read current PINSEL0
BIC R0, R0, #0x3C000000 ; Clear bits 26..29
STR R0, [R5] ; Put back in PINSEL0
; Configure output for P0.13 and P0.14
LDR R5, =IO0DIR ; Address of IO0DIR
LDR R0, [R5] ; Read current IO0DIR
ORR R0, R0, #0x6000 ; Set bits 13 and 14 - for P0.13 and P0.14
STR R0, [R5] ; Put back in IO0DIR
; Switches and Joystick inputs on ARM board
; Assign GPIO on P0.18 and P0.29
LDR R5, =PINSEL1 ; Address of PINSEL1
LDR R0, [R5] ; Read current PINSEL1
BIC R0, R0, #0x30 ; Clear bits 4..5
BIC R0, R0, #0x0c000000 ; Clear bits 26..27
STR R0, [R5] ; Put back in PINSEL0
; Configure input for P0.18 and P0.29
LDR R5, =IO0DIR ; Address of IO0DIR
LDR R0, [R5] ; Read current IO0DIR
BIC R0, R0, #0x20000000 ; Clear bits 18 and 29 - for P0.18 and P0.29
BIC R0, R0, #0x00040000
STR R0, [R5] ; Put back in IO0DIR
; Assign GPIO on P1.18 and P1.19
LDR R5, =PINSEL3 ; Address of PINSEL3
LDR R0, [R5] ; Read current PINSEL3
BIC R0, R0, #0xF0 ; Clear bits 4..7
STR R0, [R5] ; Put back in PINSEL3
; Configure input for P1.18 and P1.19
LDR R5, =IO1DIR ; Address of IO1DIR
LDR R0, [R5] ; Read current IO1DIR
BIC R0, R0, #0xc0000 ; Clear bits 18 and 19 - for P1.18 and P1.19
STR R0, [R5] ; Put back in IO1DIR
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
;=========================================================================
; InitialiseApplicationsBoard_IO
;
; Initialise the interface to the Applications Board, as follows:
;
; Port4{0..7} GPIO Output to LEDs, Motor and Heater
; bits 0..4: Temperature error LED indicators
; bit 5: Heater control
; bits 6..7: Motor control
; Port4(8..15} GPIO Input from ADC
; bits 8..15: Inputs from Application Board ADC
;
;=========================================================================
InitialiseApplicationsBoard_IO
; Define data direction for LEDs - the LEDs are connected
; to P0.13 and P0.14
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
; Applications Board Interface via Port4
; Set FIO4MASK to allow access to all bits
LDR R5, =FIO4MASK ; Address of FIO4DIR
LDR R0, [R5] ; Read current IO4DIR
MOV R0, #0x0 ; Clear all bits of FIO4MASK
STR R0, [R5] ; Put back in IO4DIR
; Configure output for P4.0 to P4.7
LDR R5, =FIO4DIR ; Address of FIO4DIR
LDR R0, [R5] ; Read current IO4DIR
ORR R0, R0, #0xFF ; Set bits 0..7 - for P4.0 and P4.7
STR R0, [R5] ; Put back in IO4DIR
; Configure input for P4.8 to P4.15
LDR R5, =FIO4DIR ; Address of FIO4DIR
LDR R0, [R5] ; Read current IO4DIR
BIC R0, R0, #0xFF00 ; Clear bits 8..15 - for P4.8 and P4.15
STR R0, [R5] ; Put back in IO4DIR
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
;=========================================================================
; Wait for BUT1 to be pressed
;=========================================================================
WaitBUT1
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
WaitForBUT1Pressed
ldr r0, = IO0PIN ; Address of FIO0PIN register
ldr r1, [r0] ; Read FIO0PIN in to r1
ands r1, r1, # B1_MASK ; Mask out BUT1
beq BUT1Pressed ; Exit LED toggle loop if button is pressed
B WaitForBUT1Pressed
BUT1Pressed
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
;=========================================================================
; Wait for BUT2 to be pressed
;=========================================================================
WaitBUT2
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
WaitForBUT2Pressed
ldr r0, = IO0PIN ; Address of FIO0PIN register
ldr r1, [r0] ; Read FIO0PIN in to r1
ands r1, r1, # B2_MASK ; Mask out BUT1
beq BUT2Pressed ; Exit LED toggle loop if button is pressed
B WaitForBUT2Pressed
BUT2Pressed
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
;=========================================================================
; Turn Fan Motor ON
;=========================================================================
FanOn
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
LDR R5, =FIO4PIN ; Address of FIO4PIN
LDR r0, [r5] ; Read current Port4
ORR r0, r0, #0x80
STR r0, [r5] ; Output
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
;=========================================================================
; Turn Fan Motor OFF
;=========================================================================
FanOff
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
LDR R5, =FIO4PIN ; Address of FIO4PIN
LDR r0, [r5] ; Read current Port4
BIC r0, r0, #0xc0
STR r0, [r5] ; Output
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
;==============================================================================
; Turn On Error LED
;==============================================================================
errorLedOn
STMFD r13!,{r0, r5,r14}
mov r0, # USB_LINK_LED_MASK
ldr r5, = IO0CLR
str r0, [r5]
LDMFD r13!,{r0, r5, r14}
mov pc, r14
;==============================================================================
; Turn Off Error LED
;==============================================================================
errorLedOff
STMFD r13!,{r0, r5,r14}
mov r0, # USB_LINK_LED_MASK
ldr r5, = IO0SET
str r0, [r5]
LDMFD r13!,{r0, r5, r14}
mov pc, r14
;==============================================================================
; Turn On System LED
;==============================================================================
systemLedOn
STMFD r13!,{r0, r5,r14}
mov r0, # USB_CONNECT_LED_MASK
ldr r5, = IO0CLR
str r0, [r5]
LDMFD r13!,{r0, r5, r14}
mov pc, r14
;==============================================================================
; Turn Off System LED
;==============================================================================
systemLedOff
STMFD r13!,{r0, r5,r14}
mov r0, # USB_CONNECT_LED_MASK
ldr r5, = IO0SET
str r0, [r5]
LDMFD r13!,{r0, r5, r14}
mov pc, r14
;==============================================================================
; Turn Heater On
;==============================================================================
heaterOn
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
LDR R5, =FIO4PIN ; Address of FIO4PIN
LDR r0, [r5] ; Read current Port4
ORR r0, r0, #0x20
STR r0, [r5] ; Output
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
;==============================================================================
; Turn The Heater Off
;==============================================================================
heaterOff
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
LDR R5, =FIO4PIN ; Address of FIO4PIN
LDR r0, [r5] ; Read current Port4
AND r0, r0, #0xDF
STR r0, [r5] ; Output
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
;==============================================================================
; Read Temperature
;==============================================================================
readTemp
STMFD r13!,{r0,r5,r14} ; Push r0, r5 and LR
LDR r0, =FIO4PIN
LDR r1, [r0]
LSR r1, r1, #8
AND r1, r1, #0xFF ; r1 now holds the temperature value
LDMFD r13!,{r0,r5,r14} ; Pop r0, r5 and LR
mov pc, r14 ; Put link register back into PC
;==============================================================================
; Implement Counter And Read Temperature
;==============================================================================
checkTemp
STMFD r13!,{r0, r14} ; Push PC, r0, Lr
LSR r1, r1, #8
LDR r0, [r2] ; Load delay value in r0.
SUB r0, r0, #0x01 ; Minus 1 from delay.
BEQ readTemp ; Branch if timer counted down.
errorVal
STMFD r13!,{r0, r14} ; Push PC, r0, Lr
SUB r1, r3, r6 ; Subtract set point from temperature, into r6
mov pc, r14 ; Put link register back into PC
END
It looks like you've confused BGT (branch if greater-than) with BLGT (branch and link if greater-than). In the middle of your main loop you have this:
BLT LoopStart ;Branches to label_bar if r7 < 0 (in which case r6 < r4)
BGT heaterOff
BGT errorLedOn
BGT FanOn
BGT LoopStart
If the condition is "greater-than", your code will branch to heaterOff and then when that function returns, it will exit the code entirely. The functions errorLedOn and FanOn can never execute.

Resources