AnsweredAssumed Answered

Periodically interrupt driven SPI

Question asked by Omar Suárez on Jan 29, 2018
Latest reply on Jan 31, 2018 by dhenry

Hello,

 

I am trying to set up a project using an STM32F746ZG and an external DAC communicated by the SPI3. The idea is to transmit data from the MCU to the DAC periodically (using a timer and its interrupt) and use the callback function for SPI transfer complete to check whether the data transmission has ended. I need to send 16 bits data with MSB first.

To send the data I use a buffer which I need to acces each of the elements load in an array and transmit every uint16_t value over the SPI. I need to transmit one 16-bit value at a time (controlled by the timer).

Here is some code snippet so you can take a look,

 

 const uint16_t aTxBuffer[32] = {2047, 1648, 1264, 910, 600,  345,   
                    156, 39,  0,  39,  156,  345,  
                    600, 910, 1264, 1648, 2048, 2447,  
                    2831, 3185, 3495, 3750, 3939, 4056,  
                    4095, 4056, 3939, 3750, 3495, 3185,  
                    2831, 2447};

uint8_t cont = 0;

...

...

 

 

int main(){

...

...

...

 

 

 while (1)
  {
       /* is it time to send data? */
        if(flagStartSPI_DAC){
            if(HAL_SPI_Transmit_IT(&hspi3, (uint8_t*)aTxBuffer[cont], 1) != HAL_OK){
                    _Error_Handler(__FILE__, __LINE__);
                }
            
            flagStartSPI_DAC = 0;
        }
        /* has the data been transmited over SPI yet? then start timer again */
        if(flagStart_TIM){
            flagStart_TIM = 0;
            HAL_TIM_Base_Start_IT(&htim6);
        }
  }
}

 

...

...

...

 

void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef* hspi){

    cont++;
     

   /* is it the last values in the array? */       
    if(cont==32){
        cont = 0;
    }

   /* led on for debugging pourposes */
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);


   /* start timer */
    flagStart_TIM = 1;                
}



void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim){
    

   /* time to send data over the SPI? */
    if(htim->Instance == TIM6){
        /* set the flag */
        flagStartSPI_DAC = 1;
    }
}

 

The problem I am experimenting now is that the SPI values I read using an logic analyzer are not correct and the SPI interrupt takes place only the first 8 timer triggers.

 

Anyone can help with this?

 

Thanks in advanced,

Omar

Outcomes