Reputation: 529
I want to reference a c pointer in an assembler function. In C the declaration is as follows:
const uint32_t *SERCOM0_SPI_DATA_REG_ADDR = (volatile uint32_t *) &(SERCOM0->SPI.DATA.reg); // uint32_t reg;
In assem the pointer address(0x40003028) is correctly shown in the debugger. With the following code I want to write the value 0x1f to the spi register which is uint32_t.
// reg uint32_t sercom spi data
ldr r0, =SERCOM0_SPI_DATA_REG_ADDR
ldrb r1,=#0x1f
str r1, [r0]
If I now look at the register r0 the value is not 0x40003028 but 0x20000F8C. Therefore at the address is not the value 0x1f written.
In the disassembly window :
44: ldr r0, =SERCOM0_SPI_DATA_REG_ADDR
00007804 ldr r0, [pc, #28]
45: ldrb r1,= #0x1f // SERCOM0_SPI_DATA_SYNC_DATA
00007806 mov.w r1, #31
46: str r1, [r0]
The assem file is like this:
.section .ram
.syntax unified
.cpu cortex-m4
.thumb
.space 0xe4
.data
.text
.align 4
.type SEND_DATA, %function
.global SEND_DATA
VUSB_SEND_DATA:
...
bx lr
Upvotes: 1
Views: 162
Reputation: 93014
Recall that symbols in assembly are the addresses of variables they represent. So
ldr r0, =SERCOM0_SPI_DATA_REG_ADDR
loads r0
with the address of SERCOM0_SPI_DATA_REG_ADDR
, roughly being equal to
r0 = &SERCOM0_SPI_DATA_REG_ADDR;
To load the value of that variable, you need to dereference the pointer you have just obtained:
ldr r0, =SERCOM0_SPI_DATA_REG_ADDR @ load address of variable
ldr r0, [r0] @ load value of variable
Combine this with your remaining code, this should fix your issues. Note that for better code size, I recommend to use movs
explicitly when loading small constants on thumb targets.
ldr r0, =SERCOM0_SPI_DATA_REG_ADDR
ldr r0, [r0]
movs r1, #0x1f
str r1, [r0]
This should yield the desired result.
Upvotes: 1