Why does enabling SPI peripheral in STM32 Nucleo L476RG change the master bit to 0?

Guys I'm trying to implement the SPI in my stm32 Nucleo l476RG without hal drivers. I have have implemented the spi configuration using spi_init function then when it ready for the communication i enable the SPE: SPI enable using a seprate function which is
#define SPI_CR1_SPE 6

void SPI_PeripheralControl(SPI_RegDef_t *pSPIX, uint8_t EnOrDi)
{
if(EnOrDi == ENABLE)
{
pSPIX->CR1 |= (1<<SPI_CR1_SPE);
}
else
{
pSPIX->CR1 &= ~(1<<SPI_CR1_SPE);
}
}
#define SPI_CR1_SPE 6

void SPI_PeripheralControl(SPI_RegDef_t *pSPIX, uint8_t EnOrDi)
{
if(EnOrDi == ENABLE)
{
pSPIX->CR1 |= (1<<SPI_CR1_SPE);
}
else
{
pSPIX->CR1 &= ~(1<<SPI_CR1_SPE);
}
}
the problem here is when pSPIX->CR1 |= (1<<SPI_CR1_SPE); line executes it changes the master bit in the cr1 register to 0 again how can i slove this?
20 Replies
wafa_ath
wafa_ath•3mo ago
Hi @Enthernet Code modify your SPI_PeripheralControl function to use a read-modify-write operation:
void SPI_PeripheralControl(SPI_RegDef_t *pSPIX, uint8_t EnOrDi)
{
uint16_t temp = pSPIX->CR1;
if(EnOrDi == ENABLE)
{
temp |= (1 << SPI_CR1_SPE);
}
else
{
temp &= ~(1 << SPI_CR1_SPE);
}
pSPIX->CR1 = temp;
}
void SPI_PeripheralControl(SPI_RegDef_t *pSPIX, uint8_t EnOrDi)
{
uint16_t temp = pSPIX->CR1;
if(EnOrDi == ENABLE)
{
temp |= (1 << SPI_CR1_SPE);
}
else
{
temp &= ~(1 << SPI_CR1_SPE);
}
pSPIX->CR1 = temp;
}
This approach preserves other bits in the CR1 register while modifying only the SPE bit.
lokii
lokii•3mo ago
I tried this code too..same result
ZacckOsiemo
ZacckOsiemo•3mo ago
are you using SPI 1?
lokii
lokii•3mo ago
Yes
ZacckOsiemo
ZacckOsiemo•3mo ago
does your MCU have i2s?
ZacckOsiemo
ZacckOsiemo•3mo ago
You likely need to disable i2s for spi1 to work, I found that you need this before https://github.com/Gaiaocho/uCDSP/blob/688e6f0e8ec7bcdd6da5561f48a9fd002aea831b/drivers/Src/32f407_spi.c#L113 SPI1 works
GitHub
uCDSP/drivers/Src/32f407_spi.c at 688e6f0e8ec7bcdd6da5561f48a9fd002...
Contribute to Gaiaocho/uCDSP development by creating an account on GitHub.
lokii
lokii•3mo ago
Actually I'm using a STM32L4 series board which doesn't have the feature of i2s
ZacckOsiemo
ZacckOsiemo•3mo ago
let me see
ZacckOsiemo
ZacckOsiemo•3mo ago
do you have schematic is spi1 one of those with an onboard sensor?
ZacckOsiemo
ZacckOsiemo•3mo ago
true are you using pa_5, pa_6, pa_7 and pb_6?
lokii
lokii•3mo ago
Yes
ZacckOsiemo
ZacckOsiemo•3mo ago
I notice pb_6 is shared with i2c1, what happens if you explicitly disable i2c1?
lokii
lokii•3mo ago
Let me try and let you know
lokii
lokii•3mo ago
Even then I face the same problem..
lokii
lokii•3mo ago
I have used the RCC->APB1RSTR1 |= (1<<21); To reset the i2c1
ZacckOsiemo
ZacckOsiemo•3mo ago
I would say that's implicit, since thats the reset condition. How about something like
pI2Cx->CR1 &= ~(1 << I2C_CR1_PE_Pos);
pI2Cx->CR1 &= ~(1 << I2C_CR1_PE_Pos);
ZacckOsiemo
ZacckOsiemo•3mo ago
Don't use magic constants like this, 6 months from now you will need to change that and it will hurt, name the register ...
lokii
lokii•3mo ago
Yeah....sure
lokii
lokii•3mo ago
Actually I haven't started with the write the driver for i2c ...I just wrote gpio then I'm now looking on to this spi drivers ....so I got to work on it
Enthernet Code
Enthernet Code•3mo ago
Thanks @wafa_ath currently trying it out, would appreciate it more if u can send the python version of your code, Thanks for the help 🙌
Want results from more Discord servers?
Add your server