0
\$\begingroup\$

I would like to read out a sensor over SPI using the DMA. Since the sensor has some noise, I would like to take the average and so I need to read out the sensor several times. For this I decided to use the HAL_SPI_TransmitReceive_DMA() function, but it seems only to read out the sensor once. I think the problem is, because of the SS Pin, which is only triggered once in the whole reading process. How can I read out this sensor with the DMA, such that it only interrupts at the end of the read process?

Sensor AS5048a: (https://www.google.ch/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0ahUKEwjOqo-G5ODWAhXDCcAKHQk5DIYQFggtMAE&url=https%3A%2F%2Fams.com%2Feng%2Fcontent%2Fdownload%2F438523%2F1341157%2Ffile%2FAS5048_DS000298_3-00.pdf&usg=AOvVaw1kcnV9G51ORmSPkN1SUFSM),

(http://www.mouser.com/ds/2/588/AS5048-EK-AB_Operation-Manual_Rev.1.3-820438.pdf)

My code so far:

transfer_init:

void spi_getData(SPI_HandleTypeDef *hspi, uint8_t *tx, uint8_t *rx) {
    //tx containts the data after spi_prepare_tx_data and spi_get_tx_data
    if(spi_dma_complete==1) {
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_RESET);
        HAL_SPI_TransmitReceive_DMA(hspi,tx,rx,SPI_SIZE);
        spi_dma_complete=0;
    }
}
void spi_prepare_tx_data() {
    uint16_t data16=SPI_CMD_READ | SPI_REG_DATA;
    data16 |= spiCalcEvenParity(data16) << 15;

    tx_data[1]=data16;//(uint16_t)SPI_CMD_READ | (uint16_t)SPI_REG_DATA; 
    tx_data[0]=(data16>>2);
}

void spi_get_tx_data(uint8_t *tx) {
    for(uint8_t i=0;i<SPI_SIZE;i=i+2) {
        tx[i]=tx_data[0];
        tx[i+1]=tx_data[1];
    }
}

Rx DMA Interrupt:

void DMA1_Channel6_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel6_IRQn 0 */
  spi_dma_complete=1;
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_SET);
  //spi_getData(&hspi1,spi_tx_buff,spi_rx_buff);
  /* USER CODE END DMA1_Channel6_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_spi1_rx);
  /* USER CODE BEGIN DMA1_Channel6_IRQn 1 */

  /* USER CODE END DMA1_Channel6_IRQn 1 */
}
\$\endgroup\$
  • \$\begingroup\$ tx_data[0]=(data16>>2); are you sure?? I see more potential errors here. \$\endgroup\$ – P__J__ Oct 8 '17 at 14:46
  • \$\begingroup\$ I'm not sure anymore why i implemented this, but the data I recieve is correct. The problem is, that the SS Pin only should be low for one dara package, then it needs to be high for a moment. I don't think the DMA can achieve this, right? I already implemented it in such a way, that I always receive an interrupt when The DMA got new data and then I set up a new transfer, but the interrupt overhead is killing me. The position is needed for FOC, which runs around 700Hz, and so for 30 samples i need to get a new position with 21kHz. \$\endgroup\$ – HansPeterLoft Oct 8 '17 at 16:29
  • \$\begingroup\$ with you do not control anything. Waste of time. Ps I think that you receive the results by simple luck. \$\endgroup\$ – P__J__ Oct 8 '17 at 16:32
  • \$\begingroup\$ Well, also if this would be a mistake, it wouldn't change the fact, that I somehow need to control the SS-Pin for a continous DMA transfer. I implemented this code half a year ago and cannot remeber why I have choosen this, but it is there for a reason and I get the data reliable. The FOC is already implemented and works just fine, but I would like to get more stable position signals to reduce vibrations in the steady state position. The angular position signals I receive vary around +-0.2°. \$\endgroup\$ – HansPeterLoft Oct 8 '17 at 17:52
  • \$\begingroup\$ With HAL I meant. All overheads come from there. Do it properly on the register level and all your problems will go away instantly \$\endgroup\$ – P__J__ Oct 8 '17 at 20:04

Your Answer

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

Browse other questions tagged or ask your own question.