El siguiente código configura y habilita SPI2 como esclavo en mi placa STM32F303RE , escribe 0xAA, 0xBB, 0xCC, 0xDD bytes en
/* Enable clocks for GPIOB (SPI2 pins) and SPI2 peripheral. */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
/* SPI pin mappings. */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_5); /* SPI2_NSS */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_5); /* SPI2_SCK */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5); /* SPI2_MISO */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_5); /* SPI2_MOSI */
GPIO_InitTypeDef gpio_init_struct =
{
.GPIO_Mode = GPIO_Mode_AF,
.GPIO_OType = GPIO_OType_PP,
.GPIO_PuPd = GPIO_PuPd_DOWN,
.GPIO_Speed = GPIO_Speed_50MHz
};
/* SPI NSS pin configuration. */
gpio_init_struct.GPIO_Pin = GPIO_Pin_12;
GPIO_Init(GPIOB, &gpio_init_struct);
/* SPI SCK pin configuration. */
gpio_init_struct.GPIO_Pin = GPIO_Pin_13;
GPIO_Init(GPIOB, &gpio_init_struct);
/* SPI MISO pin configuration. */
gpio_init_struct.GPIO_Pin = GPIO_Pin_14;
GPIO_Init(GPIOB, &gpio_init_struct);
/* SPI MOSI pin configuration. */
gpio_init_struct.GPIO_Pin = GPIO_Pin_15;
GPIO_Init(GPIOB, &gpio_init_struct);
SPI_InitTypeDef spi_init_struct =
{
.SPI_Direction = SPI_Direction_2Lines_FullDuplex,
.SPI_Mode = SPI_Mode_Slave,
.SPI_DataSize = SPI_DataSize_8b,
.SPI_CPOL = SPI_CPOL_Low,
.SPI_CPHA = SPI_CPHA_1Edge,
.SPI_NSS = SPI_NSS_Hard,
.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2,
.SPI_FirstBit = SPI_FirstBit_MSB,
.SPI_CRCPolynomial = 7
};
SPI_I2S_DeInit(SPI2);
SPI_Init(SPI2, &spi_init_struct);
SPI_CalculateCRC(SPI2, DISABLE);
SPI_TIModeCmd(SPI2, DISABLE);
SPI_NSSPulseModeCmd(SPI2, DISABLE);
SPI_Cmd(SPI2, ENABLE);
SPI_SendData8(SPI2, (uint8_t) 0xAA);
SPI_SendData8(SPI2, (uint8_t) 0xBB);
SPI_SendData8(SPI2, (uint8_t) 0xCC);
SPI_SendData8(SPI2, (uint8_t) 0xDD);
while(1) { }
Con un maestro que solicita 2 bytes por selección de chip , el maestro recibe:
0xAA 0xBB
0xCC 0xDD
0xAA 0xAA -----> TXFIFO should be empty here, why not "0x00 0x00"?
0xAA 0xAA
0xAA 0xAA
0xAA 0xAA
0xAA 0xAA
0xAA 0xAA
0xAA 0xAA
......... (0xAA 0xAA infinite times)
Habría esperado que el maestro reciba "0x00 0x00" cuando TXFIFO se quede vacío . ¿Por qué obtengo " 0xAA 0xAA " continuamente en su lugar? No pude encontrar algo que apuntara a tal comportamiento en el manual.
ACTUALIZACIÓN 1
Esperando a que las transacciones terminen solo antes de while (1) y escribiendo ceros en el SPI después, de esta manera:
while(SPI_GetTransmissionFIFOStatus(SPI2) != SPI_TransmissionFIFOStatus_Empty) { }
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) != RESET) { }
#define ZEROS_CNT (1)
for(int i = 0; i < ZEROS_CNT; i++)
SPI_SendData8(SPI2, 0);
while(1) { }
representa el siguiente comportamiento maestro para diferentes valores de ZEROS_CNT:
ZEROS_CNT = 0 => master receives after TXFIFO is empty: 0xAA infinitely
ZEROS_CNT = 1 => master receives after TXFIFO is empty: 0x00 1 times, followed by 0xBB infinitely
ZEROS_CNT = 2 => master receives after TXFIFO is empty: 0x00 2 times, followed by 0xCC infinitely
ZEROS_CNT = 3 => master receives after TXFIFO is empty: 0x00 3 times, followed by 0xDD infinitely
ZEROS_CNT >= 4 => master receives after TXFIFO is empty: 0x00 infinitely
Parece que el periférico SPI tiene algún tipo de historial de lo que se escribió en el TXFIFO y cuando se vacía, envía bytes de ese historial.
ACTUALIZACIÓN 2
Se comporta de la misma manera independientemente de cuántos bytes solicite el maestro en una sola selección de chip. He intentado solicitar 1, 2, 4 y 5 a la vez.