i2s tester

Files at this revision

API Documentation at this revision

Comitter:
UHSLMarcus
Date:
Thu Feb 02 10:14:27 2017 +0000
Commit message:
procedural test

Changed in this revision

.gitignore Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gitignore	Thu Feb 02 10:14:27 2017 +0000
@@ -0,0 +1,4 @@
+.build
+.mbed
+projectfiles
+*.py*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Feb 02 10:14:27 2017 +0000
@@ -0,0 +1,282 @@
+#include "mbed.h"
+#include "MK64F12.h"
+#include "system_MK64F12.h"
+
+#define I2S_CONFIG_MCLKFREQ             12288000    // Hz
+#define I2S_CONFIG_WORDWIDTH            16          // Bits
+#define I2S_CONFIG_SAMPLERATE           32000       // Hz
+#define I2S_CONFIG_FRAMEWIDTH           2           // Words
+#define I2S_CONFIG_INTERUPT_THRESH      4
+
+#define I2S_CONFIG_MAX_BCLK_DIV         255
+#define I2S_CONFIG_MAX_MCLK_DIV         512
+#define I2S_CONFIG_MAX_MCLK_FRACT       255
+
+
+Serial pc(USBTX, USBRX);
+
+const char *byte_to_binary(uint8_t in)
+{
+    static char b[9];
+    b[0] = '\0';
+
+    int z;
+    for (z = 128; z > 0; z >>= 1)
+    {
+        strcat(b, ((in & z) == z) ? "1" : "0");
+    }
+
+    return b;
+}
+
+
+volatile bool itr_flag = false;
+void _i2s_itr(void) {
+    itr_flag = true;
+    I2S0->TCSR &= ~I2S_TCSR_FRIE_MASK;
+}
+
+int main()
+{
+    pc.baud(115200);
+    pc.printf("Starting...\r");
+    pc.printf("System core clock: %luhz\r", (unsigned long)SystemCoreClock);
+    
+    pc.printf("Disabling I2S interupt...");
+    NVIC_DisableIRQ (I2S0_Tx_IRQn);
+    pc.printf("Done.\rReplacing I2S interupt service routine address...");
+    NVIC_SetVector (I2S0_Tx_IRQn, (uint32_t)&_i2s_itr);
+    pc.printf("Done.\rEnabling I2S interupts...");
+    NVIC_EnableIRQ (I2S0_Tx_IRQn);
+    pc.printf("Done.\r");
+    
+    pc.printf("Setting pins MUX to I2S...");
+    
+    // Set PORTC and PORTB to clocked  gate control to allow register access without hanging the MCU
+    SIM->SCGC5 |= SIM_SCGC5_PORTC(0x1); // Set PORTC clocked gate control to enabled
+    SIM->SCGC5 |= SIM_SCGC5_PORTB(0x1); // Set PORTC clocked gate control to enabled
+    
+    PORTC->PCR[8] &= ~PORT_PCR_MUX_MASK; // Clear PTC8
+    PORTC->PCR[8] |= PORT_PCR_MUX(0x04); // Set PTC8 to 4, I2S0_MCLK
+    
+    PORTC->PCR[1] &= ~PORT_PCR_MUX_MASK; // Clear PTC1
+    PORTC->PCR[1] |= PORT_PCR_MUX(0x04); // Set PTC1 to 4, I2S0_TXD0
+    
+    PORTB->PCR[18] &= ~PORT_PCR_MUX_MASK; // Clear PTB18
+    PORTB->PCR[18] |= PORT_PCR_MUX(0x04); // Set PTB18 to 4, I2S0_TX_BCLK
+    
+    PORTB->PCR[19] &= ~PORT_PCR_MUX_MASK; // Clear PTB19
+    PORTB->PCR[19] |= PORT_PCR_MUX(0x04); // Set PTB19 to 4, I2S0_TX_FS
+    
+    pc.printf("Set\r \tPTC8=%d\r \tPTC1=%d\r \tPTB18=%d\r \tPTB19=%d\r", 
+        (PORTC->PCR[8] >> PORT_PCR_MUX_SHIFT) & 0b111, 
+        (PORTC->PCR[1] >> PORT_PCR_MUX_SHIFT) & 0b111, 
+        (PORTB->PCR[18] >> PORT_PCR_MUX_SHIFT) & 0b111, 
+        (PORTB->PCR[19] >> PORT_PCR_MUX_SHIFT) & 0b111);
+    
+    pc.printf("Starting I2S init...\r");
+    SIM->SCGC6 |= SIM_SCGC6_I2S(0x1); // Set I2S clocked gate control to enabled
+    
+    pc.printf("Setting I2S Master Clock Fraction and Divider...");
+    
+    //output = input *[(I2SFRAC+1) / (I2SDIV+1) ] = (120mhz * 0.1024) = (120M* (?/?)) = 12.288 MHz 
+    
+    float target = (float)I2S_CONFIG_MCLKFREQ/(float)SystemCoreClock;   // target result from the division
+    float least_difference = 1;                                         // store the lowest error 
+    int best_numerator = 0;                                             // store the numerator which produced the lowest error
+    int best_denominator = 0;                                           // store the denominator which produced the lowest error
+    
+    for (int denominator = 1; denominator < I2S_CONFIG_MAX_MCLK_DIV; denominator++) {
+        int numerator = int(denominator * target);
+        if (numerator > 0 && numerator < I2S_CONFIG_MAX_MCLK_DIV) {
+            float diff = abs((float)((float)numerator/(float)denominator) - target);
+            if (diff < least_difference) {
+                least_difference = diff;
+                best_numerator = numerator;     
+                best_denominator = denominator;
+            }
+            if (diff == 0) break;
+        }
+    }
+    I2S0->MDR |= I2S_MDR_FRACT(best_numerator-1) | I2S_MDR_DIVIDE(best_denominator-1);
+    
+    pc.printf("Set. MDR[FRACT]=%d, MDR[DIVIDE]=%d, Error=%f\r", (I2S0->MDR >> I2S_MDR_FRACT_SHIFT) & 0xff, (I2S0->MDR >> I2S_MDR_DIVIDE_SHIFT) & 0xfff, least_difference);
+    
+    pc.printf("Setting I2S Master Clock...");
+    I2S0->MCR |= I2S_MCR_MOE(1);
+    pc.printf("Set. MCR[MOE] (MCLK Output Enable) = %d, MCR[MICS] (MCLK Input Clock Select) = %d\r", (I2S0->MCR >> I2S_MCR_MOE_SHIFT) & 1, (I2S0->MCR >> I2S_MCR_MICS_SHIFT) & 0b11);
+    
+    pc.printf("Setting Bit Clock Divider...");
+    
+    //Bit clock = sample frequency * words in a frame * bits in a word = 32000*2*16 = 1.024 MHz = 12.288 MHz/12
+    int bit_clock_div = I2S_CONFIG_MCLKFREQ/(I2S_CONFIG_SAMPLERATE*I2S_CONFIG_FRAMEWIDTH*I2S_CONFIG_WORDWIDTH);
+    
+    //12 = (DIV+1)*2 => DIV+1 = 12/2 = 6 => DIV = 6-1 = 5
+    int DIV = (bit_clock_div/2)-1;
+    I2S0->TCR2 |= I2S_TCR2_DIV(DIV);
+    pc.printf("Set. TCR2[DIV] (Bit Clock Divide) = %d\r", (I2S0->TCR2 >> I2S_TCR2_DIV_SHIFT) & 0xff);
+    
+    pc.printf("Setting I2S Configuration Registers...\r");
+    
+    
+    pc.printf("Clearing TSCR[TE] (Trasmiitter Enable)...");
+    I2S0->TCSR &= ~I2S_TCSR_TE_MASK;
+    pc.printf("Cleared. TSCR[TE]=%d\r", (I2S0->TCSR >> I2S_TCSR_TE_SHIFT) & 1);
+    
+    pc.printf("Setting TCR1[TFW] (Transmit FIFO Watermark) to 4...");
+    I2S0->TCR1 |= I2S_TCR1_TFW(I2S_CONFIG_INTERUPT_THRESH); // threshold for generating FIFO request
+    pc.printf("Set. TCR1[TFW]=%d\r", (I2S0->TCR1 >> I2S_TCR1_TFW_SHIFT) & 0b111);
+    
+    pc.printf("Setting TCR2...");
+    I2S0->TCR2 &= ~I2S_TCR2_SYNC_MASK;  // Sync to 00
+    I2S0->TCR2 |= I2S_TCR2_MSEL(1)      // MSEL to MCLK 1
+                | I2S_TCR2_BCD(1);      // Bit Clock Direction to output (internal MCLK)
+    pc.printf("Set.\r \t[SYNC] Synchronous Mode = %d\r \t[MSEL] MCLK Select = %d\r \t[BCP] Bit Clock Polarity = %d\r \t[BCD] Bit Clock Direction = %d\r",
+        (I2S0->TCR2 >> I2S_TCR2_SYNC_SHIFT) & 0b11,
+        (I2S0->TCR2 >> I2S_TCR2_MSEL_SHIFT) & 1,
+        (I2S0->TCR2 >> I2S_TCR2_BCP_SHIFT) & 1,
+        (I2S0->TCR2 >> I2S_TCR2_BCD_SHIFT) & 1);
+        
+    pc.printf("Setting TCR3[TCE] (Transmit Channel Enable) to 1 (channel 0 enable)...");
+    I2S0->TCR3 |= I2S_TCR3_TCE(1);
+    pc.printf("Set. TCR1[TFW]=%d\r", (I2S0->TCR3 >> I2S_TCR3_TCE_SHIFT) & 0b11);
+    
+    pc.printf("Setting TCR4...");
+    I2S0->TCR4 |= I2S_TCR4_FRSZ(I2S_CONFIG_FRAMEWIDTH-1)    // Frame width (number of words -1)
+                | I2S_TCR4_SYWD(I2S_CONFIG_WORDWIDTH-1)     // Sync width (bits in word0 -1) (don't fully understand this one)
+                | I2S_TCR4_MF(1)                            // MSB Transmitted first
+                | I2S_TCR4_FSD(1);                          // Frame sync clock to output (master)
+    pc.printf("Set.\r \t[FRSZ] Frame size = %d\r \t[SYWD] Sync Width = %d\r \t[MF] MSB First = %d\r",
+        (I2S0->TCR4 >> I2S_TCR4_FRSZ_SHIFT) & 0b11111,
+        (I2S0->TCR4 >> I2S_TCR4_SYWD_SHIFT) & 0b11111,
+        (I2S0->TCR4 >> I2S_TCR4_MF_SHIFT) & 1);
+    pc.printf(" \t[FSE] Frame Sync Early = %d\r \t[FSP] Frame Sync Polarity = %d\r \t[FSD] Frame Sync Direction = %d\r",
+        (I2S0->TCR4 >> I2S_TCR4_FSE_SHIFT) & 1,
+        (I2S0->TCR4 >> I2S_TCR4_FSP_SHIFT) & 1,
+        (I2S0->TCR4 >> I2S_TCR4_FSD_SHIFT) & 1);
+        
+    pc.printf("Setting TCR5...");
+    I2S0->TCR5 |= I2S_TCR5_WNW(I2S_CONFIG_WORDWIDTH-1)
+               | I2S_TCR5_W0W(I2S_CONFIG_WORDWIDTH-1)
+               | I2S_TCR5_FBT(I2S_CONFIG_WORDWIDTH+1);
+    pc.printf("Set\r \t[WNW] Word N Width = %d\r \t[W0W] Word 0 Width = %d\r \t[FBT] First Bit Shifted = %d\r",
+        (I2S0->TCR5 >> I2S_TCR5_WNW_SHIFT) & 0b11111,
+        (I2S0->TCR5 >> I2S_TCR5_W0W_SHIFT) & 0b11111,
+        (I2S0->TCR5 >> I2S_TCR5_FBT_SHIFT) & 0b11111);
+        
+    pc.printf("Setting TSCR[TE] (Trasmiitter Enable) & TSCR[BCE] (Bit Clock Enable) & TSCR[FRIE] (FIFO Request Interrupt Enabled)...");
+    I2S0->TCSR |= I2S_TCSR_TE(1) | I2S_TCSR_BCE(1) | I2S_TCSR_FRIE(1);
+    pc.printf("Set\r \tTSCR[TE] = %d\r \tTSCR[BCE] = %d\r \tTSCR[FRIE] = %d\r",
+        (I2S0->TCSR >> I2S_TCSR_TE_SHIFT) & 1,
+        (I2S0->TCSR >> I2S_TCSR_BCE_SHIFT) & 1,
+        (I2S0->TCSR >> I2S_TCSR_FRIE_SHIFT) & 1);
+    
+      
+    pc.printf("I2S Init Complete\rStarting loop...\r");
+    
+    for (int i = 0; i < 9; i++) {
+        pc.printf("Transmit FIFO Register Read Pointer: %s\r", byte_to_binary(I2S0->TFR[0] & 0xF));
+        pc.printf("Transmit FIFO Register Write Pointer: %s\r", byte_to_binary((I2S0->TFR[0] >> I2S_TFR_WFP_SHIFT) & 0xF));
+        pc.printf("FRF: %d, WSF: %d, SEF: %d, FEF: %d, FWF: %d\r", 
+                (I2S0->TCSR >> I2S_TCSR_FRF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_WSF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_SEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FWF_SHIFT) & 1);
+        
+        if (I2S0->TCSR & I2S_TCSR_WSF_MASK) I2S0->TCSR |= I2S_TCSR_WSF(1); // clear flags...
+        if (I2S0->TCSR & I2S_TCSR_SEF_MASK) I2S0->TCSR |= I2S_TCSR_SEF(1);
+        if (I2S0->TCSR & I2S_TCSR_FEF_MASK) I2S0->TCSR |= I2S_TCSR_FEF(1);
+        I2S0->TDR[0] = I2S_TDR_TDR(20);
+    }
+    
+        
+    /*while (true) {
+        if (itr_flag) {
+            itr_flag = false;
+            pc.printf("I2S interupt triggered\r");
+            pc.printf("Transmit FIFO Register Read Pointer: %s\r", byte_to_binary(I2S0->TFR[0] & 0xF));
+            pc.printf("Transmit FIFO Register Write Pointer: %s\r", byte_to_binary((I2S0->TFR[0] >> I2S_TFR_WFP_SHIFT) & 0xF));
+            pc.printf("FRF: %d, WSF: %d, SEF: %d, FEF: %d, FWF: %d", 
+                (I2S0->TCSR >> I2S_TCSR_FRF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_WSF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_SEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FWF_SHIFT) & 1);
+            I2S0->TDR[0] = I2S_TDR_TDR(20);
+            pc.printf("Transmit FIFO Register Read Pointer: %s\r", byte_to_binary(I2S0->TFR[0] & 0xF));
+            pc.printf("Transmit FIFO Register Write Pointer: %s\r", byte_to_binary((I2S0->TFR[0] >> I2S_TFR_WFP_SHIFT) & 0xF));
+            pc.printf("FRF: %d, WSF: %d, SEF: %d, FEF: %d, FWF: %d", 
+                (I2S0->TCSR >> I2S_TCSR_FRF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_WSF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_SEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FWF_SHIFT) & 1);
+            I2S0->TDR[0] = I2S_TDR_TDR(20);
+            pc.printf("Transmit FIFO Register Read Pointer: %s\r", byte_to_binary(I2S0->TFR[0] & 0xF));
+            pc.printf("Transmit FIFO Register Write Pointer: %s\r", byte_to_binary((I2S0->TFR[0] >> I2S_TFR_WFP_SHIFT) & 0xF));
+            pc.printf("FRF: %d, WSF: %d, SEF: %d, FEF: %d, FWF: %d", 
+                (I2S0->TCSR >> I2S_TCSR_FRF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_WSF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_SEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FWF_SHIFT) & 1);
+            I2S0->TDR[0] = I2S_TDR_TDR(20);
+            pc.printf("Transmit FIFO Register Read Pointer: %s\r", byte_to_binary(I2S0->TFR[0] & 0xF));
+            pc.printf("Transmit FIFO Register Write Pointer: %s\r", byte_to_binary((I2S0->TFR[0] >> I2S_TFR_WFP_SHIFT) & 0xF));
+            pc.printf("FRF: %d, WSF: %d, SEF: %d, FEF: %d, FWF: %d", 
+                (I2S0->TCSR >> I2S_TCSR_FRF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_WSF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_SEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FWF_SHIFT) & 1);
+            I2S0->TDR[0] = I2S_TDR_TDR(20);
+            pc.printf("Transmit FIFO Register Read Pointer: %s\r", byte_to_binary(I2S0->TFR[0] & 0xF));
+            pc.printf("Transmit FIFO Register Write Pointer: %s\r", byte_to_binary((I2S0->TFR[0] >> I2S_TFR_WFP_SHIFT) & 0xF));
+            pc.printf("FRF: %d, WSF: %d, SEF: %d, FEF: %d, FWF: %d", 
+                (I2S0->TCSR >> I2S_TCSR_FRF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_WSF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_SEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FWF_SHIFT) & 1);
+            I2S0->TDR[0] = I2S_TDR_TDR(20);
+            pc.printf("Transmit FIFO Register Read Pointer: %s\r", byte_to_binary(I2S0->TFR[0] & 0xF));
+            pc.printf("Transmit FIFO Register Write Pointer: %s\r", byte_to_binary((I2S0->TFR[0] >> I2S_TFR_WFP_SHIFT) & 0xF));
+            pc.printf("FRF: %d, WSF: %d, SEF: %d, FEF: %d, FWF: %d", 
+                (I2S0->TCSR >> I2S_TCSR_FRF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_WSF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_SEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FWF_SHIFT) & 1);
+            I2S0->TDR[0] = I2S_TDR_TDR(20);
+            pc.printf("Transmit FIFO Register Read Pointer: %s\r", byte_to_binary(I2S0->TFR[0] & 0xF));
+            pc.printf("Transmit FIFO Register Write Pointer: %s\r", byte_to_binary((I2S0->TFR[0] >> I2S_TFR_WFP_SHIFT) & 0xF));
+            pc.printf("FRF: %d, WSF: %d, SEF: %d, FEF: %d, FWF: %d", 
+                (I2S0->TCSR >> I2S_TCSR_FRF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_WSF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_SEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FWF_SHIFT) & 1);
+            I2S0->TDR[0] = I2S_TDR_TDR(20);
+            pc.printf("Transmit FIFO Register Read Pointer: %s\r", byte_to_binary(I2S0->TFR[0] & 0xF));
+            pc.printf("Transmit FIFO Register Write Pointer: %s\r", byte_to_binary((I2S0->TFR[0] >> I2S_TFR_WFP_SHIFT) & 0xF));
+            pc.printf("FRF: %d, WSF: %d, SEF: %d, FEF: %d, FWF: %d", 
+                (I2S0->TCSR >> I2S_TCSR_FRF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_WSF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_SEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FWF_SHIFT) & 1);
+            I2S0->TDR[0] = I2S_TDR_TDR(20);
+            pc.printf("Transmit FIFO Register Read Pointer: %s\r", byte_to_binary(I2S0->TFR[0] & 0xF));
+            pc.printf("Transmit FIFO Register Write Pointer: %s\r", byte_to_binary((I2S0->TFR[0] >> I2S_TFR_WFP_SHIFT) & 0xF));
+            pc.printf("FRF: %d, WSF: %d, SEF: %d, FEF: %d, FWF: %d", 
+                (I2S0->TCSR >> I2S_TCSR_FRF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_WSF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_SEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FEF_SHIFT) & 1,
+                (I2S0->TCSR >> I2S_TCSR_FWF_SHIFT) & 1);
+            I2S0->TDR[0] = I2S_TDR_TDR(20);
+        }
+    }*/
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Thu Feb 02 10:14:27 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#269f58d75b752a4e67a6a2d8c5c698635ffd6752