Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: Teensy 4.1/4.0 with external ADC using SPI

  1. #1
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20

    Teensy 4.1/4.0 with external ADC using SPI

    Hi Everyone,

    I'm hoping someone can help who has far more coding experience than me. I'm trying to communicate to an AD7490 ADC (https://www.analog.com/media/en/tech...ets/AD7490.pdf) over SPI. As I understand it, the way SPI works is that data is communicated at the same time over MISO and MOSI. My na´ve question is that, how do you extract the data when you have information coming from the ADC? I have to send a control register which is my struct union. but then the ADC should be sending me information back but I'm not entirely sure how to break it down.


    I've including my code in case anyone asks questions or yells at me for not including the code. It's still extremely rough, may not totally make sense either but I'm trying.



    Code:
    /*
    
    
    
    
    
    
    
    */
    
    #include <AD7490.h>
    #include <SPI.h>
    
    uint8_t i;
    
    /*Initial setup code, will only run once at system initialization
    */
    void setup()
    
    {
      pinMode(CS_AD7490, OUTPUT);
      SPI.begin();
      SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
      initialize_AD7490();
    
    }
    
    void loop()
    {
      readADC_AD7490();
      displaychannels_AD7490();
      delay(10);
    
    
    }
    
    /*Sends dummby conversions to external ADC (Analog Devices AD7490)
    */
    
    void initialize_AD7490()
    {
    
      AD7490ControlReg startconfig = {.reg = 0xFFFF};
      startconfig.WRITE = 0b1;
      startconfig.ADDR = 0b0;
      startconfig.PM1 = 0b1;
      startconfig.PM0 = 0b1;
      startconfig.WEAK_TRI = 0b1;
      digitalWrite(CS_AD7490, LOW);
      SPI.transfer16(startconfig.reg);
      delay(20);
      SPI.transfer16(startconfig.reg);
      digitalWrite(CS_AD7490, HIGH);
    
    }
    
    /*Collects samples from external ADC (Analog Devices AD7490)
    */
    
    void readADC_AD7490()
    {
      AD7490ControlReg request = {.reg = 0x0};
      request.WRITE = 0b1;
      request.ADDR = 0b0;
      request.PM1 = 0b1;
      request.PM0 = 0b1;
      request.WEAK_TRI = 0b1;
      request.CODING = 0b1;
    
      /*Collects samples from external ADC (Analog Devices AD7490)
      */
    
      digitalWrite(CS_AD7490, LOW);
      SPI.transfer16(request.reg);
      
    
      
      for (i = 0; i < AD7490_CHANNELS; i++) {
        request.ADDR = i + 1; // Set up ADDR for next read in sequence
        Serial.println(i);
        
    
      }
    
      digitalWrite(CS_AD7490, HIGH);
    }
    
    void displaychannels_AD7490()
    {
      
      Serial.println("Channel_00:");
      Serial.println("Channel_01:");
      Serial.println("Channel_02:");
      Serial.println("Channel_03:");
      Serial.println("Channel_04:");
      Serial.println("Channel_05:");
      Serial.println("Channel_06:");
      Serial.println("Channel_07:");
      Serial.println("Channel_08:");
      Serial.println("Channel_09:");
      Serial.println("Channel_10:");
      Serial.println("Channel_11:");
      Serial.println("Channel_12:");
      Serial.println("Channel_13:");
      Serial.println("Channel_14:");
      Serial.println("Channel_15:");
    }
    If you can help or even poke holes in what I'm doing so far, I'd appreciate a kick in the right direction.

  2. #2
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20
    Well no bites. Let me rephrase my question.

    How does one extract the data from the MISO pin should there be data available? My thought was that SPI.transfer(somedata) is being used only to transmit data from Master to Slave? Did I miss something?

  3. #3
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,890
    Sometimes easiest to look at the SPI documentation, like the Arduino documents: https://www.arduino.cc/en/Reference/SPITransfer

    With SPI when you do something like: uint8_t retval = SPI.transfer(val);
    It transfers the data stored in val are clocked out (with SCK pin 13) out the MOSI pin (11) and at the same time the values in the MISO pin are clocked in and the value is returned by the transfer function.

    There are several varieties of the transfer function that are part of the Teensy SPI library.

    The simple transfer 8 bits as I mentioned above: uint8_t retval = SPI.transfer(val);
    Simple transfer of 16 bit value: uint16_t retval = SPI.transfer16(val);

    The old buffer form, which I don't like: SPI.transfer(my_buffer, count);
    Which will transfer the count number of bytes out, and the contents of the my_buffer will be overwritten by the results.

    The form I use: SPI.transfer(out_buffer, in_buffer, count);
    It transfers the count number of byte out of the out_buffer, and the return values will be stored in in_buffer. If out_buffer is a nullptr (0) the system will output a constant value that defaults to 0 but can be set. If in_buffer is null the results are tossed.

    ...

  4. #4
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    711

  5. #5
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20
    Quote Originally Posted by KurtE View Post
    Sometimes easiest to look at the SPI documentation, like the Arduino documents: https://www.arduino.cc/en/Reference/SPITransfer

    With SPI when you do something like: uint8_t retval = SPI.transfer(val);
    It transfers the data stored in val are clocked out (with SCK pin 13) out the MOSI pin (11) and at the same time the values in the MISO pin are clocked in and the value is returned by the transfer function.

    There are several varieties of the transfer function that are part of the Teensy SPI library.

    The simple transfer 8 bits as I mentioned above: uint8_t retval = SPI.transfer(val);
    Simple transfer of 16 bit value: uint16_t retval = SPI.transfer16(val);

    The old buffer form, which I don't like: SPI.transfer(my_buffer, count);
    Which will transfer the count number of bytes out, and the contents of the my_buffer will be overwritten by the results.

    The form I use: SPI.transfer(out_buffer, in_buffer, count);
    It transfers the count number of byte out of the out_buffer, and the return values will be stored in in_buffer. If out_buffer is a nullptr (0) the system will output a constant value that defaults to 0 but can be set. If in_buffer is null the results are tossed.

    ...
    Thanks Kurt, I was reading the arduino SPI stuff and looking at the barometer example, did not come across the SPI Transfer explanation. Definitely helps!

  6. #6
    Member
    Join Date
    Aug 2019
    Location
    Michigan
    Posts
    20
    Quote Originally Posted by jonr View Post
    I can give this a try, thanks for the lead Jonr - I tried looking up AD7490 but apparently I need to google better.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •