CC3200 SPI 从机接收不良
CC3200 SPI Slave bad receive
已解决:我必须处理 CS/NSS 奴隶的引脚。在 TX 之前和之后添加一些延迟。
void SlaveMain()
{
MAP_SPIReset(GSPI_BASE);
MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0,
(SPI_SW_CTRL_CS |
SPI_4PIN_MODE |
SPI_TURBO_OFF |
SPI_CS_ACTIVELOW |
SPI_WL_8));
MAP_SPIEnable(GSPI_BASE);
}
while(1)
{
MAP_SPICSEnable(GSPI_BASE);
MAP_SPIDataGet(GSPI_BASE, &data);
Report("Got: %d\n\r", data);
MAP_SPICSDisable(GSPI_BASE);
}
我的问题是我通过 SPI 从 STM32F4 板接收到错误数据。我的 CC3200 开发板 SPI 从配置:
#define SPI_IF_BIT_RATE 100000
void SlaveMain()
{
// Set Tx buffer index
ucTxBuffNdx = 0;
ucRxBuffNdx = 0;
// Reset SPI
MAP_SPIReset(GSPI_BASE);
// Configure SPI interface
MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0,
(SPI_SW_CTRL_CS |
SPI_4PIN_MODE |
SPI_TURBO_OFF |
SPI_CS_ACTIVEHIGH |
SPI_WL_8));
// Register Interrupt Handler
MAP_SPIIntRegister(GSPI_BASE,SlaveIntHandler);
// Enable Interrupts
MAP_SPIIntEnable(GSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY);
// Enable SPI for communication
MAP_SPIEnable(GSPI_BASE);
Message("Enabled SPI Interface in Slave Mode\n\rReceived : ");
}
中断:
static void SlaveIntHandler()
{
unsigned long ulRecvData;
unsigned long ulStatus;
ulStatus = MAP_SPIIntStatus(GSPI_BASE,true);
MAP_SPIIntClear(SSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY);
if(ulStatus & SPI_INT_RX_FULL)
{
MAP_SPIDataGetNonBlocking(GSPI_BASE,&ulRecvData);
Report("Received: %d\n\r",ulRecvData);
}
}
我的 STM32F4 板 SPI Master 配置:
void MX_SPI2_Init(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
HAL_SPI_Init(&hspi2);
}
uint8_t data;
while (1)
{
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
data = 6;
HAL_SPI_Transmit(&hspi2, &data, 1, 50);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay(500);
}
我从 CC3200 得到的结果在我重置主设备后发生了变化:
哪里有问题?
(从机配置为软件控制 CS/NSS 引脚,您目前不处理)。 SPI 通常使用 CS pin 重新同步,所以如果在传输中丢失一位,或者从机在主机开始传输后启动),它目前永远不会恢复(SPI 没有 START/STOP 位)。
我假设 HAL_GPIO_WritePin 是你的芯片 select 线。由于 SPI 串行传输数据,您可以在发送所有位之前设置 GPIO(并禁用 SPI 通信)(特别是因为 SPI 时钟通常仅在 ~4MHz 左右)。 Check/post HAL_SPI_Transmit 函数中的代码,看看它是否在返回之前检查某种 SPI 就绪位。出于调试目的,请尝试在每次 HAL_GPIO_WritePin 调用之前添加一些延迟。另外,检查 SPI 寄存器的位长。您可能已将其配置为 8 位传输,但如果寄存器实际上是 16 位或 32 位,则传输的数据可能需要在写入前左对齐(例如,如果在 16 位寄存器上传输 8 位数据,则 0xFF 变为 0xFF00位 SPI 寄存器)。
已解决:我必须处理 CS/NSS 奴隶的引脚。在 TX 之前和之后添加一些延迟。
void SlaveMain()
{
MAP_SPIReset(GSPI_BASE);
MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0,
(SPI_SW_CTRL_CS |
SPI_4PIN_MODE |
SPI_TURBO_OFF |
SPI_CS_ACTIVELOW |
SPI_WL_8));
MAP_SPIEnable(GSPI_BASE);
}
while(1)
{
MAP_SPICSEnable(GSPI_BASE);
MAP_SPIDataGet(GSPI_BASE, &data);
Report("Got: %d\n\r", data);
MAP_SPICSDisable(GSPI_BASE);
}
我的问题是我通过 SPI 从 STM32F4 板接收到错误数据。我的 CC3200 开发板 SPI 从配置:
#define SPI_IF_BIT_RATE 100000
void SlaveMain()
{
// Set Tx buffer index
ucTxBuffNdx = 0;
ucRxBuffNdx = 0;
// Reset SPI
MAP_SPIReset(GSPI_BASE);
// Configure SPI interface
MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0,
(SPI_SW_CTRL_CS |
SPI_4PIN_MODE |
SPI_TURBO_OFF |
SPI_CS_ACTIVEHIGH |
SPI_WL_8));
// Register Interrupt Handler
MAP_SPIIntRegister(GSPI_BASE,SlaveIntHandler);
// Enable Interrupts
MAP_SPIIntEnable(GSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY);
// Enable SPI for communication
MAP_SPIEnable(GSPI_BASE);
Message("Enabled SPI Interface in Slave Mode\n\rReceived : ");
}
中断:
static void SlaveIntHandler()
{
unsigned long ulRecvData;
unsigned long ulStatus;
ulStatus = MAP_SPIIntStatus(GSPI_BASE,true);
MAP_SPIIntClear(SSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY);
if(ulStatus & SPI_INT_RX_FULL)
{
MAP_SPIDataGetNonBlocking(GSPI_BASE,&ulRecvData);
Report("Received: %d\n\r",ulRecvData);
}
}
我的 STM32F4 板 SPI Master 配置:
void MX_SPI2_Init(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
HAL_SPI_Init(&hspi2);
}
uint8_t data;
while (1)
{
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
data = 6;
HAL_SPI_Transmit(&hspi2, &data, 1, 50);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
HAL_Delay(500);
}
我从 CC3200 得到的结果在我重置主设备后发生了变化:
哪里有问题?
(从机配置为软件控制 CS/NSS 引脚,您目前不处理)。 SPI 通常使用 CS pin 重新同步,所以如果在传输中丢失一位,或者从机在主机开始传输后启动),它目前永远不会恢复(SPI 没有 START/STOP 位)。
我假设 HAL_GPIO_WritePin 是你的芯片 select 线。由于 SPI 串行传输数据,您可以在发送所有位之前设置 GPIO(并禁用 SPI 通信)(特别是因为 SPI 时钟通常仅在 ~4MHz 左右)。 Check/post HAL_SPI_Transmit 函数中的代码,看看它是否在返回之前检查某种 SPI 就绪位。出于调试目的,请尝试在每次 HAL_GPIO_WritePin 调用之前添加一些延迟。另外,检查 SPI 寄存器的位长。您可能已将其配置为 8 位传输,但如果寄存器实际上是 16 位或 32 位,则传输的数据可能需要在写入前左对齐(例如,如果在 16 位寄存器上传输 8 位数据,则 0xFF 变为 0xFF00位 SPI 寄存器)。