cancel
Showing results for 
Search instead for 
Did you mean: 

Beginner problems with 2xSPI and RTC

Stanislav Husár
Associate II

Hello, may someone help me with these peripherals? I have never used them on any ARM.

I am using STM32F051C6T8 in this project.

My setup, I have two shift register chains connected to SPI peripherals. I am using two peripherals, because two types of registers I am using, have different CPOL/CPHA requirements.

I am using SPIs as TX-only, with SS signals generated by software and GPIO peripherals - MOSI and SCLK pins only.

RCC->APB2RSTR |= RCC_APB2RSTR_SPI1RST;
RCC->APB2RSTR &= ~RCC_APB2RSTR_SPI1RST;
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
	
SPI1->CR1 |= SPI_CR1_BR_1;
SPI1->CR1 |= SPI_CR1_CPHA;
SPI1->CR1 |= SPI_CR1_MSTR;
SPI1->CR2 |= SPI_CR2_DS;
SPI1->CR1 |= SPI_CR1_SPE;

Above is init code for SPI1. After I enable SPI(SPE flag), I get mode fault.

RCC->APB1RSTR |= RCC_APB1RSTR_SPI2RST;
RCC->APB1RSTR &= ~RCC_APB1RSTR_SPI2RST;
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
	
SPI2->CR1 |= SPI_CR1_BR_1;
SPI2->CR1 |= SPI_CR1_MSTR;
SPI2->CR2 |= SPI_CR2_DS;
SPI2->CR1 |= SPI_CR1_SPE;

Above is init code for SPI2, mode fault too.

PWR->CR |= PWR_CR_DBP;
RCC->BDCR |= RCC_BDCR_BDRST;
RCC->BDCR &= ~RCC_BDCR_BDRST;
RCC->BDCR |= RCC_BDCR_RTCSEL_1;//LSI
RCC->BDCR |= RCC_BDCR_RTCEN;

RTC init code.DBP flag is not asserted, the same for RTCSEL and RTCEN.

//Unprotect
RTC->WPR = 0xCA;
RTC->WPR = 0x53;
	
//Unlock
RTC->ISR |= RTC_ISR_INIT;
while (!(RTC->ISR & RTC_ISR_INITF)) ;
	
RTC->PRER = (399 & 0x7FFF) | ((99 & 0x7F) << 16);//40kHz
RTC->TR = 0;
RTC->TR |= (thour & 0x3) << 20;
RTC->TR |= (hour & 0xF) << 16;
RTC->TR |= (tminute & 0x7) << 12;
RTC->TR |= (minute & 0xF) << 8;
RTC->TR |= (tsecond & 0x7) << 4;
RTC->TR |= (second & 0xF);
RTC->DR = 0;
RTC->DR |= (tyear & 0xF) << 20;
RTC->DR |= (year & 0xF) << 16;
RTC->DR |= (tmonth & 0x1) << 12;
RTC->DR |= (month & 0xF) << 8;
RTC->DR |= (tday & 0x3) << 4;
RTC->DR |= (day & 0xF);
	
//Lock
RTC->ISR &= ~RTC_ISR_INIT;
	
//Protect
RTC->WPR = 0;

RTC write code. Unprotect doesn't work, and INITF is never asserted.

SPI1->DR = (second << 16) & 0xFFFF;
while ((SPI1->SR & SPI_SR_TXE) == 0);
SPI1->DR = second & 0xFFFF;
while ((SPI1->SR & SPI_SR_TXE) == 0) ;
SPI1->DR = (first << 16) & 0xFFFF;
while ((SPI1->SR & SPI_SR_TXE) == 0) ;
SPI1->DR = first & 0xFFFF;
while ((SPI1->SR & SPI_SR_BSY) == SPI_SR_BSY) ;

SPI1 send code. Sending one word is okay, then it hangs up at line 4.

//Send 0 to wipe unused outputs
SPI2->DR = 0;
//Wait until tx empty
while ((SPI2->SR & SPI_SR_TXE) == 0);
//Send value	
SPI2->DR = value;
//Wait while busy == wait until data is transferred	
while ((SPI2->SR & SPI_SR_BSY) == SPI_SR_BSY) ;

SPI2 send code. Surprisingly, this works.

Does anyone know what is wrong with above code?

1 ACCEPTED SOLUTION

Accepted Solutions

> After I enable SPI(SPE flag), I get mode fault.

That's because even if you don't assign NSS pin in GPIO, the NSS input into the module itself is still active, which means that immediately after enabling SPI it sees NSS at zero (signals which are not assigned AF in GPIO are internally at zero - this is not documented anywhere so you can't rely on it, but from experience the STM32s behave quite consistently in this regard) and this switches it into slave mode.

Set both SSM and SSI.

> RTC init code.DBP flag is not asserted,

Is PWR module's clock enabled in RCC?

JW

View solution in original post

2 REPLIES 2

> After I enable SPI(SPE flag), I get mode fault.

That's because even if you don't assign NSS pin in GPIO, the NSS input into the module itself is still active, which means that immediately after enabling SPI it sees NSS at zero (signals which are not assigned AF in GPIO are internally at zero - this is not documented anywhere so you can't rely on it, but from experience the STM32s behave quite consistently in this regard) and this switches it into slave mode.

Set both SSM and SSI.

> RTC init code.DBP flag is not asserted,

Is PWR module's clock enabled in RCC?

JW

Stanislav Husár
Associate II

Thank you, most of the problems are resolved.

Unfortunately, RTC write still does not work. INITF is never asserted.

EDIT: I forgot to activate LSI, now it seems to be working.