Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading from UART RxD of the Raspberry Pi in Assembly

I have a Pi connected to my laptop through the serial port (UART). I wrote the function ReadChar which reads a char as input on the UART's RXD port but it doesn't work. When running, the program is stuck in the ReadChar infinite loop waiting for some data even when I write something in the console. The function WriteChar works perfectly fine so I think that the issue could be either in the function ReadChar or in the initialisation of the UART.

Who can help me with this?

Thanks a lot.

The main function:

main:
BL InitializeUART
BL ReadChar
BL WriteChar @ this function works properly</code>

The ReadChar function:

ReadChar:
LDR R0, =AUX_MU_LSR_REG
LDR R1, [R0]
TST R1, #1
BEQ ReadChar
LDR R0, =AUX_MU_IO_REG
LDR R1, [R0]        
MOV pc, lr

Initialisation of the UART

.equ AUX_ENABLES,   0x20215004
.equ AUX_MU_IER_REG,    0x20215044
.equ AUX_MU_CNTL_REG,   0x20215060
.equ AUX_MU_LCR_REG,    0x2021504C
.equ AUX_MU_MCR_REG,    0x20215050
.equ AUX_MU_IIR_REG,    0x20215048
.equ AUX_MU_BAUD_REG,   0x20215068
.equ GPPUD,    0x20200094
.equ GPPUDCLK0,    0x20200098
.equ GPCLR0,    0x20200028
.equ GPFSEL1,    0x20200004



InitializeUART:
PUSH {lr}
@ Enable UART
MOV R1, #1
LDR R0, =AUX_ENABLES
STR R1, [R0]
@ disable interrupts
MOV R1, #0
LDR R0, =AUX_MU_IER_REG
STR R1, [R0]
@ disable transmit/receive
MOV R1, #0
LDR R0, =AUX_MU_CNTL_REG
STR R1, [R0]
@ set 8 bits communication
MOV R1, #3
LDR R0, =AUX_MU_LCR_REG
STR R1, [R0]
@ set the RTS line high
MOV R1, #0
LDR R0, =AUX_MU_MCR_REG
STR R1, [R0]
@ leave disable interrupts
MOV R3, #0
LDR R0, =AUX_MU_IER_REG
STR R3, [R0]
@ clear the input and output buffers
MOV R1, #198
LDR R0, =AUX_MU_IIR_REG
STR R1, [R0]
@ set BAUD = 270
MOV R1, #200
ADD R1, R1, #70
LDR R0, =AUX_MU_BAUD_REG
STR R1, [R0]
@ Set GPIO line 14 for transmission (TXD)
LDR R0, =GPFSEL1
LDR R1, [R0]
BIC R3, R1, #28672
ORR R3, R3, #8192
STR R3, [R0]
@ Set GPIO line 15 for receiving (RXD)
LDR R1, [R0]
BIC R3, R1, #229376
ORR R3, R3, #65536
STR R3, [R0]
@ disable GPIO pull-up/down
MOV R1, #0
LDR R0, =GPPUD
STR R1, [R0]
@ wait for 150 cycles
MOV R1, #0
cycle1: ADD R1, R1, #1
BL Cycle
CMP R1, #150
BNE cycle1
@ Assert clock lines (14 & 15)
MOV R1, #16384  @ 1<<14
LDR R0, =GPPUDCLK0
STR R1, [R0]
MOV R1, #32768 @ 1<<15
STR R1, [R0]
@ wait for 150 cycles
MOV R1, #0
cycle2: ADD R1, R1, #1
BL Cycle
CMP R1, #150
BNE cycle2
@ clear clock lines
MOV R1, #0
LDR R0, =GPCLR0
STR R1, [R0]
@ enable bits 0 and 1 in CONTROL
MOV R1, #2
LDR R0, =AUX_MU_CNTL_REG
STR R1, [R0]
@ return
POP {pc}        

Cycle:      MOV pc, lr
like image 623
Ashley Avatar asked Jan 21 '26 04:01

Ashley


1 Answers

I found the solution. In the last step of the initialization, only the transmitter is enabled and not the receiver. So #3 (0b11) should be stored instead of #2 (0b10).

@ enable bits 0 and 1 in CONTROL
MOV R1, #3
LDR R0, =AUX_MU_CNTL_REG
STR R1, [R0]
like image 154
Ashley Avatar answered Jan 23 '26 14:01

Ashley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!