Question
SPI Transmit Interrupt Enable causes STM8 device reset
Hi,
I am using STM8 device as a SPI master and SMP580 is a slave. When I enable SPI Transmit Interrupt (SPI_ICR-> TXIE = 1) MCU is resetting and when not enable MCU reset not occurring. I am enabling these interrupt during MCU Init. MCU not reset when Rx interrupt is enabled.
My Observations are:
- Break point in ISR is hitting once debug mode is running.
- Break point in main() is hitting always. Which indicate MCU reset.
- When Tx interrupt not enable MCU reset NOT occurred
- When Rx interrupt is enabled MCU reset NOT occurred.
- Tried to read and write to SPI->DR in ISR but issue is same.
Please give your suggestions for how to use SPI transmit interrupt. Below is code for your reference.
#pragma vector = 0x0C // ToDo: To be checked
__interrupt void SPI_IRQHandler(void)
{
disableInterrupts();
if(SPIT_GetFlagStatus(SPI_SR_RXNE))
{
/* Receiving SPI Data */
temp = (uint8_t)(SPI->DR);
/* Clearing Receive FIFO drain request enable flag */
SPI_ClearFlag(SPI_SR_RXNE);
}
if(SPIT_GetFlagStatus(SPI_SR_TXE))
{
/* Transmit complete */
/* Clearing Receive FIFO drain request enable flag */
SPI_ClearFlag(SPI_SR_TXE);
}
enableInterrupts();
return;
}
void SPIT_ITConfig(uint8_t SPIT_IT, uint8_t NewState)
{
VAR(uint8_t, SPIT_VAR) itpos;
/* Get the SPI IT index */
itpos = (uint8_t)((uint8_t)1 << (uint8_t)((uint8_t)SPIT_IT & (uint8_t)0x0F));
if (NewState != SPIT_DISABLE)
{
SPI->ICR |= itpos; /* Enable interrupt*/
}
else
{
SPI->ICR &= (uint8_t)(~itpos); /* Disable interrupt*/
}
}
void SPIT_DeInit(void)
{
SPI->CR1 = ((uint8_t)0x00);
SPI->CR2 = ((uint8_t)0x00);
SPI->ICR = ((uint8_t)0x00);
SPI->SR = ((uint8_t)0x02);
SPI->CRCPR = ((uint8_t)0x07);
SPI_ClearFlag(SPI_SR_RXNE);
}
void SPIT_Init(void)
{
VAR(uint8_t, SPIT_VAR) SPIT_Loop = SPIT_ZERO;
SPIT_DeInit();
CLK->ICKR = 0; // Reset the Internal Clock Register.
CLK->ICKR |= CLK_ICKR_HSIEN; // Enable the HSI.
CLK->ECKR = 0; // Disable the external clock.
while (CLK_ICKR_HSIRDY == 0); // Wait for the HSI to be ready for use.
CLK->CKDIVR = 0; // Ensure the clocks are running at full speed.
CLK->PCKENR1 |= (uint8_t)((uint8_t)1 << ((uint8_t)SPIT_CLK_PERIPHERAL_SPI & (uint8_t)0x0F)); // Enable all peripheral clocks.
// CLK->CCOR = 1; // Turn on CCO.
CLK->HSITRIMR = 0; // Turn off any HSIU trimming.
CLK->SWIMCCR = 0; // Set SWIM to run at clock / 2.
CLK->SWR = 0xe1; // Use HSI as the clock source.
CLK->SWCR = 0; // Reset the clock switch control register.
CLK->SWCR |= CLK_SWCR_SWEN; // Enable switching.
while (CLK->SWCR & CLK_SWCR_SWBSY != 0); // Pause while the clock switch is busy.
/* Reset corresponding bit to GPIO_Pin in CR2 register */
GPIOC->CR2 &= (uint8_t)(~(SPIT_CFG_GPIOC_PIN));
GPIOE->CR2 &= (uint8_t)(~(SPIT_CFG_GPIOE_PIN));
/*-----------------------------*/
/* Input/Output mode selection */
/*-----------------------------*/
GPIOC->ODR |= (uint8_t)SPIT_CFG_GPIOC_PIN;
GPIOE->ODR |= (uint8_t)SPIT_CFG_GPIOE_PIN;
/* Set Output mode */
GPIOC->DDR |= (uint8_t)SPIT_CFG_GPIOC_PIN;
GPIOE->DDR |= (uint8_t)SPIT_CFG_GPIOE_PIN;
GPIOC->DDR &= (uint8_t)(~(SPIT_GPIOC_PIN_7_MISO));// Setting MISO Pin as Input
/*------------------------------------------------------------------------*/
/* Pull-Up/Float (Input) or Push-Pull/Open-Drain (Output) modes selection */
/*------------------------------------------------------------------------*/
GPIOC->CR1 |= (uint8_t)SPIT_CFG_GPIOC_PIN;
GPIOE->CR1 |= (uint8_t)SPIT_CFG_GPIOE_PIN;
/*-----------------------------------------------------*/
/* Interrupt (Input) or Slope (Output) modes selection */
/*-----------------------------------------------------*/
//GPIOC->CR2 |= (uint8_t)SPIT_CFG_GPIOC_PIN;
//GPIOC->CR2 |= (uint8_t)(SPIT_GPIOC_PIN_7_MISO);
GPIOE->CR2 |= (uint8_t)SPIT_CFG_GPIOE_PIN;
/* Frame Format, BaudRate, Clock Polarity and Phase configuration */
SPI->CR1 = (uint8_t)((uint8_t)((uint8_t)(uint8_t)0x00 | (uint8_t)0x18) |
(uint8_t)((uint8_t)(uint8_t)0x00 | (uint8_t)0x01));
/* Data direction configuration: BDM, BDOE and RXONLY bits */
SPI->CR2 = (uint8_t)((uint8_t)((uint8_t)0x00) | (uint8_t)((uint8_t)0x02));
SPI->CR2 |= (uint8_t)((uint8_t)0x01);
/* Master/Slave mode configuration */
SPI->CR1 |= (uint8_t)(0x04);
/* CRC configuration */
SPI->CRCPR = (uint8_t)0x00;
SPIT_ITConfig(((uint8_t)0x06),ENABLE);// Rx Interrupt Enable
SPIT_ITConfig(((uint8_t)0x07),ENABLE);// Tx Interrupt Enable
SPI->CR1 &= (uint8_t)(~((uint8_t)0x40));
/* Enable the SPI peripheral*/
SPI->CR1 |= ((uint8_t)0x40);
}