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

Thread: ADC Data Recording with SpiSlave and DMA....

  1. #1
    Junior Member
    Join Date
    Sep 2021
    Posts
    3

    ADC Data Recording with SpiSlave and DMA....

    Hello,

    I am trying to interface a Teensy4.0 and a ADC:AD7764 ADC. The ADC acts a spi master sending out 32bit data samples at 156KS/Sec.

    I have it hooked up to the SPI interface on the TEENSY and am able to successfully read data at a slow (slower than 156KS/S rate) by manually reading the LPSPI4_RDR register. (16 samples are stored in the FIFO).

    The issue is that I now what this process to be automatic so I can record ALL of the data and copy it over in large chunks. Setting up the DMA has been fun...

    I expect the minor loop to run through 16 samples, then iterate the major loop (on the same channel). If I set CITER and BITER to 1 I successfully get 16 samples. If I set CITER and BITER to 2 I would expect to get 32 samples. Unfortunately, and strangely I only get 17 samples. Can anyone see what I didn't set up correctly?


    Code:
    Code:
    #include <Arduino.h>
    
    //Teensy4.1 Pin Declarations
    const int SDO = 11;
    const int SDI = 12;
    const int SCO = 13;
    const int nFSO = 10;
    const int nFSI = 4;
    const int nSYNC = 5;
    const int OVERRANGE = 6;
    const int nRESET = 7;
    const int HEARTBEAT = 8;
    const int ErrLED = 9;
    
    //DMA Buffer
    #define DMASIZE 100
    uint32_t dmaDestination[DMASIZE];
    
    //Functions
    void configSpi();
    void configDMA();
    void startSPI();
    void startDMA();
    void startADC();
    void printDMABUFFER();
    
    void setup() 
    {
    	Serial.begin(115200);
    
      pinMode(nFSI, OUTPUT);
      pinMode(nSYNC, INPUT);
      pinMode(OVERRANGE, INPUT);
      pinMode(nRESET, OUTPUT);
      pinMode(HEARTBEAT, OUTPUT);
      pinMode(ErrLED, OUTPUT);
      
      digitalWrite(HEARTBEAT, HIGH);
      digitalWrite(ErrLED, HIGH);
    
      digitalWrite(nSYNC, HIGH);
      digitalWrite(SDI, LOW);
      digitalWrite(nFSI, HIGH);
      digitalWrite(nRESET, LOW);
    
      delay(1000);
      
      Serial.println("Preparing source and destination");
      memset(dmaDestination, 0x00, DMASIZE);
      Serial.println("DMA BUFFER: ........");
      printDMABUFFER();
      Serial.println("Buffers are Ready...");
    
      Serial.println("Starting ADC...");
      startADC();
    
      /** set up SPI **/
      Serial.println("Setting up, and starting SPI...");
    	configSPI();
      startSPI();
      while((LPSPI4_FSR >> 16) < 16)
      {
        Serial.println("WAITING FOR FIFO TO FILL UP..,");
        delayMicroseconds(10);
      }
      Serial.println("Data Received"); 
    
      for(int i = 0; i<16; i++)
      {
        dmaDestination[i] = LPSPI4_RDR;
      }
      
      Serial.println("Data Copied"); 
      printDMABUFFER();
      
      Serial.println("Clearing buffer....");
      memset(dmaDestination, 0x00, DMASIZE);
      printDMABUFFER();
      
      Serial.println("Setting up DMA...");
      configDMA();
      startDMA();
      
      Serial.println("Starting DMA Transfer...");
      
      while(!(bool)(DMA_TCD1_CSR & 1<<7));
      
      Serial.println("DONE Transfer...");
    
      printDMABUFFER();
      Serial.print("Error Register: "); Serial.println(DMA_ES, BIN);
      
    
    	
    }
    
    void loop() 
    {            
      Serial.print("RXCOUNT: "); Serial.println(LPSPI4_FSR >> 16);
      if((LPSPI4_FSR >> 16)>15)
      {
        LPSPI4_CR |= LPSPI_CR_RRF; // reset SPI Registers
      }
      delayMicroseconds(1);
    }
    
    void configDMA()
    {
      CCM_CCGR5 |= CCM_CCGR5_DMA(CCM_CCGR_ON);
      
      DMA_CR = DMA_CR_GRP0PRI | DMA_CR_EMLM | DMA_CR_CLM | DMA_CR_EDBG; //Group 1 Channel Priroty, Minor Loop Mapping, DEBUG Mode
      DMA_CERQ = 1; //Clear enable request for Channel 1
      DMA_CERR = 1; //Clear Errrir Register for channel 1
      DMA_CEEI = 1; //Clear enable error interrupt register for channel 1
      DMA_CINT = 1; //Clear Interupt Request Register channel 1
      
      DMA_ERQ = 1;
      DMA_TCD1_CITER = 5; //Set Major Iteration Count to 1
      DMA_TCD1_BITER = 5; //Set Starting MAjor Interation Count to 1
      DMA_TCD1_NBYTES = 64; //Tell it to transfer 16 bytes of data
      DMA_TCD1_SADDR = &LPSPI4_RDR; //Source Address
      DMA_TCD1_SOFF = 0; //Source Offset
      DMA_TCD1_ATTR = DMA_TCD_ATTR_SSIZE(DMA_TCD_ATTR_SIZE_32BIT) | DMA_TCD_ATTR_DSIZE(DMA_TCD_ATTR_SIZE_32BIT);
      DMA_TCD1_SLAST = -64; //put the source address back to the beginning when done. 
      DMA_TCD1_DADDR = &dmaDestination;//&dmaDestination;
      DMA_TCD1_DOFF = 4;
      DMA_TCD1_CITER_ELINKYES |= DMA_TCD_CITER_ELINK | DMA_TCD_CITER_ELINKYES_LINKCH(1);
      DMA_TCD1_BITER_ELINKYES |= DMA_TCD_CITER_ELINK | DMA_TCD_CITER_ELINKYES_LINKCH(1);
      DMA_TCD1_DLASTSGA = 0;
      //DMA_TCD1_CSR = DMA_TCD_CSR_INTMAJOR | DMA_TCD_CSR_DREQ;
      //DMA_TCD1_CSR = DMA_TCD_CSR_MAJORLINKCH(1) | DMA_TCD_CSR_MAJORELINK;
      DMAMUX_CHCFG1 = 0; //disable rxChannel
      //Serial.print("DMAMUX CHCFG1 Register: "); Serial.println(DMAMUX_CHCFG1);
      DMAMUX_CHCFG1 = DMAMUX_CHCFG_ENBL | DMAMUX_SOURCE_LPSPI4_RX; //Enable rxChannel    
      //Serial.print("DMAMUX CHCFG1 Register: "); Serial.println(DMAMUX_CHCFG1);
    }
    
    
    void startDMA()
    {
      DMA_TCD1_CSR |= DMA_TCD_CSR_START;
    }
      
    
    // initialize LPSPI4
    void configSPI()
    {	
    	CCM_CCGR1 |= CCM_CCGR1_LPSPI4(3);		// Turn on SPI clock	
    	
      //MOSI - SDO Setup
    	IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_02 = 3;						
    	IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_02 = 0	| IOMUXC_PAD_DSE(0)	| IOMUXC_PAD_SPEED(3);
    	IOMUXC_LPSPI4_SDO_SELECT_INPUT = 0;		
    
      //MISO - SDI Setup      
    	IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_01 = 3;					
    	IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_01 = 0	| IOMUXC_PAD_DSE(0)	| IOMUXC_PAD_SPEED(3);
    	IOMUXC_LPSPI4_SDI_SELECT_INPUT = 0;			
    
      //SCK - SCO Setup
    	IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_03 = 3;				
    	IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = 0	| IOMUXC_PAD_DSE(0)	| IOMUXC_PAD_SPEED(3);
      IOMUXC_LPSPI4_SCK_SELECT_INPUT = 0;  
    
      //CS - PCSO - FSO Setup
    	IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_00 = 3;					
    	IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_00 = 0  | IOMUXC_PAD_DSE(0)	| IOMUXC_PAD_SPEED(3);
      IOMUXC_LPSPI4_PCS0_SELECT_INPUT = 0;
    
    	
    	LPSPI4_CR &= ~LPSPI_CR_MEN;				// disable SPI
    	LPSPI4_CR = 0	| LPSPI_CR_RST | LPSPI_CR_RTF	| LPSPI_CR_RRF;	// reset SPI Registers
    	LPSPI4_CR = 0;							// turn off software reset															
      LPSPI4_CFGR1 = 0 | LPSPI_CFGR1_PINCFG(3);  //SOUT used for Input Data, SIN used for output data (Tested)
    	LPSPI4_FCR = 0 | LPSPI_FCR_RXWATER(10) | LPSPI_FCR_RXWATER(5);							
    	LPSPI4_TCR = 0 | LPSPI_TCR_FRAMESZ(31);				// use 31+1 bits (32-bits) per transfer
      LPSPI4_DER = LPSPI_DER_RDDE;							
    
    }
    
    void startADC()
    {
      digitalWrite(nRESET, LOW);
      delay(1);
      digitalWrite(nRESET, HIGH);
      delay(2000);
    }
    
    void startSPI()
    {
      LPSPI4_CR |= LPSPI_CR_MEN;        // ENABLE LPSPI4
    }
    
    
    void printDMABUFFER()
    {
      for (int i = 0; i<DMASIZE; i++)
      {
        Serial.print(i);Serial.print(". ");Serial.print(dmaDestination[i] >> 8);Serial.print("\t");
      }
      Serial.println();
    }

    OUTPUT:

    Preparing source and destination

    DMA BUFFER: ........

    0. 0 1. 0 2. 0 3. 0 4. 0 5. 0 6. 0 7. 0 8. 0 9. 0 10. 0 11. 0 12. 0 13. 0 14. 0 15. 0 16. 0 17. 0 18. 0 19. 0 20. 0 21. 0 22. 0 23. 0 24. 0 25. 0 26. 0 27. 0 28. 0 29. 0 30. 0 31. 0 32. 0 33. 0 34. 0 35. 0 36. 0 37. 0 38. 0 39. 0 40. 0 41. 0 42. 0 43. 0 44. 0 45. 0 46. 0 47. 0 48. 0 49. 0 50. 0 51. 0 52. 0 53. 0 54. 0 55. 0 56. 0 57. 0 58. 0 59. 0 60. 0 61. 0 62. 0 63. 0 64. 0 65. 0 66. 0 67. 0 68. 0 69. 0 70. 0 71. 0 72. 0 73. 0 74. 0 75. 0 76. 0 77. 0 78. 0 79. 0 80. 0 81. 0 82. 0 83. 0 84. 0 85. 0 86. 0 87. 0 88. 0 89. 0 90. 0 91. 0 92. 0 93. 0 94. 0 95. 0 96. 0 97. 0 98. 0 99. 0

    Buffers are Ready...

    Starting ADC...

    Setting up, and starting SPI...

    WAITING FOR FIFO TO FILL UP..,

    WAITING FOR FIFO TO FILL UP..,

    WAITING FOR FIFO TO FILL UP..,

    WAITING FOR FIFO TO FILL UP..,

    WAITING FOR FIFO TO FILL UP..,

    WAITING FOR FIFO TO FILL UP..,

    WAITING FOR FIFO TO FILL UP..,

    WAITING FOR FIFO TO FILL UP..,

    WAITING FOR FIFO TO FILL UP..,

    WAITING FOR FIFO TO FILL UP..,

    Data Received

    Data Copied

    0. 1579264 1. 1580576 2. 1573000 3. 1572928 4. 1580998 5. 1572880 6. 1580050 7. 1580160 8. 1580800 9. 1580556 10. 1572864 11. 1572878 12. 1579265 13. 1573132 14. 1572961 15. 1579076 16. 0 17. 0 18. 0 19. 0 20. 0 21. 0 22. 0 23. 0 24. 0 25. 0 26. 0 27. 0 28. 0 29. 0 30. 0 31. 0 32. 0 33. 0 34. 0 35. 0 36. 0 37. 0 38. 0 39. 0 40. 0 41. 0 42. 0 43. 0 44. 0 45. 0 46. 0 47. 0 48. 0 49. 0 50. 0 51. 0 52. 0 53. 0 54. 0 55. 0 56. 0 57. 0 58. 0 59. 0 60. 0 61. 0 62. 0 63. 0 64. 0 65. 0 66. 0 67. 0 68. 0 69. 0 70. 0 71. 0 72. 0 73. 0 74. 0 75. 0 76. 0 77. 0 78. 0 79. 0 80. 0 81. 0 82. 0 83. 0 84. 0 85. 0 86. 0 87. 0 88. 0 89. 0 90. 0 91. 0 92. 0 93. 0 94. 0 95. 0 96. 0 97. 0 98. 0 99. 0

    Clearing buffer....

    0. 0 1. 0 2. 0 3. 0 4. 0 5. 0 6. 0 7. 0 8. 0 9. 0 10. 0 11. 0 12. 0 13. 0 14. 0 15. 0 16. 0 17. 0 18. 0 19. 0 20. 0 21. 0 22. 0 23. 0 24. 0 25. 0 26. 0 27. 0 28. 0 29. 0 30. 0 31. 0 32. 0 33. 0 34. 0 35. 0 36. 0 37. 0 38. 0 39. 0 40. 0 41. 0 42. 0 43. 0 44. 0 45. 0 46. 0 47. 0 48. 0 49. 0 50. 0 51. 0 52. 0 53. 0 54. 0 55. 0 56. 0 57. 0 58. 0 59. 0 60. 0 61. 0 62. 0 63. 0 64. 0 65. 0 66. 0 67. 0 68. 0 69. 0 70. 0 71. 0 72. 0 73. 0 74. 0 75. 0 76. 0 77. 0 78. 0 79. 0 80. 0 81. 0 82. 0 83. 0 84. 0 85. 0 86. 0 87. 0 88. 0 89. 0 90. 0 91. 0 92. 0 93. 0 94. 0 95. 0 96. 0 97. 0 98. 0 99. 0

    Setting up DMA...

    Starting DMA Transfer...

    DONE Transfer...

    0. 1580544 1. 1572929 2. 1572928 3. 1580551 4. 1572896 5. 1573059 6. 1579056 7. 1580033 8. 1573007 9. 1580800 10. 1572912 11. 1572928 12. 1572866 13. 1581025 14. 1581055 15. 1572864 16. 1580620 17. 0 18. 0 19. 0 20. 0 21. 0 22. 0 23. 0 24. 0 25. 0 26. 0 27. 0 28. 0 29. 0 30. 0 31. 0 32. 0 33. 0 34. 0 35. 0 36. 0 37. 0 38. 0 39. 0 40. 0 41. 0 42. 0 43. 0 44. 0 45. 0 46. 0 47. 0 48. 0 49. 0 50. 0 51. 0 52. 0 53. 0 54. 0 55. 0 56. 0 57. 0 58. 0 59. 0 60. 0 61. 0 62. 0 63. 0 64. 0 65. 0 66. 0 67. 0 68. 0 69. 0 70. 0 71. 0 72. 0 73. 0 74. 0 75. 0 76. 0 77. 0 78. 0 79. 0 80. 0 81. 0 82. 0 83. 0 84. 0 85. 0 86. 0 87. 0 88. 0 89. 0 90. 0 91. 0 92. 0 93. 0 94. 0 95. 0 96. 0 97. 0 98. 0 99. 0

    Error Register: 0

    RXCOUNT: 12

    RXCOUNT: 12

    RXCOUNT: 12

    RXCOUNT: 12

    RXCOUNT: 13

    RXCOUNT: 13

    RXCOUNT: 13

    RXCOUNT: 14

    RXCOUNT: 14

    RXCOUNT: 14

    RXCOUNT: 14

    RXCOUNT: 15

    RXCOUNT: 15

    RXCOUNT: 15

    RXCOUNT: 15

    RXCOUNT: 0

    RXCOUNT: 0

    RXCOUNT: 0

    RXCOUNT: 1
    Attached Files Attached Files

Posting Permissions

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