2022-12-28 01:25 AM
I try to spi communication between my board with STM32MP157AACx microprocessor and STM32F429 disco board. I write code using bare metal for master side(my board), using HAL library for slave board(STM32F429). My problem is that I can't receive data from master side. There is my sample code piece from master side below:
int enable = 1;
uint8_t data;
uint8_t someval = 0x40;
void spi_init(void)
{
RCC->MC_AHB4ENSETR |= (1 << 1); //GPIOB peripheral clocks enable
RCC->MC_AHB4ENSETR |= (1 << 8); //GPIOI peripheral clocks enable
RCC->MC_APB1ENSETR |= (1<<11); //spi2 peripheral clocks enable
GPIOI->MODER &= ~(1<<2);
GPIOI->MODER |= (1<<3); //PI1 Alternate function
GPIOI->PUPDR &= ~(1<<2);
GPIOI->PUPDR &= ~(1<<3); //PI1 no pull up no pull down
GPIOI->MODER &= ~(1<<4);
GPIOI->MODER |= (1<<5); //PI2 Alternate function
GPIOI->PUPDR &= ~(1<<4);
GPIOI->PUPDR &= ~(1<<5); //PI2 no pull up no pull down
GPIOI->MODER &= ~(1<<6);
GPIOI->MODER |= (1<<7); //PI3 Alternate function
GPIOI->PUPDR &= ~(1<<6);
GPIOI->PUPDR &= ~(1<<7); //PI3 no pull up no pull down
GPIOB->MODER &= ~(1<<18);
GPIOB->MODER |= (1<<19); //Pb9 Alternate function
GPIOB->PUPDR &= ~(1<<18);
GPIOB->PUPDR &= ~(1<<19); //Pb9 no pull up no pull down
GPIOB->IDR |= (1<<9); //Pb9 GPIOB_IDR
GPIOI->AFR[0] |= (1<<4); //PI1 ALTERNETE FUNCTION
GPIOI->AFR[0] &= ~(1<<5);
GPIOI->AFR[0] |= (1<<6);
GPIOI->AFR[0] &= ~(1<<7);
GPIOI->AFR[0] |= (1<<8); //PI2 ALTERNETE FUNCTION
GPIOI->AFR[0] &= ~(1<<9);
GPIOI->AFR[0] |= (1<<10);
GPIOI->AFR[0] &= ~(1<<11);
GPIOI->AFR[0] |= (1<<12); // //PI3 ALTERNETE FUNCTION
GPIOI->AFR[0] &= ~(1<<13);
GPIOI->AFR[0] |= (1<<14);
GPIOI->AFR[0] &= ~(1<<15);
GPIOB->AFR[1] |= (1<<4); //PB9 ALTERNETE FUNCTION
GPIOB->AFR[1] &= ~(1<<5);
GPIOB->AFR[1] |= (1<<6);
GPIOB->AFR[1] &= ~(1<<7);
SPI2->CR2 |= (1<<0); //TSIZE (1 byte transfer)
SPI2-> CFG1 |= (1<<0); //SPI Data Frame 8 bit
SPI2-> CFG1 |= (1<<1);
SPI2-> CFG1 |= (1<<2);
SPI2-> CFG1 &= ~(1<<3);
SPI2-> CFG1 &= ~(1<<4);
SPI2-> CFG1 |= (1<<28); //SPI Master clock/256
SPI2-> CFG1 |= (1<<29);
SPI2-> CFG1 |= (1<<30);
/****************/
SPI2-> CFG2 &= ~(1<<24); //CPHA: the first clock transition is the first data capture edge
SPI2-> CFG2 &= ~(1<<25); //CPOL: SCK signal is at 0 when idle
SPI2-> CFG2 |= (1<<22); //spi master
SPI2-> CFG2 &= ~(1<<23); //MSB First
SPI2-> CFG2 |= (1<<29); //SSOE
SPI2-> CFG2 |= (1<<30); //SSOM
SPI2-> CR1 |= (1<<12); //SSI
SPI2-> CFG2 |= (1<<26); //SSM Enable
/*SPI Motorola*/
SPI2-> CFG2 &= ~(1<<21);
SPI2-> CFG2 &= ~(1<<20);
SPI2-> CFG2 &= ~(1<<19);
//SPI Communication Mode: FULL DUPLEX
SPI2-> CFG2 &= ~(1<<17);
SPI2-> CFG2 &= ~(1<<18);
SPI2-> CR1 |= (1<<0); //SPI Enable
SPI2-> CR1 |= (1<<9); //MASTER TRANSFER START
}
void spi_tx(uint8_t data)
{
while(!((SPI2->SR >> 1) & 1));
*(uint8_t*)&SPI2->TXDR = data;
while(((SPI2->SR >> 12) & 1));
}
uint8_t spi_rx(void)
{
while(((SPI2->SR >> 12) & 1));
*(uint8_t*)&SPI2->RXDR = 0;
while(!((SPI2->SR >> 0) & 1));
return SPI2->RXDR;
}
void Delay_us(uint16_t us)
{
TIM2->CNT = 0;
while (TIM2->CNT < us);
}
void Delay_ms(uint16_t ms)
{
for(uint16_t i=0; i<ms; i++)
{
Delay_us (1000); //delay of 1ms
}
}
void TIM2_IRQHandler(void){
TIM2->SR &= ~TIM_SR_UIF;
counter++;
}
void delay(uint32_t time)
{
while(time--);
}
int main(int argc, char **argv)
{
SysClockConfig();
TIM2_Config();
spi_init();
Delay_ms(10000);
while(1)
{
if(enable)
{
spi_tx(someval);
Delay_ms(1000);
}
}
}
2022-12-28 01:37 AM
Note: PI1: SPI2_SCK, PI2:SPI2_MISO, PI3: SPI2_MOSI, PB9: SPI2_NSS
2022-12-28 04:24 AM
How do your sync both sides if they boot at different time? EXTI on nss for slave? Is the slave using dma cyclic to internal read and write buffers? Check the core over spi clock ratio, slave works at half frequency than master mode. How long is the mimimum NSS high time to let interrupts process and prep next data exchange ? HAL examples are typically Refman style, rather than application style...
2022-12-28 05:27 AM
Slave board using circular dma to receive data and there is no exti on nss for slave
2022-12-28 05:53 AM
You need exti on nss.
Also check with low sck bitrate to make sure things arr not broken by too high speed.
2022-12-30 01:49 AM
I set exti on nss in slave side but i still can't receive any data in slave side. Finally i tried to manage css pin as gpio output so software slave management in master side. When i send data in master side, enter exti callback 20 times in slave side but more than 20 times exit from exti callback and doesn't receive any data.
2023-01-04 05:38 AM
Hi @Emre Avcı
might be worth to check pins with an oscilloscope or logic analyzer to see if chip select, clock and data are present on the bus and in which direction the data are missing ?
I did not clearly understand which are the master and which are the slave and on what side you are expecting to receive the data.
On an SPI master side, chip select output, clock output and MISO input pin sampling are triggered by master SW action and whatever the slave is answering or not, you must get some good or bad data (i.e. all 1's if pull-up).
In a first step, as you are in full=duplex, external data loopback on master side might help to debug only one side of the problem.
I also recommend to use whenever possible HAL libraries and definitions provided in CubeMP1 as it is very hard to catch a typo when using direct bit access.
Regards.