void AudioOutputI2SQuad::begin(void) { #if 1 dma.begin(true); // Allocate the DMA channel first block_ch1_1st = NULL; block_ch2_1st = NULL; block_ch3_1st = NULL; block_ch4_1st = NULL; // TODO: can we call normal config_i2s, and then just enable the extra output? config_i2s(); CORE_PIN22_CONFIG = PORT_PCR_MUX(6); // pin 22, PTC1, I2S0_TXD0 -> ch1 & ch2 CORE_PIN15_CONFIG = PORT_PCR_MUX(6); // pin 15, PTC0, I2S0_TXD1 -> ch3 & ch4 dma.TCD->SADDR = i2s_tx_buffer; dma.TCD->SOFF = 2; dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1) | DMA_TCD_ATTR_DMOD(3); dma.TCD->NBYTES_MLNO = 4; dma.TCD->SLAST = -sizeof(i2s_tx_buffer); dma.TCD->DADDR = &I2S0_TDR0; dma.TCD->DOFF = 4; dma.TCD->CITER_ELINKNO = sizeof(i2s_tx_buffer) / 4; dma.TCD->DLASTSGA = 0; dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 4; dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_TX); update_responsibility = update_setup(); dma.enable(); I2S0_TCSR = I2S_TCSR_SR; I2S0_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE; dma.attachInterrupt(isr); #endif }
void AudioOutputI2S::begin(void) { dma.begin(true); // Allocate the DMA channel first block_left_1st = NULL; block_right_1st = NULL; // TODO: should we set & clear the I2S_TCSR_SR bit here? config_i2s(); CORE_PIN22_CONFIG = PORT_PCR_MUX(6); // pin 22, PTC1, I2S0_TXD0 #if defined(KINETISK) dma.TCD->SADDR = i2s_tx_buffer; dma.TCD->SOFF = 2; dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); dma.TCD->NBYTES_MLNO = 2; dma.TCD->SLAST = -sizeof(i2s_tx_buffer); dma.TCD->DADDR = (void *)((uint32_t)&I2S0_TDR0 + 2); dma.TCD->DOFF = 0; dma.TCD->CITER_ELINKNO = sizeof(i2s_tx_buffer) / 2; dma.TCD->DLASTSGA = 0; dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2; dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; #endif dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_TX); update_responsibility = update_setup(); dma.enable(); I2S0_TCSR = I2S_TCSR_SR; I2S0_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE; dma.attachInterrupt(isr); }
void AudioInputI2SQuad::begin(void) { dma.begin(true); // Allocate the DMA channel first // TODO: should we set & clear the I2S_RCSR_SR bit here? AudioOutputI2SQuad::config_i2s(); CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0 CORE_PIN30_CONFIG = PORT_PCR_MUX(4); // pin 30, PTC11, I2S0_RXD1 #if defined(KINETISK) dma.TCD->SADDR = &I2S0_RDR0; dma.TCD->SOFF = 4; dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_SMOD(3) | DMA_TCD_ATTR_DSIZE(1); dma.TCD->NBYTES_MLNO = 4; dma.TCD->SLAST = 0; dma.TCD->DADDR = i2s_rx_buffer; dma.TCD->DOFF = 2; dma.TCD->CITER_ELINKNO = sizeof(i2s_rx_buffer) / 4; dma.TCD->DLASTSGA = -sizeof(i2s_rx_buffer); dma.TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 4; dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; #endif dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX); update_responsibility = update_setup(); dma.enable(); I2S0_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE | I2S_RCSR_FRDE | I2S_RCSR_FR; I2S0_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE; // TX clock enable, because sync'd to TX dma.attachInterrupt(isr); }
void AudioOutputI2S2::begin(void) { dma.begin(true); // Allocate the DMA channel first block_left_1st = NULL; block_right_1st = NULL; config_i2s(); CORE_PIN2_CONFIG = 2; //2:TX_DATA0 dma.TCD->SADDR = i2s2_tx_buffer; dma.TCD->SOFF = 2; dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); dma.TCD->NBYTES_MLNO = 2; dma.TCD->SLAST = -sizeof(i2s2_tx_buffer); dma.TCD->DOFF = 0; dma.TCD->CITER_ELINKNO = sizeof(i2s2_tx_buffer) / 2; dma.TCD->DLASTSGA = 0; dma.TCD->BITER_ELINKNO = sizeof(i2s2_tx_buffer) / 2; dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; dma.TCD->DADDR = (void *)((uint32_t)&I2S2_TDR0 + 2); dma.triggerAtHardwareEvent(DMAMUX_SOURCE_SAI2_TX); // I2S2_RCSR |= I2S_RCSR_RE; I2S2_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE; update_responsibility = update_setup(); dma.attachInterrupt(isr); dma.enable(); }
void AudioOutputI2S2slave::begin(void) { dma.begin(true); // Allocate the DMA channel first //pinMode(2, OUTPUT); block_left_1st = NULL; block_right_1st = NULL; AudioOutputI2S2slave::config_i2s(); CORE_PIN2_CONFIG = 2; //2:TX_DATA0 //CORE_PIN33_CONFIG = 2; //2:RX_DATA0 dma.TCD->SADDR = i2s2_tx_buffer; dma.TCD->SOFF = 2; dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); dma.TCD->NBYTES_MLNO = 2; dma.TCD->SLAST = -sizeof(i2s2_tx_buffer); dma.TCD->DADDR = (void *)((uint32_t)&I2S2_TDR0 + 2); dma.TCD->DOFF = 0; dma.TCD->CITER_ELINKNO = sizeof(i2s2_tx_buffer) / 2; dma.TCD->DLASTSGA = 0; dma.TCD->BITER_ELINKNO = sizeof(i2s2_tx_buffer) / 2; dma.triggerAtHardwareEvent(DMAMUX_SOURCE_SAI2_TX); update_responsibility = update_setup(); dma.enable(); dma.attachInterrupt(isr); }
void AudioInputTDM2::begin(void) { dma.begin(true); // Allocate the DMA channel first // TODO: should we set & clear the I2S_RCSR_SR bit here? AudioOutputTDM2::config_tdm(); CORE_PIN33_CONFIG = 2; //2:RX_DATA0 IOMUXC_SAI2_RX_DATA0_SELECT_INPUT = 0; dma.TCD->SADDR = &I2S2_RDR0; dma.TCD->SOFF = 0; dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(2) | DMA_TCD_ATTR_DSIZE(2); dma.TCD->NBYTES_MLNO = 4; dma.TCD->SLAST = 0; dma.TCD->DADDR = tdm_rx_buffer; dma.TCD->DOFF = 4; dma.TCD->CITER_ELINKNO = sizeof(tdm_rx_buffer) / 4; dma.TCD->DLASTSGA = -sizeof(tdm_rx_buffer); dma.TCD->BITER_ELINKNO = sizeof(tdm_rx_buffer) / 4; dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; dma.triggerAtHardwareEvent(DMAMUX_SOURCE_SAI2_RX); update_responsibility = update_setup(); dma.enable(); I2S2_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE | I2S_RCSR_FRDE | I2S_RCSR_FR; I2S2_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE; dma.attachInterrupt(isr); }
void AudioOutputAnalog::begin(void) { dma.begin(true); // Allocate the DMA channel first SIM_SCGC2 |= SIM_SCGC2_DAC0; DAC0_C0 = DAC_C0_DACEN; // 1.2V VDDA is DACREF_2 // slowly ramp up to DC voltage, approx 1/4 second for (int16_t i=0; i<2048; i+=8) { *(int16_t *)&(DAC0_DAT0L) = i; delay(1); } // set the programmable delay block to trigger DMA requests if (!(SIM_SCGC6 & SIM_SCGC6_PDB) || (PDB0_SC & PDB_CONFIG) != PDB_CONFIG || PDB0_MOD != PDB_PERIOD || PDB0_IDLY != 1 || PDB0_CH0C1 != 0x0101) { SIM_SCGC6 |= SIM_SCGC6_PDB; PDB0_IDLY = 1; PDB0_MOD = PDB_PERIOD; PDB0_SC = PDB_CONFIG | PDB_SC_LDOK; PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG; PDB0_CH0C1 = 0x0101; } dma.TCD->SADDR = dac_buffer; dma.TCD->SOFF = 2; dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); dma.TCD->NBYTES_MLNO = 2; dma.TCD->SLAST = -sizeof(dac_buffer); dma.TCD->DADDR = &DAC0_DAT0L; dma.TCD->DOFF = 0; dma.TCD->CITER_ELINKNO = sizeof(dac_buffer) / 2; dma.TCD->DLASTSGA = 0; dma.TCD->BITER_ELINKNO = sizeof(dac_buffer) / 2; dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; dma.triggerAtHardwareEvent(DMAMUX_SOURCE_PDB); update_responsibility = update_setup(); dma.enable(); dma.attachInterrupt(isr); }
void AudioInputI2S::begin(void) { //block_left_1st = NULL; //block_right_1st = NULL; //pinMode(3, OUTPUT); //digitalWriteFast(3, HIGH); //delayMicroseconds(500); //digitalWriteFast(3, LOW); // TODO: should we set & clear the I2S_RCSR_SR bit here? AudioOutputI2S::config_i2s(); CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0 DMA_CR = 0; DMA_TCD1_SADDR = &I2S0_RDR0; DMA_TCD1_SOFF = 0; DMA_TCD1_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); DMA_TCD1_NBYTES_MLNO = 2; DMA_TCD1_SLAST = 0; DMA_TCD1_DADDR = i2s_rx_buffer; DMA_TCD1_DOFF = 2; DMA_TCD1_CITER_ELINKNO = sizeof(i2s_rx_buffer) / 2; DMA_TCD1_DLASTSGA = -sizeof(i2s_rx_buffer); DMA_TCD1_BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2; DMA_TCD1_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; DMAMUX0_CHCFG1 = DMAMUX_DISABLE; DMAMUX0_CHCFG1 = DMAMUX_SOURCE_I2S0_RX | DMAMUX_ENABLE; update_responsibility = update_setup(); DMA_SERQ = 1; // TODO: is I2S_RCSR_BCE appropriate if sync'd to transmitter clock? //I2S0_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE | I2S_RCSR_FRDE | I2S_RCSR_FR; I2S0_RCSR |= I2S_RCSR_RE | I2S_RCSR_FRDE | I2S_RCSR_FR; NVIC_ENABLE_IRQ(IRQ_DMA_CH1); }
// Setup connection to other side // - Only supports a single slave and master // - If USB has been initiallized at this point, this side is the master // - If both sides assert master, flash error leds void Connect_setup( uint8_t master ) { // Indication that UARTs are not ready uarts_configured = 0; // Register Connect CLI dictionary CLI_registerDictionary( uartConnectCLIDict, uartConnectCLIDictName ); // Check if master Connect_master = master; if ( Connect_master ) Connect_id = 0; // 0x00 is always the master Id // UART0 setup // UART1 setup // Setup the the UART interface for keyboard data input SIM_SCGC4 |= SIM_SCGC4_UART0; // Disable clock gating SIM_SCGC4 |= SIM_SCGC4_UART1; // Disable clock gating // Pin Setup for UART0 / UART1 PORTA_PCR1 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(2); // RX Pin PORTA_PCR2 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(2); // TX Pin PORTE_PCR0 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); // RX Pin PORTE_PCR1 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin // Baud Rate setting UART0_BDH = (uint8_t)(Connect_baud >> 8); UART0_BDL = (uint8_t)Connect_baud; UART0_C4 = Connect_baudFine; UART1_BDH = (uint8_t)(Connect_baud >> 8); UART1_BDL = (uint8_t)Connect_baud; UART1_C4 = Connect_baudFine; // 8 bit, Even Parity, Idle Character bit after stop // NOTE: For 8 bit with Parity you must enable 9 bit transmission (pg. 1065) // You only need to use UART0_D for 8 bit reading/writing though // UART_C1_M UART_C1_PE UART_C1_PT UART_C1_ILT UART0_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT; UART1_C1 = UART_C1_M | UART_C1_PE | UART_C1_ILT; // Only using Tx Fifos UART0_PFIFO = UART_PFIFO_TXFE; UART1_PFIFO = UART_PFIFO_TXFE; // Setup DMA clocks SIM_SCGC6 |= SIM_SCGC6_DMAMUX; SIM_SCGC7 |= SIM_SCGC7_DMA; // Start with channels disabled first DMAMUX0_CHCFG0 = 0; DMAMUX0_CHCFG1 = 0; // Configure DMA channels //DMA_DSR_BCR0 |= DMA_DSR_BCR_DONE_MASK; // TODO What's this? DMA_TCD0_CSR = 0; DMA_TCD1_CSR = 0; // Default control register DMA_CR = 0; // DMA Priority DMA_DCHPRI0 = 0; // Ch 0, priority 0 DMA_DCHPRI1 = 1; // ch 1, priority 1 // Clear error interrupts DMA_EEI = 0; // Setup TCD DMA_TCD0_SADDR = (uint32_t*)&UART0_D; DMA_TCD1_SADDR = (uint32_t*)&UART1_D; DMA_TCD0_SOFF = 0; DMA_TCD1_SOFF = 0; // No modulo, 8-bit transfer size DMA_TCD0_ATTR = DMA_TCD_ATTR_SMOD(0) | DMA_TCD_ATTR_SSIZE(0) | DMA_TCD_ATTR_DMOD(0) | DMA_TCD_ATTR_DSIZE(0); DMA_TCD1_ATTR = DMA_TCD_ATTR_SMOD(0) | DMA_TCD_ATTR_SSIZE(0) | DMA_TCD_ATTR_DMOD(0) | DMA_TCD_ATTR_DSIZE(0); // One byte transferred at a time DMA_TCD0_NBYTES_MLNO = 1; DMA_TCD1_NBYTES_MLNO = 1; // Source address does not change DMA_TCD0_SLAST = 0; DMA_TCD1_SLAST = 0; // Destination buffer DMA_TCD0_DADDR = (uint32_t*)uart_rx_buf[0].buffer; DMA_TCD1_DADDR = (uint32_t*)uart_rx_buf[1].buffer; // Incoming byte, increment by 1 in the rx buffer DMA_TCD0_DOFF = 1; DMA_TCD1_DOFF = 1; // Single major loop, must be the same value DMA_TCD0_CITER_ELINKNO = UART_Buffer_Size; DMA_TCD1_CITER_ELINKNO = UART_Buffer_Size; DMA_TCD0_BITER_ELINKNO = UART_Buffer_Size; DMA_TCD1_BITER_ELINKNO = UART_Buffer_Size; // Reset buffer when full DMA_TCD0_DLASTSGA = -( UART_Buffer_Size ); DMA_TCD1_DLASTSGA = -( UART_Buffer_Size ); // Enable DMA channels DMA_ERQ |= DMA_ERQ_ERQ0 | DMA_ERQ_ERQ1; // Setup DMA channel routing DMAMUX0_CHCFG0 = DMAMUX_ENABLE | DMAMUX_SOURCE_UART0_RX; DMAMUX0_CHCFG1 = DMAMUX_ENABLE | DMAMUX_SOURCE_UART1_RX; // Enable DMA requests (requires Rx interrupts) UART0_C5 = UART_C5_RDMAS; UART1_C5 = UART_C5_RDMAS; // TX Enabled, RX Enabled, RX Interrupt Enabled UART0_C2 = UART_C2_TE | UART_C2_RE | UART_C2_RIE; UART1_C2 = UART_C2_TE | UART_C2_RE | UART_C2_RIE; // Add interrupts to the vector table NVIC_ENABLE_IRQ( IRQ_UART0_STATUS ); NVIC_ENABLE_IRQ( IRQ_UART1_STATUS ); // UARTs are now ready to go uarts_configured = 1; // Reset the state of the UART variables Connect_reset(); }
void AudioInputAnalogStereo::init(uint8_t pin0, uint8_t pin1) { uint32_t i, sum0=0, sum1=0; //pinMode(32, OUTPUT); //pinMode(33, OUTPUT); // Configure the ADC and run at least one software-triggered // conversion. This completes the self calibration stuff and // leaves the ADC in a state that's mostly ready to use analogReadRes(16); analogReference(INTERNAL); // range 0 to 1.2 volts #if F_BUS == 96000000 || F_BUS == 48000000 || F_BUS == 24000000 analogReadAveraging(8); ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(1); #else analogReadAveraging(4); ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(0); #endif // Actually, do many normal reads, to start with a nice DC level for (i=0; i < 1024; i++) { sum0 += analogRead(pin0); sum1 += analogReadADC1(pin1); } for (i = 0; i < 16; i++) { left_dc_average_hist[i] = sum0 >> 10; right_dc_average_hist[i] = sum1 >> 10; } // set the programmable delay block to trigger the ADC at 44.1 kHz //if (!(SIM_SCGC6 & SIM_SCGC6_PDB) //|| (PDB0_SC & PDB_CONFIG) != PDB_CONFIG //|| PDB0_MOD != PDB_PERIOD //|| PDB0_IDLY != 1 //|| PDB0_CH0C1 != 0x0101) { SIM_SCGC6 |= SIM_SCGC6_PDB; PDB0_IDLY = 1; PDB0_MOD = PDB_PERIOD; PDB0_SC = PDB_CONFIG | PDB_SC_LDOK; PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG; PDB0_CH0C1 = 0x0101; PDB0_CH1C1 = 0x0101; //} // enable the ADC for hardware trigger and DMA ADC0_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN; ADC1_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN; // set up a DMA channel to store the ADC data dma0.begin(true); dma1.begin(true); // ADC0_RA = 0x4003B010 // ADC1_RA = 0x400BB010 dma0.TCD->SADDR = &ADC0_RA; dma0.TCD->SOFF = 0; dma0.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); dma0.TCD->NBYTES_MLNO = 2; dma0.TCD->SLAST = 0; dma0.TCD->DADDR = left_buffer; dma0.TCD->DOFF = 2; dma0.TCD->CITER_ELINKNO = sizeof(left_buffer) / 2; dma0.TCD->DLASTSGA = -sizeof(left_buffer); dma0.TCD->BITER_ELINKNO = sizeof(left_buffer) / 2; dma0.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; dma1.TCD->SADDR = &ADC1_RA; dma1.TCD->SOFF = 0; dma1.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); dma1.TCD->NBYTES_MLNO = 2; dma1.TCD->SLAST = 0; dma1.TCD->DADDR = right_buffer; dma1.TCD->DOFF = 2; dma1.TCD->CITER_ELINKNO = sizeof(right_buffer) / 2; dma1.TCD->DLASTSGA = -sizeof(right_buffer); dma1.TCD->BITER_ELINKNO = sizeof(right_buffer) / 2; dma1.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; dma0.triggerAtHardwareEvent(DMAMUX_SOURCE_ADC0); //dma1.triggerAtHardwareEvent(DMAMUX_SOURCE_ADC1); dma1.triggerAtTransfersOf(dma0); dma1.triggerAtCompletionOf(dma0); update_responsibility = update_setup(); dma0.enable(); dma1.enable(); dma0.attachInterrupt(isr0); dma1.attachInterrupt(isr1); }
void OctoWS2811::begin(void) { uint32_t frequency; // set up the buffers memset(frameBuffer[0], 0, bufSize); memset(frameBuffer[1], 0, bufSize); // configure the 8 output pins GPIOD_PCOR = 0xFF; pinMode(2, OUTPUT); // strip #1 pinMode(14, OUTPUT); // strip #2 pinMode(7, OUTPUT); // strip #3 pinMode(8, OUTPUT); // strip #4 pinMode(6, OUTPUT); // strip #5 pinMode(20, OUTPUT); // strip #6 pinMode(21, OUTPUT); // strip #7 pinMode(5, OUTPUT); // strip #8 #ifdef TWOPORT #ifdef C8SYNC //don't use pin 15-16 loopback, use something else. You still pretty much need to use pin16 as it has FTM1_CH0 muxed on it. Instead of B0 you could also use A12 (see datasheet) GPIOC_PCOR = 0xFF; pinMode(28, OUTPUT); // C8(pin28) -> B0 for sync instead of C0-B0 to free up C0 for an extra LED strip. #else //reserve C0 for pwm (this is default setup of the Octo2811 buffer board, but you can't use C0 for strip output so you only get 15 usable channels) GPIOC_PCOR = 0xFE; #endif pinMode(22, OUTPUT); // PC1 strip #9 pinMode(23, OUTPUT); // PC2 strip #10 pinMode(9, OUTPUT); // PC3 strip #11 pinMode(10, OUTPUT); // PC4 strip #12 pinMode(13, OUTPUT); // PC5 strip #13 pinMode(11, OUTPUT); // PC6 strip #14 pinMode(12, OUTPUT); // PC7 strip #15 #endif #ifdef DEBUGSYNC pinMode(0, OUTPUT); // B16 sync for scope testing #endif // create the two waveforms for WS2811 low and high bits frequency = 800000; analogWriteResolution(8); analogWriteFrequency(3, frequency); analogWriteFrequency(4, frequency); analogWrite(3, WS2811_TIMING_T0H); analogWrite(4, WS2811_TIMING_T1H); #ifdef C8SYNCxxxxx // Optionally use A12 (pin 3) instead of B0 - triggers DMA(port B) on rising edge (configure for pin 3's waveform) #else // pin 16 (b0) is FTM1_CH0, triggers DMA(port B) on rising edge (configure mux to output pin 3's waveform) CORE_PIN16_CONFIG = PORT_PCR_IRQC(1)|PORT_PCR_MUX(3); //pin35 (B0) , mux to FTM1_CH0 IRQC0001 = DMA on rising edge pinMode(3, INPUT_PULLUP); // pin 3 (A12, configured by the AnalogWrite(3..) above is no longer needed for PWM so set as input or whatever you like #endif #ifdef C8SYNC // pin 28 (C8) triggers DMA(port C) on falling edge of low duty waveform // pin 28 and 25 must be connected by the user: 25 is output, 28 is input pinMode(28, INPUT); //c8 //PTC8 input, IRQC0010 = DMA on rising edge CORE_PIN28_CONFIG = PORT_PCR_IRQC(2)|PORT_PCR_MUX(1); #else // pin 15 (C0) triggers DMA(port C) on falling edge of low duty waveform // pin 15 and 16 must be connected by the user: 16 is output, 15 is input pinMode(15, INPUT); //c0 //pin43 = PTC0 input, IRQC0010 = DMA on rising edge CORE_PIN15_CONFIG = PORT_PCR_IRQC(2)|PORT_PCR_MUX(1); #endif // pin 4 triggers DMA(port A) on falling edge of high duty waveform //pin29 = (A13) mux to FTM1_CH1 IRQC0010=DMA on falling edge CORE_PIN4_CONFIG = PORT_PCR_IRQC(2)|PORT_PCR_MUX(3); // enable clocks to the DMA controller and DMAMUX SIM_SCGC7 |= SIM_SCGC7_DMA; SIM_SCGC6 |= SIM_SCGC6_DMAMUX; DMA_CR = 0; DMA_ERQ = 0; // DMA channel #1 sets WS2811 high at the beginning of each cycle #ifndef TWOPORT //original octo2811 8-channel DMA setup DMA_TCD1_SADDR = &ones; DMA_TCD1_SOFF = 0; DMA_TCD1_ATTR = DMA_TCD_ATTR_SSIZE(0) | DMA_TCD_ATTR_DSIZE(0); DMA_TCD1_NBYTES_MLNO = 1; DMA_TCD1_SLAST = 0; DMA_TCD1_DADDR = &GPIOD_PSOR; DMA_TCD1_DOFF = 0; DMA_TCD1_CITER_ELINKNO = bufSize; DMA_TCD1_DLASTSGA = 0; DMA_TCD1_CSR = DMA_TCD_CSR_DREQ; DMA_TCD1_BITER_ELINKNO = bufSize; // DMA channel #2 writes the pixel data at 20% of the cycle DMA_TCD2_SADDR = frameBuffer[1]; DMA_TCD2_SOFF = 1; DMA_TCD2_ATTR = DMA_TCD_ATTR_SSIZE(0) | DMA_TCD_ATTR_DSIZE(0); DMA_TCD2_NBYTES_MLNO = 1; DMA_TCD2_SLAST = -bufSize; DMA_TCD2_DADDR = &GPIOD_PDOR; DMA_TCD2_DOFF = 0; DMA_TCD2_CITER_ELINKNO = bufSize; DMA_TCD2_DLASTSGA = 0; DMA_TCD2_CSR = DMA_TCD_CSR_DREQ; DMA_TCD2_BITER_ELINKNO = bufSize; // DMA channel #3 clear all the pins low at 48% of the cycle DMA_TCD3_SADDR = &ones; DMA_TCD3_SOFF = 0; DMA_TCD3_ATTR = DMA_TCD_ATTR_SSIZE(0) | DMA_TCD_ATTR_DSIZE(0); DMA_TCD3_NBYTES_MLNO = 1; DMA_TCD3_SLAST = 0; DMA_TCD3_DADDR = &GPIOD_PCOR; DMA_TCD3_DOFF = 0; DMA_TCD3_CITER_ELINKNO = bufSize; DMA_TCD3_DLASTSGA = 0; DMA_TCD3_CSR = DMA_TCD_CSR_DREQ | DMA_TCD_CSR_INTMAJOR; DMA_TCD3_BITER_ELINKNO = bufSize; #else //DrTune's 16-channel DMA setup //0x40 byte address gap between sequential ports (a,b,c,d) #define PORT_SPACING 0x40 /*between ports C and D */ #define MLOFFYES (1+1) // 2 byte tranfers per minor loop (port C then D) #define FREEZE_DEST_ADDR_BITS 7 /*force dest address to alternate between ports C+D */ DMA_CR = (1<<7); //EMLM minor loop enabled; //write port C and D in a minor loop DMA_TCD1_SADDR = &ones; DMA_TCD1_SOFF = 0; DMA_TCD1_ATTR = DMA_TCD_ATTR_SSIZE(0) | DMA_TCD_ATTR_DSIZE(0) | (FREEZE_DEST_ADDR_BITS<<3); DMA_TCD1_NBYTES_MLOFFYES = MLOFFYES; DMA_TCD1_SLAST = 0; DMA_TCD1_DADDR = &GPIOC_PSOR; DMA_TCD1_DOFF = PORT_SPACING; DMA_TCD1_CITER_ELINKNO = bufSize/2; DMA_TCD1_DLASTSGA = 0; DMA_TCD1_CSR = DMA_TCD_CSR_DREQ; DMA_TCD1_BITER_ELINKNO = bufSize/2; // DMA channel #2 writes the pixel data at 20% of the cycle DMA_TCD2_SADDR = frameBuffer[1]; DMA_TCD2_SOFF = 1; DMA_TCD2_ATTR = DMA_TCD_ATTR_SSIZE(0) | DMA_TCD_ATTR_DSIZE(0) | (FREEZE_DEST_ADDR_BITS<<3);; DMA_TCD2_NBYTES_MLOFFYES = MLOFFYES; DMA_TCD2_SLAST = -bufSize; DMA_TCD2_DADDR = &GPIOC_PDOR; DMA_TCD2_DOFF = PORT_SPACING; DMA_TCD2_CITER_ELINKNO = bufSize/2; DMA_TCD2_DLASTSGA = 0; DMA_TCD2_CSR = DMA_TCD_CSR_DREQ; DMA_TCD2_BITER_ELINKNO = bufSize/2; // DMA channel #3 clear all the pins low at 48% of the cycle DMA_TCD3_SADDR = &ones; DMA_TCD3_SOFF = 0; DMA_TCD3_ATTR = DMA_TCD_ATTR_SSIZE(0) | DMA_TCD_ATTR_DSIZE(0) | (FREEZE_DEST_ADDR_BITS<<3);; DMA_TCD3_NBYTES_MLOFFYES = MLOFFYES; DMA_TCD3_SLAST = 0; DMA_TCD3_DADDR = &GPIOC_PCOR; DMA_TCD3_DOFF = PORT_SPACING; DMA_TCD3_CITER_ELINKNO = bufSize/2; DMA_TCD3_DLASTSGA = 0; DMA_TCD3_CSR = DMA_TCD_CSR_DREQ | DMA_TCD_CSR_INTMAJOR; DMA_TCD3_BITER_ELINKNO = bufSize/2; #endif #ifdef __MK20DX256__ MCM_CR = MCM_CR_SRAMLAP(1) | MCM_CR_SRAMUAP(0); AXBS_PRS0 = 0x1032; #endif // route the edge detect interrupts to trigger the 3 channels DMAMUX0_CHCFG1 = 0; DMAMUX0_CHCFG1 = DMAMUX_SOURCE_PORTB | DMAMUX_ENABLE; DMAMUX0_CHCFG2 = 0; DMAMUX0_CHCFG2 = DMAMUX_SOURCE_PORTC | DMAMUX_ENABLE; DMAMUX0_CHCFG3 = 0; DMAMUX0_CHCFG3 = DMAMUX_SOURCE_PORTA | DMAMUX_ENABLE; // enable a done interrupts when channel #3 completes NVIC_ENABLE_IRQ(IRQ_DMA_CH3); //pinMode(1, OUTPUT); // testing: oscilloscope trigger }
void AudioInputAnalog::begin(unsigned int pin) { uint32_t i, sum=0; // pin must be 0 to 13 (for A0 to A13) // or 14 to 23 for digital pin numbers A0-A9 // or 34 to 37 corresponding to A10-A13 if (pin > 23 && !(pin >= 34 && pin <= 37)) return; //pinMode(2, OUTPUT); //pinMode(3, OUTPUT); //digitalWriteFast(3, HIGH); //delayMicroseconds(500); //digitalWriteFast(3, LOW); // Configure the ADC and run at least one software-triggered // conversion. This completes the self calibration stuff and // leaves the ADC in a state that's mostly ready to use analogReadRes(16); analogReference(INTERNAL); // range 0 to 1.2 volts //analogReference(DEFAULT); // range 0 to 3.3 volts analogReadAveraging(8); // Actually, do many normal reads, to start with a nice DC level for (i=0; i < 1024; i++) { sum += analogRead(pin); } dc_average = sum >> 10; // testing only, enable adc interrupt //ADC0_SC1A |= ADC_SC1_AIEN; //while ((ADC0_SC1A & ADC_SC1_COCO) == 0) ; // wait //NVIC_ENABLE_IRQ(IRQ_ADC0); // set the programmable delay block to trigger the ADC at 44.1 kHz SIM_SCGC6 |= SIM_SCGC6_PDB; PDB0_MOD = PDB_PERIOD; PDB0_SC = PDB_CONFIG | PDB_SC_LDOK; PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG; PDB0_CH0C1 = 0x0101; // enable the ADC for hardware trigger and DMA ADC0_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN; // set up a DMA channel to store the ADC data SIM_SCGC7 |= SIM_SCGC7_DMA; SIM_SCGC6 |= SIM_SCGC6_DMAMUX; DMA_CR = 0; DMA_TCD2_SADDR = &ADC0_RA; DMA_TCD2_SOFF = 0; DMA_TCD2_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); DMA_TCD2_NBYTES_MLNO = 2; DMA_TCD2_SLAST = 0; DMA_TCD2_DADDR = analog_rx_buffer; DMA_TCD2_DOFF = 2; DMA_TCD2_CITER_ELINKNO = sizeof(analog_rx_buffer) / 2; DMA_TCD2_DLASTSGA = -sizeof(analog_rx_buffer); DMA_TCD2_BITER_ELINKNO = sizeof(analog_rx_buffer) / 2; DMA_TCD2_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; DMAMUX0_CHCFG2 = DMAMUX_DISABLE; DMAMUX0_CHCFG2 = DMAMUX_SOURCE_ADC0 | DMAMUX_ENABLE; update_responsibility = update_setup(); DMA_SERQ = 2; NVIC_ENABLE_IRQ(IRQ_DMA_CH2); }
void AudioInputAnalogStereo::init(uint8_t pin0, uint8_t pin1) { uint32_t tmp; //pinMode(32, OUTPUT); //pinMode(33, OUTPUT); // Configure the ADC and run at least one software-triggered // conversion. This completes the self calibration stuff and // leaves the ADC in a state that's mostly ready to use analogReadRes(16); analogReference(INTERNAL); // range 0 to 1.2 volts #if F_BUS == 96000000 || F_BUS == 48000000 || F_BUS == 24000000 analogReadAveraging(8); ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(1); #else analogReadAveraging(4); ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(0); #endif // Note for review: // Probably not useful to spin cycles here stabilizing // since DC blocking is similar to te external analog filters tmp = (uint16_t) analogRead(pin0); tmp = ( ((int32_t) tmp) << 14); hpf_x1[0] = tmp; // With constant DC level x1 would be x0 hpf_y1[0] = 0; // Output will settle here when stable tmp = (uint16_t) analogReadADC1(pin1); tmp = ( ((int32_t) tmp) << 14); hpf_x1[1] = tmp; // With constant DC level x1 would be x0 hpf_y1[1] = 0; // Output will settle here when stable // set the programmable delay block to trigger the ADC at 44.1 kHz //if (!(SIM_SCGC6 & SIM_SCGC6_PDB) //|| (PDB0_SC & PDB_CONFIG) != PDB_CONFIG //|| PDB0_MOD != PDB_PERIOD //|| PDB0_IDLY != 1 //|| PDB0_CH0C1 != 0x0101) { SIM_SCGC6 |= SIM_SCGC6_PDB; PDB0_IDLY = 1; PDB0_MOD = PDB_PERIOD; PDB0_SC = PDB_CONFIG | PDB_SC_LDOK; PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG; PDB0_CH0C1 = 0x0101; PDB0_CH1C1 = 0x0101; //} // enable the ADC for hardware trigger and DMA ADC0_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN; ADC1_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN; // set up a DMA channel to store the ADC data dma0.begin(true); dma1.begin(true); // ADC0_RA = 0x4003B010 // ADC1_RA = 0x400BB010 dma0.TCD->SADDR = &ADC0_RA; dma0.TCD->SOFF = 0; dma0.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); dma0.TCD->NBYTES_MLNO = 2; dma0.TCD->SLAST = 0; dma0.TCD->DADDR = left_buffer; dma0.TCD->DOFF = 2; dma0.TCD->CITER_ELINKNO = sizeof(left_buffer) / 2; dma0.TCD->DLASTSGA = -sizeof(left_buffer); dma0.TCD->BITER_ELINKNO = sizeof(left_buffer) / 2; dma0.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; dma1.TCD->SADDR = &ADC1_RA; dma1.TCD->SOFF = 0; dma1.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); dma1.TCD->NBYTES_MLNO = 2; dma1.TCD->SLAST = 0; dma1.TCD->DADDR = right_buffer; dma1.TCD->DOFF = 2; dma1.TCD->CITER_ELINKNO = sizeof(right_buffer) / 2; dma1.TCD->DLASTSGA = -sizeof(right_buffer); dma1.TCD->BITER_ELINKNO = sizeof(right_buffer) / 2; dma1.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; dma0.triggerAtHardwareEvent(DMAMUX_SOURCE_ADC0); //dma1.triggerAtHardwareEvent(DMAMUX_SOURCE_ADC1); dma1.triggerAtTransfersOf(dma0); dma1.triggerAtCompletionOf(dma0); update_responsibility = update_setup(); dma0.enable(); dma1.enable(); dma0.attachInterrupt(isr0); dma1.attachInterrupt(isr1); }