2022-03-14 11:38 PM
Is it possible to send data from SPI2 to SPI1 ? SPI2 being the slave. In SPI, Master initiates the communication, correct ?
This is how i do it:
When the Slave SPI2 receives a byte from SPI1, i set a flag, and i check for this flag in main context.
If this flag is set, i send a dummy byte from Master and wait for the interrupt in SPI1 IRQ Handler (configured for RXNE interrupt).
if( Slave_Rx_Flag == 1 ){
SPI_Master_Tx_Data(0x00); //Dummy byte
SPI_Slave_Tx_Data(0x5D);
Delay_us(50);
Slave_Rx_Flag = 0;
}
My transmit function for slave looks so:
while (!LL_SPI_IsActiveFlag_TXE(SPI2))
; // wait while not empty
LL_SPI_TransmitData8(SPI2, byte); // NO EFFECT ??
void SPI1_IRQHandler( void ) {
Master_Rx_Flag =1;
uint8_t spi2_data ;
spi2_data = SPI1->DR;
}
I am reading 0x00 when i expect 0x5D.
SPI2 (Slave) is initialized this way:
/** MASTER SLAVE
* ********** **********
* PA4 - NSS PB12 - NSS
* PA5 - SCK PB13 - SCK
* PA6 - MISO PB14 - MISO
* PA7 - MOSI PB15 - MOSI
*/
if (RESET == __HAL_RCC_GPIOB_IS_CLK_ENABLED())
{
__HAL_RCC_GPIOB_CLK_ENABLE();
}
LL_GPIO_InitTypeDef gpioSPIInitStr;
gpioSPIInitStr.Alternate = LL_GPIO_AF_5;
gpioSPIInitStr.Pin = LL_GPIO_PIN_13 | LL_GPIO_PIN_15;
gpioSPIInitStr.Mode = LL_GPIO_MODE_ALTERNATE;
gpioSPIInitStr.Speed = LL_GPIO_SPEED_FREQ_HIGH;
gpioSPIInitStr.Pull = LL_GPIO_PULL_UP;
gpioSPIInitStr.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
LL_GPIO_Init(GPIOB, &gpioSPIInitStr);
gpioSPIInitStr.Alternate = LL_GPIO_AF_5;
gpioSPIInitStr.Pin = LL_GPIO_PIN_14;
gpioSPIInitStr.Mode = LL_GPIO_MODE_INPUT;
gpioSPIInitStr.Speed = LL_GPIO_SPEED_FREQ_HIGH;
gpioSPIInitStr.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
LL_GPIO_Init(GPIOB, &gpioSPIInitStr);
gpioSPIInitStr.Alternate = LL_GPIO_AF_5;
gpioSPIInitStr.Pin = LL_GPIO_PIN_12; //NSS
gpioSPIInitStr.Mode = LL_GPIO_MODE_INPUT;
gpioSPIInitStr.Pull = LL_GPIO_PULL_NO;
gpioSPIInitStr.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
LL_GPIO_Init(GPIOB, &gpioSPIInitStr);
__HAL_RCC_SPI2_CLK_ENABLE();
LL_SPI_InitTypeDef SPI_SlaveInitStruct;
SPI_SlaveInitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4;
SPI_SlaveInitStruct.ClockPhase = LL_SPI_PHASE_2EDGE;
SPI_SlaveInitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH;
SPI_SlaveInitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
SPI_SlaveInitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
SPI_SlaveInitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
SPI_SlaveInitStruct.BitOrder = LL_SPI_MSB_FIRST;
SPI_SlaveInitStruct.Mode = LL_SPI_MODE_SLAVE;
SPI_SlaveInitStruct.NSS = LL_SPI_NSS_HARD_OUTPUT;
LL_SPI_Init(SPI2, &SPI_SlaveInitStruct);
LL_SPI_Enable(SPI2);
LL_I2S_EnableIT_RXNE(SPI2);
HAL_NVIC_SetPriority(SPI2_IRQn, 0 , 0 );
HAL_NVIC_EnableIRQ(SPI2_IRQn);
2022-03-15 12:28 AM
It is possible, but I don't know the API functions you are using for TX. The slave must be prepared to receive/transmit ahead, because it all happens at the same time. Can be done with polling:
for(;;)
{
while( !(SPI2->SR & SPI_SR_TXE) ); // poll for TX empty
SPI2->DR = tx[ti++];
while( !(SPI3->SR & SPI_SR_RXNE) ); // poll for RX non-empty
rx[rxi++] = SPI3->DR;
}
but this is kinda cheating because we assume exactly when to read. In a more realistic scenario you might use interrupt or DMA for the receiver.
hth
KnarfB
2022-03-15 02:02 AM
My Transmit function from Slave to Master looks so:
while (!LL_SPI_IsActiveFlag_TXE(SPI2))
; // wait while not empty
LL_SPI_TransmitData8(SPI2, byte); // NO EFFECT ??
My Receive interrupt handler looks so:
void SPI1_IRQHandler( void ) {
Master_Rx_Flag =1;
uint8_t spi2_data ;
spi2_data = SPI1->DR;
}
2022-03-15 06:18 AM
> Is it possible to send data from SPI2 to SPI1 ? SPI2 being the slave. In SPI, Master initiates the communication, correct ?
Yes. Correct.
> SPI_Master_Tx_Data(0x00); //Dummy byte
> SPI_Slave_Tx_Data(0x5D);
The slave needs to be ready to send before the maser starts the clock. Your order is backwards.
2022-03-15 09:08 PM
Please try developping using 2 boards. Loop back on the same chip to have only one debug plateform will cause additional debug and recode effort when dissociating master slave to 2 devices. Overall time spent will be lesser.