0
\$\begingroup\$

I've connected two NUCLEOSTM32F411RE together, and trying to send an ASCII letter from one PC to another PC in Simplex mode from master to slave.

When I send a character the slave enters a routine in startup_stn32f411xe.s where it is written in the comment of the code "This is the code that gets called when the processor receives an unexpected interrupt. This simply enters an infinite loop, preserving the system state for examination by a debugger"

I've connected SPI2MOSI (master) to SPI2MOSI (slave) as described on page 6 (PC3 to PC3)

http://www2.st.com/content/ccc/resource/training/technical/product_training/d9/cf/69/ae/71/43/4f/23/STM32L4_Peripheral_SPI.pdf/files/STM32L4_Peripheral_SPI.pdf/jcr:content/translations/en.STM32L4_Peripheral_SPI.pdf

Also SPI2_SCK to SPI2_SCK (PB10) as well as SPI2_NSS to SPI2_NSS (PB12)

CPOL and CPHA are configured the same in the Cube. For the slave only I have in the NVIC checked the SPI2 global interrupt interrupt priority 0, also have USART2 global interrupt.

The configuration of the SPI slave is like this in main:

void MX_NVIC_Init(void)
{
  /* SPI2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(SPI2_IRQn);
  __HAL_SPI_ENABLE_IT(&hspi2, SPI_IT_RXNE);//My addition

 /* USART2_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(USART2_IRQn);
 __HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE); //My addition
 __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);//My addition

}

/* SPI2 init function */
void MX_SPI2_Init(void)
{
 hspi2.Instance = SPI2;
 hspi2.Init.Mode = SPI_MODE_SLAVE;
 hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
 hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
 hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
 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);
 __HAL_SPI_ENABLE(&hspi2); // My addition
 }

My IRQ handler in STM324fxx_it.c looks like this

void SPI2_IRQHandler(void)
{
 HAL_SPI_IRQHandler(&hspi2);
 uint8_t data1;
 HAL_SPI_Receive_IT(&hspi2,&data1,sizeof(data1));
 HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);
}

Why is the interrupt unexpected on the slave side?

//Adding more info after suggestion,init USART slave main
void MX_USART2_UART_Init(void)
{

 huart2.Instance = USART2;
 huart2.Init.BaudRate = 115200;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 HAL_UART_Init(&huart2);
__HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}
//Masterside stm324fxx_it.c
void USART2_IRQHandler(void)
{  
  HAL_UART_IRQHandler(&huart2);
  uint8_t data1;
  HAL_UART_Receive_IT(&huart2,&data1,sizeof(data1));
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin,GPIO_PIN_SET);
  HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);

}

The interrupt routine is prepared for bidirectional communication, and is not entered since I've initilizing it in nvic with

__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);

and I am not trying to send from the slave conntected PC. The transmission to the slaveside PC, I hope to accomplish with

HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);

in

void SPI2_IRQHandler(void)//Thank's for your interest :)
\$\endgroup\$
  • \$\begingroup\$ Needless to say, I of course connected together the gnd pins of each card... \$\endgroup\$ – Lasse Karagiannis Apr 17 '16 at 18:44
  • \$\begingroup\$ Interrupts can be difficult to manage. Often it is an "everything must be configured correctly" or "nothing will work" situation. I would suggest to fall back to polling the SPI hardware. SPI does not need to run fast as the master is controlling the clock for both the master and slave. Run it slow. Once working try running it faster. Then using interrupts on one side, then on both sides. \$\endgroup\$ – st2000 Apr 17 '16 at 18:46
  • \$\begingroup\$ By the way, I didn't see a MISO connection in your post. Also, you might check how interrupts are "registered" in your SDK environment. You may need to remove a duplicate label (SPI2_IRQHandler) from the default interrupt routine. \$\endgroup\$ – st2000 Apr 17 '16 at 18:48
  • \$\begingroup\$ Hi, and thank's I don't use MISO since I only do simplex transmission from master to slave. I'll follow your advice, by trying to do polling and then go with lowest possible transfer rate with interrupt. \$\endgroup\$ – Lasse Karagiannis Apr 17 '16 at 19:22
  • \$\begingroup\$ You've enabled your UART2 & SPI2 interrupts, but I only see an handler for SPI2. Do you have a UART2 interrupt handler? \$\endgroup\$ – brhans Apr 18 '16 at 15:06
2
\$\begingroup\$

This works in main of the master-board:

SPI2_MOSI (PC3) to SPI2_MOSI (PC3)
SPI2_NSS (PB12) to SPI2_NSS (PB12) 
SPI2_SCK (PB10) to SPI2_SCK (PB10)

Termainalprogram running on each PC connected to each board. Baud:115200, No-parity, CTS/RTS

void MX_NVIC_Init(void)
{
/* USART2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);

}

/* SPI2 init function */
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_HIGH;
 hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
 hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
 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);
 __HAL_SPI_ENABLE(&hspi2);
}


/* USART2 init function */
void MX_USART2_UART_Init(void)
{
 huart2.Instance = USART2;
 huart2.Init.BaudRate = 115200;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 HAL_UART_Init(&huart2);
 __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}

On stm32f4xx_it.c for the master

void USART2_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart2);
  uint8_t data1;
  HAL_UART_Receive_IT(&huart2,&data1,sizeof(data1));
  data1++; //Icrementing 'A' to 'B'
  HAL_SPI_Transmit(&hspi2,&data1,  (uint16_t)sizeof(data1),HAL_MAX_DELAY);
 HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);//echoing back to PC
}

On the slave side in main

void MX_NVIC_Init(void)
{
 HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(SPI2_IRQn);
 __HAL_SPI_ENABLE_IT(&hspi2, SPI_IT_RXNE);
 HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(USART2_IRQn);
 __HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);
 __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}

/* SPI2 init function */
void MX_SPI2_Init(void)
{
 hspi2.Instance = SPI2;
 hspi2.Init.Mode = SPI_MODE_SLAVE;
 hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
 hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
 hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
 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);
 __HAL_SPI_ENABLE(&hspi2);
}


/* USART2 init function */
void MX_USART2_UART_Init(void)
{
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart2);
  __HAL_UART_HWCONTROL_RTS_ENABLE(&huart2);
}

In slave stm32f4xx_it.c

void SPI2_IRQHandler(void)
{
  HAL_SPI_IRQHandler(&hspi2);
 uint8_t data1;
 HAL_SPI_Receive_IT(&hspi2,&data1,sizeof(data1));
 HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);

}

void USART2_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart2);
  uint8_t data1;
  HAL_UART_Receive_IT(&huart2,&data1,sizeof(data1));
  data1++;
  HAL_UART_Transmit(&huart2,&data1,(uint16_t)sizeof(data1),HAL_MAX_DELAY);
}
\$\endgroup\$
0
\$\begingroup\$

You did not mention MISO when you described your SPI connections. For full duplex SPI communications you need the 3 connections (MOSI, MISO & SCK) found in the below diagram plus a SS or Select Signal when addressing multiple slaves:

enter image description here

You may need the Select Signal even with only 1 slave. It depends on what the slave is expecting to see and how you want to manage future expansion.

\$\endgroup\$
  • \$\begingroup\$ Thank you friend, but I am just doing one way communication for the moment, I don't think it is necessary to use MISO, therefore. \$\endgroup\$ – Lasse Karagiannis Apr 19 '16 at 17:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.