2022-05-24 02:36 AM
I have the problem that I don't get the NSS configured correctly on my SPI transmission. I should get according to reference Manuel a NSS signal that switches just before the first bit and just after the last bit. I send several different data one after the other using the command LL_SPI_TransmitData16. For me now NSS should be permanently low as long as I send data directly one after the other.
But for me the NSS signal toggles also in between, respectively always then, when a send process is finished.
Configuration:
void spi2_init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
LL_SPI_InitTypeDef SPI_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Peripheral clock enable */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
/**SPI2 GPIO Configuration
PB12 ------> SPI2_NSS
PB13 ------> SPI2_SCK
PB14 ------> SPI2_MISO
PB15 ------> SPI2_MOSI
*/
GPIO_InitStruct.Pin = S_CS_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_0;
LL_GPIO_Init(S_CS_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = S_SCLK_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_0;
LL_GPIO_Init(S_SCLK_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = S_MISO_F_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_0;
LL_GPIO_Init(S_MISO_F_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = S_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_0;
LL_GPIO_Init(S_MOSI_GPIO_Port, &GPIO_InitStruct);
/* SPI2 DMA Init */
//spi12_dmatest();
/* SPI2_TX Init */
LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_4, LL_DMAMUX_REQ_SPI2_TX);
LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_4, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PRIORITY_HIGH);
LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MODE_NORMAL);
LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PDATAALIGN_HALFWORD);
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MDATAALIGN_HALFWORD);
// /* SPI2_RX Init */
// LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_7, LL_DMAMUX_REQ_SPI2_RX);
//
// LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_7, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
//
// LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_7, LL_DMA_PRIORITY_HIGH);
//
// LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_7, LL_DMA_MODE_NORMAL);
//
// LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_7, LL_DMA_PERIPH_NOINCREMENT);
//
// LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_7, LL_DMA_MEMORY_INCREMENT);
//
// LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_7, LL_DMA_PDATAALIGN_HALFWORD);
//
// LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_7, LL_DMA_MDATAALIGN_HALFWORD);
/* SPI2 interrupt Init */
NVIC_SetPriority(SPI2_IRQn, 3);
NVIC_EnableIRQ(SPI2_IRQn);
/* USER CODE BEGIN SPI2_Init 1 */
LL_SPI_Disable(SPI2);
/* USER CODE END SPI2_Init 1 */
SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_16BIT;
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
SPI_InitStruct.NSS = LL_SPI_NSS_HARD_OUTPUT;
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8;
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_ENABLE;
SPI_InitStruct.CRCPoly = 0xED2F;
LL_SPI_Init(SPI2, &SPI_InitStruct);
LL_SPI_SetStandard(SPI2, LL_SPI_PROTOCOL_MOTOROLA);
LL_SPI_SetCRCWidth(SPI2, LL_SPI_CRC_16BIT);
LL_SPI_EnableNSSPulseMgt(SPI2);
//LL_SPI_SetNSSMode(SPI2, 1);
LL_SPI_EnableCRC(SPI2);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_4, SPI2TxBufferSize);
LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_4, LL_SPI_DMA_GetRegAddr(SPI2));
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_4, (uint32_t) &SPI2_TX_BUFF[0]);
//LL_SPI_EnableDMAReq_TX(SPI2);
//enable SPI2
LL_SPI_Enable(SPI2);
//enable DMA Channel
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_4);
}
Sending process:
void TIM2_IRQHandler(void)
{
/* USER CODE BEGIN TIM2_IRQn 0 */
LED_Red_toggle();
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_4);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_4, SPI2TxBufferSize);
//RAW for U_SEC
while (LL_SPI_GetTxFIFOLevel(SPI2) > 2);
//LL_SPI_TransmitData16(SPI2, 50);
LL_SPI_TransmitData16(SPI2, SPI2_TX_BUFF[0]);
//RAW for I_ch_a
while (LL_SPI_GetTxFIFOLevel(SPI2) > 2);
//LL_SPI_TransmitData16(SPI2, 100);
LL_SPI_TransmitData16(SPI2, SPI2_TX_BUFF[1]);
//RAW for I_ch_b
while (LL_SPI_GetTxFIFOLevel(SPI2) > 2);
//LL_SPI_TransmitData16(SPI2, 200);
LL_SPI_TransmitData16(SPI2, SPI2_TX_BUFF[2]);
//RAW for U_SEC_FILTERT
while (LL_SPI_GetTxFIFOLevel(SPI2) > 2);
//LL_SPI_TransmitData16(SPI2, 300);
LL_SPI_TransmitData16(SPI2, SPI2_TX_BUFF[3]);
while (LL_SPI_GetTxFIFOLevel(SPI2) > 2);
LL_SPI_SetCRCNext(SPI2);
adc1_raw();
LL_TIM_ClearFlag_UPDATE(TIM2);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_4);
/* USER CODE END TIM2_IRQn 0 */
/* USER CODE BEGIN TIM2_IRQn 1 */
/* USER CODE END TIM2_IRQn 1 */
}
2022-05-24 06:29 AM
NSS is driven based on SPI configuration word size - 16-bits in this case. If you need to send more bits (24-32-40) and SPI for this iCPU (what exactly ?) doesn't support - the only option is software NSS. Drive NSS as common GPIO output in software.