Library to control and transfer data from NXP SGTL5000. As used on the Teensy Audio Shield. It uses DMA to transfer I2S FIFO data.

The Library now supports dual codecs. Allowing all 4 channels of the Teensy I2S interface to RX and TX data to separate SGTL5000 devices.

The ISR routines that handles pointer swaps for double buffering has been fully coded in assembler to reduce overhead and now takes < 800nS per FIFO transfer when using all 4 channels.

Support added for all typical sample rates and system Clock speeds of 96Mhz or 120Mhz.

Pause and Resume functions added to allow quick and simple suppression of IRQs and stream halting and restart. This required software triggered IRQ, in order to ensure accurate word sync control.

Revision:
6:4ab5aaeaa064
Parent:
4:91354c908416
Child:
7:d65476c153a4
--- a/sgtl5000.h	Fri Jun 30 09:46:54 2017 +0000
+++ b/sgtl5000.h	Sat Jul 01 10:20:45 2017 +0000
@@ -57,7 +57,7 @@
 *   {
 *       codec.modify_i2c(SGTL5000_ANA_HP_CTRL, 0x18, SGTL5000_ANA_HP_CTRL_HP_VOL_RIGHT_MASK);   // Headphone volume control with 0.5 dB steps.0x00 = +12 dB, 0x01 = +11.5 dB, 0x18 = 0 dB,...0x7F = -51.5 dB
 *       codec.modify_i2c(SGTL5000_ANA_HP_CTRL, 0x18, SGTL5000_ANA_HP_CTRL_HP_VOL_LEFT_MASK);
-*    
+*
 *       codec.attach_SYNC_NB((uint32_t)&I2S_SYNC_ISR);
 *       codec.freq(96);
 *       codec.start_SYNC((uint32_t)&RX_AudioL, (uint32_t)&RX_AudioR, (uint32_t)&TX_AudioL, (uint32_t)&TX_AudioR, I2S_FIFO_BS)
@@ -107,7 +107,7 @@
     @returns            0 = register data, -1 = fail
     */
     int32_t read_i2c(uint32_t reg_addr, uint32_t mask = 0xFFFF);
-    
+
     /*!
     @brief  Write 16bit register of SGTL5000
     @param  reg_addr    16bit address of the codec control register
@@ -115,7 +115,7 @@
     @returns            0 = success, -1 = fail
     */
     int32_t write_i2c(uint32_t reg_addr, uint32_t data);
-    
+
     /*!
     @brief  Modify masked bits within 16bit register of SGTL5000
     @param  reg_addr    16bit address of the codec control register
@@ -124,8 +124,8 @@
                         The function automatically shifts the data to the position of the first masked bit.
     @returns            0 = success, -1 = fail
     */
-    int32_t modify_i2c(uint32_t reg_addr, uint32_t data, uint32_t mask);       
-    
+    int32_t modify_i2c(uint32_t reg_addr, uint32_t data, uint32_t mask);
+
     /*!
     @brief Attach a callback function to TX
     @param func         Address of the user function to be called from the TX FIFO triggered ISR.
@@ -135,7 +135,7 @@
                         Fails if already attached, must detach first.
     */
     int32_t attach_TX(Callback<void()> func);
-    
+
     /*!
     @brief Attach an ISR function to DMA TX
     @param user_ISR     Address of the user function to be assigned as the NVIC vector for the DMA TX FIFO triggered user_ISR.
@@ -146,7 +146,7 @@
                         across the whole system needs consideration.
     */
     void attach_TX_NB(uint32_t user_ISR, uint32_t irq_pri = 1, IRQn sw_irq = Reserved54_IRQn);
-    
+
     /*!
     @brief Stop TX channel and flag as detached.
                         During running stream, the callback based function can not be changed. However changes to the NB IRQ based attachment can have the vector changed on-the-fly
@@ -157,7 +157,7 @@
     @brief Stops i2s TX channel but maintains clocking.
     */
     void stop_TX(void);
-    
+
     /*!
     @brief  Starts the codec I2S interface and begins transferring TX buffers. Transfers use DMA.
     @param  BufTX_L_safe    A pointer address to the TX Left channel data.
@@ -192,7 +192,7 @@
                         Fails if already attached, must detach first.
     */
     int32_t attach_RX(Callback<void()> func);
-    
+
     /*!
     @brief Attach an ISR function to DMA RX
     @param user_ISR     User function to be assigned as the NVIC vector for the DMA RX FIFO triggered user_ISR.
@@ -203,7 +203,7 @@
                         across the whole system needs consideration.
     */
     void attach_RX_NB(uint32_t user_ISR, uint32_t irq_pri = 1, IRQn sw_irq = Reserved55_IRQn);
-    
+
     /*!
     @brief Stop RX channel and flag as detached.
                         During running stream, the callback based function can not be changed. However changes to the NB IRQ based attachment can have the vector changed on-the-fly
@@ -214,7 +214,7 @@
     @brief Stops i2s RX channel but maintains clocking.
     */
     void stop_RX(void);
-    
+
     /*!
     @brief  Starts the codec I2S interface and begins transferring RX buffers. Transfers use DMA.
     @param  BufRX_L_safe    A pointer address to the RX Left channel data.
@@ -249,7 +249,7 @@
                         Fails if already attached, must detach first.
     */
     int32_t attach_SYNC(Callback<void()> func);
-    
+
     /*!
     @brief Attach a ISR function to DMA SYNC
     @param user_ISR     User function to be assigned as the NVIC vector for the DMA SYNC FIFO triggered user_ISR.
@@ -331,12 +331,7 @@
 
 
 protected:
-
-
-    static uint32_t volatile debug[16];
-
-
-
+    static uint32_t debug[16];
 
 
 private:
@@ -349,11 +344,17 @@
 
     void init_DMA(void);                                                        // Configure SYNC DMA settings on MK20DX256
 
-    static void tx_dma_ISR(void);                                               // Handle TX DMA transfers complete
+    static void tx_dma_ISR_NB(void);                                            // Handle TX DMA transfers complete using IRQs to user
+
+    static void rx_dma_ISR_NB(void);                                            // Handle RX DMA transfers complete using IRQs to user
+
+    static void sync_dma_ISR_NB(void);                                          // Handle SYNC DMA transfers complete using IRQs to user
 
-    static void rx_dma_ISR(void);                                               // Handle RX DMA transfers complete
+    static void tx_dma_ISR(void);                                               // Handle TX DMA transfers complete using Callback
 
-    static void sync_dma_ISR(void);                                             // Handle SYNC DMA transfers complete
+    static void rx_dma_ISR(void);                                               // Handle RX DMA transfers complete using Callback
+
+    static void sync_dma_ISR(void);                                             // Handle SYNC DMA transfers complete using Callback
 
     static void tx_I2S_ISR(void);                                               // Handle TX word start allignment
 
@@ -362,17 +363,11 @@
     static void sync_I2S_ISR(void);                                             // Handle SYNC word start allignment
 
 
-    static uint32_t I2S_RX_Buffer[];                                            // Define global statics needed within ISRs
-    static uint32_t I2S_TX_Buffer[];
-    static uint32_t *BufRX_L_safe;
+
+    static uint32_t *BufRX_L_safe;                                              // Define statics for ISRs
     static uint32_t *BufRX_R_safe;
     static uint32_t *BufTX_L_safe;
     static uint32_t *BufTX_R_safe;
-    static uint32_t TX_block_size;
-    static uint32_t RX_block_size;
-    static uint32_t SYNC_attach_type;
-    static uint32_t TX_attach_type;
-    static uint32_t RX_attach_type;
     static uint32_t RX_DMAch;
     static uint32_t TX_DMAch;
     static IRQn SYNC_swIRQ;
@@ -382,18 +377,23 @@
     static Callback<void()> RX_user_func;
     static Callback<void()> SYNC_user_func;
 
+    uint32_t I2S_RX_Buffer[16];
+    uint32_t I2S_TX_Buffer[16];
+    uint32_t SYNC_attach_type;
+    uint32_t TX_attach_type;
+    uint32_t RX_attach_type;
+    uint32_t TX_block_size;
+    uint32_t RX_block_size;
     uint32_t TX_bs_bytes;
     uint32_t RX_bs_bytes;
     bool SYNC_run;
     bool TX_run;
     bool RX_run;
-
     bool SYNC_attached;
     bool TX_attached;
     bool RX_attached;
     bool TX_shift;
     bool RX_shift;
-    
     bool packed_RX;
     bool packed_TX;
 };