[ATSAMD51J18A- A/D Interrupt ] SPI data loss

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Team,

 

We are working on the project to start the A/D conversions using counter/Timer (TC0). As of now, we are able to generate the overflow interrupt using TC0. We have toggled one GPIO in overflow interrupt ISR and probed the same to oscilloscope and confirmed the frequency.

 

In the same manner, we have started the A/D conversion in counter/timer ISR and read A/D data and write into SPI bus for Host reading purpose (through Interrupt).

 

By referring the below video, https://www.digikey.com/en/videos/m/microchip/atmel-start-sensors-adc-with-timer-callback-visualization-6

 

We have tested and noticed that sometimes we are facing data loss issue.  In order to find the data loss issue related to SPI/AD, we have hardcoded the values(instead of reading from ADC) in firmware and read the same from host for every interrupt. 

 

For every interrupt, SAMD51 will trigger the GPIO ( to notify host) and then write the data into SPI bus. Once master is notified , it will read 2 bytes (LSB and MSB) from SPI bus. Please refer the below code,

 

gpio_set_pin_level(GPIO_EXP0_INT_3P3, false); // for notifying to host
gpio_set_pin_level(DIO_0,false);                    // just to probe in oscilloscope
        
hri_sercomspi_write_DATA_reg(SERCOM4, SampleData[0]);
while (!hri_sercomi2cm_get_INTFLAG_reg(SERCOM4, SERCOM_SPI_INTFLAG_DRE));

hri_sercomspi_write_DATA_reg(SERCOM4, SampleData[1]);
while (!hri_sercomi2cm_get_INTFLAG_reg(SERCOM4, SERCOM_SPI_INTFLAG_DRE));

 

gpio_set_pin_level(GPIO_EXP0_INT_3P3, true);         // changing to default state.
gpio_set_pin_level(DIO_0,true);

 

Previously, we used io_Write () function for writing into SPI bus, since it is hanged at higher frequencies like 500 Hz, Microchip advised us to use direct register call.

 

We have hardcoded 0x8EE in firmware and reading from master. Sometimes we are getting 00 as LSB and 0xEE as MSB. Is there any synchronization issue?

 

Thanks,

Jana

Jana8153

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jana07 wrote:

Hi Team,

 

We are working on the project to start the A/D conversions using counter/Timer (TC0). As of now, we are able to generate the overflow interrupt using TC0. We have toggled one GPIO in overflow interrupt ISR and probed the same to oscilloscope and confirmed the frequency.

 

In the same manner, we have started the A/D conversion in counter/timer ISR and read A/D data and write into SPI bus for Host reading purpose (through Interrupt).

 

By referring the below video, https://www.digikey.com/en/videos/m/microchip/atmel-start-sensors-adc-with-timer-callback-visualization-6

 

We have tested and noticed that sometimes we are facing data loss issue.  In order to find the data loss issue related to SPI/AD, we have hardcoded the values(instead of reading from ADC) in firmware and read the same from host for every interrupt. 

 

For every interrupt, SAMD51 will trigger the GPIO ( to notify host) and then write the data into SPI bus. Once master is notified , it will read 2 bytes (LSB and MSB) from SPI bus. Please refer the below code,

 

gpio_set_pin_level(GPIO_EXP0_INT_3P3, false); // for notifying to host
gpio_set_pin_level(DIO_0,false);                    // just to probe in oscilloscope
        
hri_sercomspi_write_DATA_reg(SERCOM4, SampleData[0]);
while (!hri_sercomi2cm_get_INTFLAG_reg(SERCOM4, SERCOM_SPI_INTFLAG_DRE));

hri_sercomspi_write_DATA_reg(SERCOM4, SampleData[1]);
while (!hri_sercomi2cm_get_INTFLAG_reg(SERCOM4, SERCOM_SPI_INTFLAG_DRE));

 

gpio_set_pin_level(GPIO_EXP0_INT_3P3, true);         // changing to default state.
gpio_set_pin_level(DIO_0,true);

 

Previously, we used io_Write () function for writing into SPI bus, since it is hanged at higher frequencies like 500 Hz, Microchip advised us to use direct register call.

 

We have hardcoded 0x8EE in firmware and reading from master. Sometimes we are getting 00 as LSB and 0xEE as MSB. Is there any synchronization issue?

 

Thanks,

Jana

 

SPI configuration,

 

Master : SPI clock frequency 500 KhZ

SPI mode : 1

 

SAMD51(Slave): core and slow frequency is 40 MHz

 

Jana8153

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe you could try  "35.6.3.2 Preloading of the Slave Shift Register", i.e., do that before 

gpio_set_pin_level(GPIO_EXP0_INT_3P3, false); // for notifying to host

Not the problem but looks bad:

hri_sercomi2cm_get_INTFLAG_reg

use the SPI functions.
/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lajon wrote:

Maybe you could try  "35.6.3.2 Preloading of the Slave Shift Register", i.e., do that before 

gpio_set_pin_level(GPIO_EXP0_INT_3P3, false); // for notifying to host

Not the problem but looks bad:

hri_sercomi2cm_get_INTFLAG_reg

use the SPI functions.
/Lars

 

Hi Lars,

 

>>Not the problem but looks bad:

 

If i am using io_Write (spi write ) function at 1 KHz , firmware gets hanged. So that we are using direct register call.

 

Thanks,

Jana

Jana8153

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I understand why you use direct register functions but when you are using the SERCOM in SPI mode it makes no sense to use the I2C hri functions (even if they work as in this case, reading the INTFLAG register is the same for SPI and I2C).

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Lars,

 

We have INTFLAG  register call by referring below function definition which is auto-generated during Atmel start.

-----------------------------------------------------------------------------------

bool _spi_s_sync_is_tx_ready(struct _spi_s_sync_dev *dev)
{
    ASSERT(dev && dev->prvt);

    return hri_sercomi2cm_get_INTFLAG_reg(dev->prvt, SERCOM_SPI_INTFLAG_DRE);
}

-------------------------------------------------------------------------------------

 

Also, Microchip technical support  suggested below inputs,

 

Yes, to reduce the overhead of the spi write functions, you may use the hri_sercomspi_write_DATA_reg(dev->prvt, data) .

After each write to the DATA register and before writing the next data, ensure that SPI is ready for the next transfer using the "_spi_s_sync_is_tx_ready" API.

 

--------------

hri_sercomspi_write_DATA_reg(dev->prvt, data);

while (!_spi_s_sync_is_tx_ready());

--------------

 

-------------------------------------------------------------------------------------------------------

 

Thanks,

Jana

Jana8153

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You don't necessarily have to repeat the error Microchip has made in that _spi_s_sync_is_tx_ready function, there is a hri_sercomspi_get_INTFLAG_reg also.

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Lars,

 

Shall we try with below code, instead of Microchip suggested inputs?

 

hri_sercomspi_write_DATA_reg(SERCOM4, SampleData[1]);
while (! hri_sercomspi_get_INTFLAG_reg (SERCOM4, SERCOM_SPI_INTFLAG_DRE));

 

 

Jana8153

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes but note I wrote this has nothing to do with the data loss problem. Preloading the shift register might help.

/Lars