From 348b1390f02cbb66e68c140d1d1d3f887355a306 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Tue, 12 Aug 2014 19:34:55 +0200 Subject: New I2S and DMA files (dummy). --- firmware/drivers/dma.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++++ firmware/drivers/dma.h | 46 ++++++++++++ firmware/drivers/i2s.c | 159 +++++++++++++++++++++++++++++++++++++++++ firmware/drivers/i2s.h | 41 +++++++++++ 4 files changed, 435 insertions(+) create mode 100644 firmware/drivers/dma.c create mode 100644 firmware/drivers/dma.h create mode 100644 firmware/drivers/i2s.c create mode 100644 firmware/drivers/i2s.h diff --git a/firmware/drivers/dma.c b/firmware/drivers/dma.c new file mode 100644 index 0000000..fb7324a --- /dev/null +++ b/firmware/drivers/dma.c @@ -0,0 +1,189 @@ +/**************************************************************************** + * $Id:: dma.c 5797 2010-12-03 00:27:00Z usb00423 $ + * Project: NXP LPC17xx DMA for I2S example + * + * Description: + * This file contains DMA code example which include DMA initialization, + * DMA interrupt handler, and APIs for DMA access. + * + **************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. +****************************************************************************/ +#include +//#include "type.h" +#include "i2s.h" +#include "dma.h" + +#if I2S_DMA_ENABLED +volatile uint32_t DMATCCount = 0; +volatile uint32_t DMAErrCount = 0; +volatile uint32_t I2SDMA0Done = 0; +volatile uint32_t I2SDMA1Done = 0; + +#define FALSE 0 +#define TRUE 1 + +/****************************************************************************** +** Function name: DMA_IRQHandler +** +** Descriptions: DMA interrupt handler +** +** parameters: None +** Returned value: None +** +******************************************************************************/ +void DMA_IRQHandler(void) +{ + uint32_t regVal; + + regVal = LPC_GPDMA->DMACIntTCStat; + if ( regVal ) + { + DMATCCount++; + LPC_GPDMA->DMACIntTCClear |= regVal; + if ( regVal & 0x01 ) + { + I2SDMA0Done = 1; + } + else if ( regVal & 0x02 ) + { + I2SDMA1Done = 1; + } + } + + regVal = LPC_GPDMA->DMACIntErrStat; + if ( regVal ) + { + DMAErrCount++; + LPC_GPDMA->DMACIntErrClr |= regVal; + } + +} + +/****************************************************************************** +** Function name: DMA_Init +** +** Descriptions: clock to GPDMA in PCONP, GPDMA init before channel init +** +** parameters: None +** Returned value: None +** +******************************************************************************/ +void DMA_Init( void ) +{ + /* Enable CLOCK into GPDMA controller */ + LPC_SC->PCONP |= (1 << 29); + + LPC_GPDMA->DMACIntTCClear = 0x03; + LPC_GPDMA->DMACIntErrClr = 0x03; + + LPC_GPDMA->DMACConfig = 0x01; /* Enable DMA channels, little endian */ + while ( !(LPC_GPDMA->DMACConfig & 0x01) ); + + return; +} + +/****************************************************************************** +** Function name: DMAChannel_Init +** +** Descriptions: +** +** parameters: +** Returned value: +** +******************************************************************************/ +uint32_t DMAChannel_Init( uint32_t ChannelNum, uint32_t DMAMode ) +{ + if ( ChannelNum == 0 ) + { + I2SDMA0Done = 0; + LPC_GPDMA->DMACIntTCClear = 0x01; + if ( DMAMode == M2P ) + { + /* Ch0 set for M2P transfer from mempry to I2S TX FIFO. */ + LPC_GPDMACH0->DMACCSrcAddr = DMA_SRC; + LPC_GPDMACH0->DMACCDestAddr = DMA_I2S_TX_FIFO; + /* The burst size is set to 1. Terminal Count Int enable */ + LPC_GPDMACH0->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x00 << 12) | (0x00 << 15) + | (1 << 26) | 0x80000000; + } + else if ( DMAMode == P2M ) + { + /* Ch0 set for P2M transfer from I2S RX FIFO to memory. */ + LPC_GPDMACH0->DMACCSrcAddr = DMA_I2S_RX_FIFO; + LPC_GPDMACH0->DMACCDestAddr = DMA_DST; + /* The burst size is set to 1. Terminal Count Int enable. */ + LPC_GPDMACH0->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x00 << 12) | (0x00 << 15) + | (1 << 27) | 0x80000000; + } + else if ( DMAMode == P2P ) + { + /* Ch0 set for P2P transfer from I2S DAO to I2S DAI. */ + LPC_GPDMACH0->DMACCSrcAddr = DMA_I2S_TX_FIFO; + LPC_GPDMACH0->DMACCDestAddr = DMA_I2S_RX_FIFO; + /* The burst size is set to 32. */ + LPC_GPDMACH0->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x04 << 12) | (0x04 << 15) + | 0x80000000; + } + else + { + return ( FALSE ); + } + } + else if ( ChannelNum == 1 ) + { + I2SDMA1Done = 0; + LPC_GPDMA->DMACIntTCClear = 0x02; + if ( DMAMode == M2P ) + { + /* Ch1 set for M2P transfer from mempry to I2S TX FIFO. */ + LPC_GPDMACH1->DMACCSrcAddr = DMA_SRC; + LPC_GPDMACH1->DMACCDestAddr = DMA_I2S_TX_FIFO; + /* The burst size is set to 1. Terminal Count Int enable. */ + LPC_GPDMACH1->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x00 << 12) | (0x00 << 15) + | (1 << 26) | 0x80000000; + } + else if ( DMAMode == P2M ) + { + /* Ch1 set for P2M transfer from I2S RX FIFO to memory. */ + LPC_GPDMACH1->DMACCSrcAddr = DMA_I2S_RX_FIFO; + LPC_GPDMACH1->DMACCDestAddr = DMA_DST; + /* The burst size is set to 1. Terminal Count Int enable. */ + LPC_GPDMACH1->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x00 << 12) | (0x00 << 15) + | (1 << 27) | 0x80000000; + } + else if ( DMAMode == P2P ) + { + /* Ch1 set for P2P transfer from I2S DAO to I2S DAI. */ + LPC_GPDMACH1->DMACCSrcAddr = DMA_I2S_TX_FIFO; + LPC_GPDMACH1->DMACCDestAddr = DMA_I2S_RX_FIFO; + /* The burst size is set to 32. */ + LPC_GPDMACH1->DMACCControl = (DMA_SIZE & 0x0FFF) | (0x04 << 12) | (0x04 << 15) + | 0x80000000; + } + else + { + return ( FALSE ); + } + } + else + { + return ( FALSE ); + } + return( TRUE ); +} + +#endif /* end if DMA_ENABLED */ + +/****************************************************************************** +** End Of File +******************************************************************************/ diff --git a/firmware/drivers/dma.h b/firmware/drivers/dma.h new file mode 100644 index 0000000..fe75fcd --- /dev/null +++ b/firmware/drivers/dma.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * $Id:: dma.h 5797 2010-12-03 00:27:00Z usb00423 $ + * Project: NXP LPC17xx DMA example + * + * Description: + * This file contains DMA code header definition. + * + **************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. +****************************************************************************/ +#ifndef __I2S_DMA_H +#define __I2S_DMA_H + +#define DMA_I2S_REQ0 5 +#define DMA_I2S_REQ1 6 + +#define DMA_SRC 0x2007C000 +#define DMA_DST 0x2007D000 +#define DMA_I2S_TX_FIFO (LPC_I2S_BASE + 0x08) +#define DMA_I2S_RX_FIFO (LPC_I2S_BASE + 0x0C) + +#define DMA_SIZE 0x200 + +/* DMA mode */ +#define M2M 0x00 +#define M2P 0x01 +#define P2M 0x02 +#define P2P 0x03 + +extern void DMA_IRQHandler( void ); +extern void DMA_Init( void ); +extern uint32_t DMAChannel_Init( uint32_t ChannelNum, uint32_t DMAMode ); + +#endif /* end __I2S_DMA_H */ +/**************************************************************************** +** End Of File +****************************************************************************/ diff --git a/firmware/drivers/i2s.c b/firmware/drivers/i2s.c new file mode 100644 index 0000000..0085e1d --- /dev/null +++ b/firmware/drivers/i2s.c @@ -0,0 +1,159 @@ +/**************************************************************************** + * $Id:: i2s.c 5797 2010-12-03 00:27:00Z usb00423 $ + * Project: NXP LPC17xx I2S example + * + * Description: + * This file contains I2S code example which include I2S initialization, + * I2C interrupt handler, and APIs for I2S access. + * + **************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. +****************************************************************************/ +#include +//#include "type.h" +#include "i2s.h" +#include "dma.h" + +/* treat I2S TX and RX as a constant address, make the code and buffer +easier for both DMA and non-DMA test */ +volatile uint8_t *I2STXBuffer = (uint8_t *)(DMA_SRC); +volatile uint8_t *I2SRXBuffer = (uint8_t *)(DMA_DST); +volatile uint32_t I2SReadLength = 0; +volatile uint32_t I2SWriteLength = 0; +volatile uint32_t I2SRXDone = 0, I2STXDone = 0; + +/***************************************************************************** +** Function name: I2S_IRQHandler +** +** Descriptions: I2S interrupt handler, only RX interrupt is enabled +** for simplicity. +** +** parameters: None +** Returned value: None +** +*****************************************************************************/ +void I2S_IRQHandler (void) +{ + uint32_t RxCount = 0; + + if ( LPC_I2S->I2SSTATE & 0x01 ) + { + RxCount = (LPC_I2S->I2SSTATE >> 8) & 0xFF; + if ( (RxCount != RXFIFO_EMPTY) && !I2SRXDone ) + { + while ( RxCount > 0 ) + { + if ( I2SReadLength == BUFSIZE ) + { + LPC_I2S->I2SDAI |= ((0x01 << 3) | (0x01 << 4)); + LPC_I2S->I2SIRQ &= ~(0x01 << 0); /* Disable RX */ + I2SRXDone = 1; + break; + } + else + { + I2SRXBuffer[I2SReadLength++] = LPC_I2S->I2SRXFIFO; + } + RxCount--; + } + } + } + return; +} + +/***************************************************************************** +** Function name: I2SStart +** +** Descriptions: Start I2S DAI and DAO +** +** parameters: None +** Returned value: None +** +*****************************************************************************/ +void I2SStart( void ) +{ + uint32_t DAIValue, DAOValue; + + /* Audio output is the master, audio input is the slave, */ + /* 16 bit data, stereo, reset, master mode, not mute. */ + DAOValue = LPC_I2S->I2SDAO; + DAIValue = LPC_I2S->I2SDAI; + LPC_I2S->I2SDAO = DAOValue & (~((0x01 << 4)|(0x01 <<3))); + /* 16 bit data, stereo, reset, slave mode, not mute. */ + LPC_I2S->I2SDAI = DAIValue & (~((0x01 << 4)|(0x01 <<3))); + return; +} + +/***************************************************************************** +** Function name: I2SStop +** +** Descriptions: Stop I2S DAI and DAO +** +** parameters: None +** Returned value: None +** +*****************************************************************************/ +void I2SStop( void ) +{ + uint32_t DAIValue, DAOValue; + + /* Stop the I2S to start. Audio output is master, audio input is the slave. */ + /* 16 bit data, set STOP and RESET bits to reset the channels */ + DAOValue = LPC_I2S->I2SDAO; + /* Switch to master mode, TX channel, no mute */ + DAOValue &= ~((0x01 << 5)|(0x01 << 15)); + DAIValue = LPC_I2S->I2SDAI; + DAIValue &= ~(0x01 << 15); + LPC_I2S->I2SDAO = (0x01 << 4) | (0x01 << 3) | DAOValue; /* Master */ + LPC_I2S->I2SDAI = (0x01 << 4) | (0x01 << 3) | DAIValue; /* Slave */ + return; +} + +/***************************************************************************** +** Function name: I2SInit +** +** Descriptions: Initialize I2S controller +** +** parameters: None +** Returned value: true or false, return false if the I2S +** interrupt handler was not installed correctly +** +*****************************************************************************/ +void I2SInit( void ) +{ + + /*enable I2S in the PCONP register. I2S is disabled on reset*/ + LPC_SC->PCONP |= (1 << 27); + + /*connect the I2S sigals to port pins(P0.4-P0.9)*/ + LPC_PINCON->PINSEL0 &= ~0x000FFF00; + LPC_PINCON->PINSEL0 |= 0x00055500; + + /* Please note, in order to generate accurate TX/RX clock rate for I2S, + PCLK and CCLK needs to be carefully reconsidered. For this test + program, the TX is looped back to RX without external I2S device, + clock rate is not critical in this matter. */ + LPC_I2S->I2STXRATE = //0x241; + (100 << 0) | // Y + (49 << 8) // X + ; + + // LPC_I2S->I2SRXRATE = 0x241; + + I2SStop(); + return; +} + +/****************************************************************************** +** End Of File +******************************************************************************/ + diff --git a/firmware/drivers/i2s.h b/firmware/drivers/i2s.h new file mode 100644 index 0000000..dbbb6f2 --- /dev/null +++ b/firmware/drivers/i2s.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * $Id:: i2s.h 5797 2010-12-03 00:27:00Z usb00423 $ + * Project: NXP LPC17xx I2S example + * + * Description: + * This file contains I2S code header definition. + * + **************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. +****************************************************************************/ +#ifndef __I2S_H +#define __I2S_H + +//#include "../src/sample.h" + +#define I2S_DMA_ENABLED 1 + +#define BUFSIZE 0x200 +//(1097 * sizeof(short) * 2)/*stereo*/ +//((int)(sizeof(samples) * 2/*stereo*/)) +#define RXFIFO_EMPTY 0 +#define TXFIFO_FULL 8 + +extern void I2S_IRQHandler( void ); +extern void I2SStart( void ); +extern void I2SStop( void ); +extern void I2SInit( void ); + +#endif /* end __I2S_H */ +/**************************************************************************** +** End Of File +*****************************************************************************/ -- cgit v1.2.3