There is address of registry (first?) SPI1. There is structure with offsets. I suppose it means that SPI1_REG_BASE + offset = address of some SPI registry
#define SPI1_REG_BASE (0x01F0E000)
//-----------------------------------------------------
//Register Structure & Defines
//-----------------------------------------------------
typedef struct
{
volatile uint32_t SPIGCR0; // 0x0000
volatile uint32_t SPIGCR1; // 0x0004
volatile uint32_t SPIINT; // 0x0008
volatile uint32_t SPILVL; // 0x000C
volatile uint32_t SPIFLG; // 0x0010
volatile uint32_t SPIPC0; // 0x0014
volatile uint32_t SPIPC1; // 0x0018
volatile uint32_t SPIPC2; // 0x001C
volatile uint32_t SPIPC3; // 0x0020
volatile uint32_t SPIPC4; // 0x0024
volatile uint32_t SPIPC5; // 0x0028
volatile uint32_t RSVD0[3]; // 0x002C
volatile uint32_t SPIDAT0; // 0x0038
volatile uint32_t SPIDAT1; // 0x003C
volatile uint32_t SPIBUF; // 0x0040
volatile uint32_t SPIEMU; // 0x0044
volatile uint32_t SPIDELAY; // 0x0048
volatile uint32_t SPIDEF; // 0x004C
volatile uint32_t SPIFMT0; // 0x0050
volatile uint32_t SPIFMT1; // 0x0054
volatile uint32_t SPIFMT2; // 0x0058
volatile uint32_t SPIFMT3; // 0x005C
volatile uint32_t INTVEC0; // 0x0060
volatile uint32_t INTVEC1; // 0x0064
} spi_regs_t;
There are some definitions and the definition of pointer *spi
#define CSDEF0 (0x00000001) //bit 0
#define CSHOLD (0x10000000) //bit 28
spi_regs_t *spi = (spi_regs_t *)SPI1_REG_BASE;
I misunderstood setting of bits. For example,
spi->SPIDEF |= CSDEF0 //set 0 bit in the registry field
I understand that SPIDEF - is SPI register which has offset address 4Ch
(0x01F0E000 + 0x4C). But why CSDEF0 is bit 0 ?? There is a field CSDEF in SPIDEF registry (0-7 bits). Is it mean that 7 bit of CSDEF has address 0x00000008 ? and 5 bit has address 0x00000006?
But then why CSHOLD field of SPIDAT1 registry has address 0x10000000 ??
spi->SPIDAT1 |= CSHOLD //set bit 28
SPIDAT1 register has offset address 3Ch (0x01F0E000 + 0x3C) It truly has field CSHOLD (28st bit)
How does |= work in this situation?
I'll be grateful for any help for figuring out... all this %)
I think you are misunderstanding the notions of address and value of the registers.
You are right (based on the structure description you gave) when you say that the CSDEF0
register of the SPI1 module is located at address 0x01F0E000 + 0x4C
. This address will never change, it is defined by the hardware design.
Now with the following statements you are not manipulating addresses but values of the registers:
spi->SPIDEF |= CSDEF0; //set 0 bit in the registry field
spi->SPIDAT1 |= CSHOLD; //set bit 28
The |=
operator is a bitwise OR and assign operator. It is equivalent to the following :
spi->SPIDEF = spi->SPIDEF | CSDEF0; //set 0 bit in the registry field
spi->SPIDAT1 = spi->SPIDAT1 | CSHOLD; //set bit 28
As CSDEF0
is defined to 0x00000001
, in the first statement you are effectively setting the LSB bit of the SPIDEF
register, leaving all other bits to their original value.
But why CSDEF0 is bit 0 ?
Because of:
#define CSDEF0 (0x00000001) //bit 0
What they mean is not a "bit with value 0" but "the bit at position 0".
And concerning the:
#define CSHOLD (0x10000000) //bit 28
Take a look at converting hex-notation to binary-notation and it will become clear.
How does |= work in this situation?
The 1-bits AT those positions (0 and 28) are or'ed into the value that was previously in that variable.
But why CSDEF0 is bit 0 ??
The purpose of this macro is to set bit-0 to 1. If this macro is ORed with any register, then that register's bit-0 is set to 1.
For example
Lets take spi->SPIDEF = 0x050A
ie 0x050A ==> 0000 0101 0000 1010
Now setting 0th bit of spi->SPIDEF using CSDEF0 .
0x050A ==> 0000 0101 0000 1010
CSDEF0 ==> 0000 0000 0000 0001
--------------------
spi->SPIDEF ==> 0000 0101 0000 1011
why CSHOLD field of SPIDAT1 registry has address 0x10000000??
Same-way how CSDEF0 is used to represent 0th bit, CSHOLD is used for 28th bit.
I guess you confused with Hexa-deciamal and binary representation of 0x000001 and 000001 (???).
0x01 is 01.
0x02 is 10.
0x100 is 1 0000 0000
0x1000 is 1 0000 0000 0000
0x10000000 is 1 0000 0000 0000 0000 0000 0000 0000
^-- Bit 28 starting from bit-0
Bits don't have individual addresses.
Instead a common practise in embedded world is to concatenate several small attributes to a larger register. eg one could define some internals of realtime scheduler as:
31 30 29 28 27 26 25 24 32 22 21 20 19 18 0
[ max_priority ] [ current_priority] [ reserved] [ address_xxxx ]
Here max_priority would be 5-bit unsigned integer having values 0-31; One could as well define max_priority0 being the least significant bit of that value. All these parameters would be accessed within the same absolute address (REG_BASE + offset).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.