unsigned char Wiz610_put_buf(unsigned char *buf, unsigned long count) { unsigned long i; unsigned long ulMode; ulMode=ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT); if (ulMode!=UDMA_MODE_STOP) return false; i=0; while(i<count) { g_ucTxBuf[i]=*buf++; i++; } ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC,(void *) g_ucTxBuf, (void *)(UART1_BASE + UART_O_DR), count); ROM_UARTEnable(WIZ610_UART_BASE); ROM_uDMAChannelEnable(UDMA_CHANNEL_UART1TX); return true; }
//***************************************************************************** // // The interrupt handler for uDMA interrupts from the memory channel. This // interrupt will increment a counter, and then restart another memory // transfer. // //***************************************************************************** void uDMAIntHandler(void) { uint32_t ui32Mode; // // Check for the primary control structure to indicate complete. // ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SW); if(ui32Mode == UDMA_MODE_STOP) { // // Increment the count of completed transfers. // g_ui32MemXferCount++; // // Configure it for another transfer. // ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SW, UDMA_MODE_AUTO, g_ui32SrcBuf, g_ui32DstBuf, MEM_BUFFER_SIZE); // // Initiate another transfer. // ROM_uDMAChannelEnable(UDMA_CHANNEL_SW); ROM_uDMAChannelRequest(UDMA_CHANNEL_SW); } // // If the channel is not stopped, then something is wrong. // else { g_ui32BadISR++; } }
//***************************************************************************** // //! Handles the I2S sound interrupt. //! //! This function services the I2S interrupt and ensures that DMA buffers are //! correctly handled to ensure smooth flow of audio data to the DAC. //! //! \return None. // //***************************************************************************** void SoundIntHandler(void) { unsigned long ulStatus; unsigned long *pulTemp; // // Get the interrupt status and clear any pending interrupts. // ulStatus = I2SIntStatus(I2S0_BASE, 1); // // Clear out any interrupts. // I2SIntClear(I2S0_BASE, ulStatus); // // Handle the TX channel interrupt // if(HWREGBITW(&g_ulDMAFlags, FLAG_TX_PENDING)) { // // If the TX DMA is done, then call the callback if present. // if(ROM_uDMAChannelModeGet(UDMA_CHANNEL_I2S0TX | UDMA_PRI_SELECT) == UDMA_MODE_STOP) { // // Save a temp pointer so that the current pointer can be set to // zero before calling the callback. // pulTemp = (unsigned long *)g_sBuffers[0].pulData; // // If at the mid point then refill the first half of the buffer. // if((g_sBuffers[0].pfnBufferCallback) && (g_sBuffers[0].pulData != 0)) { g_sBuffers[0].pulData = 0; g_sBuffers[0].pfnBufferCallback(pulTemp, BUFFER_EVENT_FREE); } } // // If the TX DMA is done, then call the callback if present. // if(ROM_uDMAChannelModeGet(UDMA_CHANNEL_I2S0TX | UDMA_ALT_SELECT) == UDMA_MODE_STOP) { // // Save a temp pointer so that the current pointer can be set to // zero before calling the callback. // pulTemp = (unsigned long *)g_sBuffers[1].pulData; // // If at the mid point then refill the first half of the buffer. // if((g_sBuffers[1].pfnBufferCallback) && (g_sBuffers[1].pulData != 0)) { g_sBuffers[1].pulData = 0; g_sBuffers[1].pfnBufferCallback(pulTemp, BUFFER_EVENT_FREE); } } // // If no more buffers are pending then clear the flag. // if((g_sBuffers[0].pulData == 0) && (g_sBuffers[1].pulData == 0)) { HWREGBITW(&g_ulDMAFlags, FLAG_TX_PENDING) = 0; } } }
//***************************************************************************** // // The interrupt handler for UART0. This interrupt will occur when a DMA // transfer is complete using the UART0 uDMA channel. It will also be // triggered if the peripheral signals an error. This interrupt handler will // switch between receive ping-pong buffers A and B. It will also restart a TX // uDMA transfer if the prior transfer is complete. This will keep the UART // running continuously (looping TX data back to RX). // //***************************************************************************** void UART0IntHandler(void) { unsigned long ulStatus; unsigned long ulMode; // // Read the interrupt status of the UART. // ulStatus = ROM_UARTIntStatus(UART0_BASE, 1); // // Clear any pending status, even though there should be none since no UART // interrupts were enabled. If UART error interrupts were enabled, then // those interrupts could occur here and should be handled. Since uDMA is // used for both the RX and TX, then neither of those interrupts should be // enabled. // ROM_UARTIntClear(UART0_BASE, ulStatus); // // Check the DMA control table to see if the ping-pong "A" transfer is // complete. The "A" transfer uses receive buffer "A", and the primary // control structure. // ulMode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT); // // If the primary control structure indicates stop, that means the "A" // receive buffer is done. The uDMA controller should still be receiving // data into the "B" buffer. // if(ulMode == UDMA_MODE_STOP) { // // Increment a counter to indicate data was received into buffer A. In // a real application this would be used to signal the main thread that // data was received so the main thread can process the data. // g_ulRxBufACount++; // // Set up the next transfer for the "A" buffer, using the primary // control structure. When the ongoing receive into the "B" buffer is // done, the uDMA controller will switch back to this one. This // example re-uses buffer A, but a more sophisticated application could // use a rotating set of buffers to increase the amount of time that // the main thread has to process the data in the buffer before it is // reused. // ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(UART0_BASE + UART_O_DR), g_ucRxBufA, sizeof(g_ucRxBufA)); } // // Check the DMA control table to see if the ping-pong "B" transfer is // complete. The "B" transfer uses receive buffer "B", and the alternate // control structure. // ulMode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT); // // If the alternate control structure indicates stop, that means the "B" // receive buffer is done. The uDMA controller should still be receiving // data into the "A" buffer. // if(ulMode == UDMA_MODE_STOP) { // // Increment a counter to indicate data was received into buffer A. In // a real application this would be used to signal the main thread that // data was received so the main thread can process the data. // g_ulRxBufBCount++; // // Set up the next transfer for the "B" buffer, using the alternate // control structure. When the ongoing receive into the "A" buffer is // done, the uDMA controller will switch back to this one. This // example re-uses buffer B, but a more sophisticated application could // use a rotating set of buffers to increase the amount of time that // the main thread has to process the data in the buffer before it is // reused. // ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(UART0_BASE + UART_O_DR), g_ucRxBufB, sizeof(g_ucRxBufB)); } // // If the UART0 DMA TX channel is disabled, that means the TX DMA transfer // is done. // if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_UART0TX)) { // // Start another DMA transfer to UART0 TX. // ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, g_ucTxBuf, (void *)(UART0_BASE + UART_O_DR), sizeof(g_ucTxBuf)); // // The uDMA TX channel must be re-enabled. // ROM_uDMAChannelEnable(UDMA_CHANNEL_UART0TX); } }