2018-12-05 09:06 PM
Hi, i'm using SPI to communicate two STM32F446RE
Unfortunately, I get different value after the reset button pressed. Due to some other reasons, these two 446RE use LL and opencm3, but I don't think it is an issue.
The code for master in one of the 446RE (LL):
LL_SPI_InitTypeDef SPI_InitStruct;
LL_GPIO_InitTypeDef GPIO_InitStruct;
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI3);
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
GPIO_InitStruct.Pin = SPI3_SCK_PIN | SPI3_MISO_PIN | SPI3_MOSI_PIN;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_6;
LL_GPIO_Init(SPI3_PORT, &GPIO_InitStruct);
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8;
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH;
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE;
SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
LL_SPI_Init(SPI3, &SPI_InitStruct);
LL_SPI_Enable(SPI3);
And the slave on the other 446RE (opencm3):
rcc_periph_clock_enable(RCC_SPI3);
rcc_periph_clock_enable(RCC_GPIOB);
nvic_enable_irq(NVIC_SPI3_IRQ);
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO3 | GPIO4 | GPIO5);
gpio_set_af(GPIOB, GPIO_AF6, GPIO3 | GPIO4 | GPIO5);
gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO10);
spi_set_slave_mode(SPI3);
spi_set_baudrate_prescaler(SPI3, SPI_CR1_BR_FPCLK_DIV_8);
spi_set_full_duplex_mode(SPI3);
spi_set_clock_polarity_1(SPI3);
spi_set_clock_phase_1(SPI3);
spi_set_dff_8bit(SPI3);
spi_send_msb_first(SPI3);
spi_enable_software_slave_management(SPI3);
spi_enable_rx_buffer_not_empty_interrupt(SPI3);
spi_enable(SPI3);
Both 446RE have the same clock speed , 180MHz, and same pre-scaler.
I send some value for test:
int main(void)
{
all setups.....
while(1)
{
LL_SPI_TransmitData8(SPI3, 20);
}
}
and for slave part
volatile int i = 0;
void spi3_isr(void)
{
i = spi_xfer(SPI3, 0);
}
and print the value in main.
The results:
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
160
<< after the reset button pressed
40
40
40
40
40
40
40
40
40
40
40
40
40
40
<< after the reset button pressed
130
130
130
130
130
130
130
130
130
130
130
130
130
130
130
130
130
130
<< after reset button pressed
20
20
20
20
20
20
20
20
20
20
20
20
20
20
Which is different every time the reset button is pressed, however, during each time, the value just never changes.
Any help or advice will be great, thanks in advance!
Solved! Go to Solution.
2018-12-06 10:14 AM
OK, so the problem is resolved, it is due to the NSS. I wasn't that familiar with it before, but now I have a better understand to it.
Basically, I added some additional codes:
LL part (Master) -> GPIO setup for NSS pin, and pull low before transmission, pull high after busy flag is cleared
opencm3 part (Slave)
gpio_mode_setup(NSS_port, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, NSS_pin);
spi_disable_software_slave_management (SPI3);
spi_disable_ss_output(SPI3);
The most important part I've missed before is GPIO_MODE_INPUT, since it is receiving the external signal from master. By doing so, the communication finally work as expected.
Thanks again to @Community member for pointing out the very problem, so that I can fix the issue relatively fast :D
2018-12-06 12:36 AM
Do you have some framing in place, e.g. have connected NSS from master to slave and pulsing it between bytes? If not, slave sees the stream of bits starting at a random point, so it sees several bits from the end of previous byte and then the remaining bits from start of next byte, concatenated as one byte.
JW
2018-12-06 05:46 AM
Hi, first of all, thanks for your quick response.
Could you make some example? I have a hard time understanding NSS, i've connected the NSS of master and slave. However, from what I know so far, SSM = 1 means that the external NSS GPIO logic will be ignored. Using SSM = 0 doesn't make sense either, since the NSS of the master is pulled low immediately after it is enabled, I can't stop the transmission by pulling the NSS high.
Thank you for your response, really appreciate it!
2018-12-06 10:14 AM
OK, so the problem is resolved, it is due to the NSS. I wasn't that familiar with it before, but now I have a better understand to it.
Basically, I added some additional codes:
LL part (Master) -> GPIO setup for NSS pin, and pull low before transmission, pull high after busy flag is cleared
opencm3 part (Slave)
gpio_mode_setup(NSS_port, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, NSS_pin);
spi_disable_software_slave_management (SPI3);
spi_disable_ss_output(SPI3);
The most important part I've missed before is GPIO_MODE_INPUT, since it is receiving the external signal from master. By doing so, the communication finally work as expected.
Thanks again to @Community member for pointing out the very problem, so that I can fix the issue relatively fast :D