This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123GH6PM + aic20k codec

Could anybody give me an example of configuring microcontroller to use with aic20k codec (dma in scatter-gather mode, 2 channels)?

  • There are some examples

    #define SLAVE_ADDRESS 	0x40	// slave address for I2C bus
    
    uint8_t cof_regs[14];	// array just for reading of cofidec's registers
    
    // item for the one register of cofidec
    typedef struct
    {
    	uint32_t cof;	// channel
    	uint32_t reg;	// number of register
    	uint32_t val;	// value
    } T_COF_CONF;
    
    
    // configuration: 
    T_COF_CONF conf[] = 
    {
    	{0x40, 3, 0x01},
    	{0x40, 5, 0x0E},
    	{0x40, 6, 0x04},
    
    	{0x41, 1, 0x49},
    	{0x41, 2, 0x20},
    	{0x41, 3, 0x01},
    	{0x41, 3, 0x47},
    	{0x41, 3, 0x80},
    	{0x41, 3, 0xC0},
    	{0x41, 4, 0x99},
    	{0x41, 4, 0x29},
    	{0x41, 5, 0x0E},
    	{0x41, 5, 0x40},
    	{0x41, 5, 0xBF},
    	{0x41, 5, 0xC0},
    	{0x41, 6, 0x04},
    	{0x41, 6, 0x82}
    };
    
    // cofidec's reset subroutine
    void cof_reset(bool state)
    {
    	if(state)
    		GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5, GPIO_PIN_5);
    	else
    		GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5, 0);
    }
    
    // ----(beg)----------------------------- I2C section -----------------------------------
    // just for completion transaction on errors
    void i2c_errors_process(uint32_t error)
    {
    	I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP);
    	while(I2CMasterBusy(I2C1_MASTER_BASE));
    }
    
    // initial function
    void i2c_init()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
        // Configure the pin muxing for I2C0 functions on port A6 and A7.
        // This step is not necessary if your part does not support pin muxing.
        GPIOPinConfigure(GPIO_PA6_I2C1SCL);
        GPIOPinConfigure(GPIO_PA7_I2C1SDA);
    
        // Select the I2C function for these pins.  This function will also
        // configure the GPIO pins pins for I2C operation, setting them to
        // open-drain operation with weak pull-ups
        GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
        GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
    
        // Enable and initialize the I2C0 master module.  Use the system clock for
        // the I2C0 module.  The last parameter sets the I2C data transfer rate.
        // If false the data rate is set to 100kbps and if true the data rate will
        // be set to 400kbps.
        I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false);
    
        // Enable the I2C0 master module 
    	I2CMasterEnable(I2C1_MASTER_BASE);
    
        // Tell the master module what address it will place on the bus when
        // communicating with the slave
        I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS, false);
    }
    
    // write full set of configuration words into cofidec
    void i2c_write_reg_device(uint8_t device, uint8_t reg, uint8_t data)
    {
    	I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, device, false);	// set WRITE bit!
    	I2CMasterDataPut(I2C1_MASTER_BASE, reg);
    	I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
    	while(I2CMasterBusy(I2C1_MASTER_BASE));
    	if(I2CMasterErr(I2C1_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    	{
    		i2c_errors_process(1);
    	}
    	I2CMasterDataPut(I2C1_MASTER_BASE, data);
    	I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
    	while(I2CMasterBusy(I2C1_MASTER_BASE));
    	if(I2CMasterErr(I2C1_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    	{
    		i2c_errors_process(1);
    	}
    }
    
    // just for reading registers
    int i2c_read_reg(uint8_t reg, uint8_t *data)
    {
    	I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS, false);	// set WRITE bit!
    	I2CMasterDataPut(I2C1_MASTER_BASE, reg);
    	I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    	while(I2CMasterBusy(I2C1_MASTER_BASE));
    	if(I2CMasterErr(I2C1_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    	{
    		i2c_errors_process(1);
    		return -1;
    	}
    	I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, SLAVE_ADDRESS, true);	// set WRITE bit!
    	I2CMasterControl(I2C1_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
    	while(I2CMasterBusy(I2C1_MASTER_BASE));
    	if(I2CMasterErr(I2C1_MASTER_BASE) != I2C_MASTER_ERR_NONE)
    	{
    		i2c_errors_process(2);
    	}
    	*data = I2CMasterDataGet(I2C1_MASTER_BASE);
    	return 0;
    }
    
    // ----(end)----------------------------- I2C section -----------------------------------
    
    // init cofidec
    void cof_init()
    {
    	int i;
    	
    	cof_reset(0);
    	{uint32_t delay = 1000000; while(delay--);}
    	cof_reset(1);
    	{uint32_t delay = 1000000; while(delay--);}
    	
    	for(i=0; i<sizeof(conf)/sizeof(T_COF_CONF); i++)
    	{
    		i2c_write_reg_device(conf[i].cof, conf[i].reg, conf[i].val);
    	}
    	
    	{uint32_t delay = 1000; while(delay--);}
    }
    
    // if you want you can read all registers back into the array cof_regs[]
    void read_cof_regs()
    {
    	i2c_read_reg(1, &cof_regs[0]);
    	i2c_read_reg(2, &cof_regs[1]);
    	i2c_read_reg(3, &cof_regs[2]);
    	i2c_read_reg(3, &cof_regs[3]);
    	i2c_read_reg(3, &cof_regs[4]);
    	i2c_read_reg(3, &cof_regs[5]);
    	//i2c_read_regs(3, &cof_regs[5], 2);
    	//i2c_read_regs(4, &cof_regs[7], 2);
    	i2c_read_reg(4, &cof_regs[6]);
    	//i2c_read_reg(5, &cof_regs[7]);
    	i2c_read_reg(5, &cof_regs[7]);
    	i2c_read_reg(5, &cof_regs[8]);
    	i2c_read_reg(5, &cof_regs[9]);
    	i2c_read_reg(5, &cof_regs[10]);
    	//i2c_read_regs(5, &cof_regs[11], 2);
    	i2c_read_reg(6, &cof_regs[11]);
    	i2c_read_reg(6, &cof_regs[12]);
    }
    
    // ---------------------- the part of the main initialization ----------------
    
    void HwSetup(void)
    {
    	// cofidec reset pin
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_5);
    	
    	// I2C init
    	i2c_init();
    
    	// cofidec init	
    	cof_init();
    	
    	// I2S init
    	spi_init();
    }
    
    // ---(beg)-------------------------- I2S section -------------------------------
    
    // ---(end)-------------------------- I2S section -------------------------------

    #include <stdint.h>
    #include <stdbool.h>
    #include <string.h>
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_ssi.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/ssi.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/udma.h"
    #include "spi.h"
    #include "bsp.h"
    #include "system.h"
    
    #pragma data_alignment=1024
    unsigned char ucControlTable[1024];
    // you can use these samples to output sinus through your cofidec
    /*int16_t sin_buf[VOC_BUF_LEN] = 
    {
    	0, 6180, 11756, 16180, 19021, 20000, 19021, 16180, 11756, 6180, 0, -6180, -11756, 
    	-16180, -19021, -20000, -19021, -16180, -11756, -6180, 0, 6180, 11756, 16180, 
    	19021, 20000, 19021, 16180, 11756, 6180, 0, -6180, -11756, -16180, -19021, -20000, 
    	-19021, -16180, -11756, -6180, 0, 6180, 11756, 16180, 19021, 20000, 19021, 16180, 
    	11756, 6180, 0, -6180, -11756, -16180, -19021, -20000, -19021, -16180, -11756, 
    	-6180, 0, 6180, 11756, 16180, 19021, 20000, 19021, 16180, 11756, 6180, 0, -6180, 
    	-11756, -16180, -19021, -20000, -19021, -16180, -11756, -6180, 0, 6180, 11756, 
    	16180, 19021, 20000, 19021, 16180, 11756, 6180, 0, -6180, -11756, -16180, -19021, 
    	-20000, -19021, -16180, -11756, -6180, 0, 6180, 11756, 16180, 19021, 20000, 19021, 
    	16180, 11756, 6180, 0, -6180, -11756, -16180, -19021, -20000, -19021, -16180, 
    	-11756, -6180, 0, 6180, 11756, 16180, 19021, 20000, 19021, 16180, 11756, 6180, 
    	0, -6180, -11756, -16180, -19021, -20000, -19021, -16180, -11756, -6180, 0, 6180, 
    	11756, 16180, 19021, 20000, 19021, 16180, 11756, 6180, 0, -6180, -11756, -16180, 
    	-19021, -20000, -19021, -16180, -11756, -6180
    };*/
    
    int16_t voc_buf_rx[16*VOC_BUF_LEN];
    int16_t *p_voc_buf_rx = voc_buf_rx;
    int16_t *p_voc_buf_end = voc_buf_rx + 16*VOC_BUF_LEN;
    
    int16_t voc_buf_rx_1[2*VOC_BUF_LEN];
    int16_t voc_buf_tx_1[2*VOC_BUF_LEN];
    int16_t voc_buf_rx_2[2*VOC_BUF_LEN];
    int16_t voc_buf_tx_2[2*VOC_BUF_LEN];
    
    int16_t proc_buf[2][VOC_BUF_LEN];
    int i_rd = 0, i_wr = 0;
    
    void spi_init(void)
    {
        unsigned long delay;
    	
    	memset(voc_buf_rx_1, 0, sizeof(voc_buf_rx_1));
    	memset(voc_buf_rx_2, 0, sizeof(voc_buf_rx_2));
        
        SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        uDMAEnable();
        uDMAControlBaseSet(ucControlTable);
        
        GPIOPinConfigure(GPIO_PD0_SSI3CLK);
        GPIOPinConfigure(GPIO_PD1_SSI3FSS);
        GPIOPinConfigure(GPIO_PD2_SSI3RX);
        GPIOPinConfigure(GPIO_PD3_SSI3TX);
        GPIOPinTypeSSI(GPIO_PORTD_BASE,
            GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
        GPIOPadConfigSet(GPIO_PORTD_BASE,
            GPIO_PIN_2, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
        
        for(delay=0; delay<10000; delay++);
    
    	SSIConfigSetExpClk(
            SSI3_BASE, 
            80000000UL, 
            SSI_FRF_TI,
            SSI_MODE_SLAVE, 
            10000000, 
            16);
       
        uDMAChannelDisable(UDMA_CHANNEL_SSI3RX);
     	uDMAChannelAssign(UDMA_CH14_SSI3RX);
    	uDMAChannelDisable(UDMA_CHANNEL_SSI3TX);
     	uDMAChannelAssign(UDMA_CH15_SSI3TX);
    	
    	// Init DMA-channel for SPI-RX
        uDMAChannelAttributeEnable(
            UDMA_CHANNEL_SSI3RX,
            UDMA_ATTR_ALTSELECT);
        uDMAChannelAttributeDisable(
            UDMA_CHANNEL_SSI3RX,
            UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
    	
    	// Init DMA-channel for SPI-TX
        uDMAChannelAttributeEnable(
            UDMA_CHANNEL_SSI3TX,
            UDMA_ATTR_ALTSELECT);
        uDMAChannelAttributeDisable(
            UDMA_CHANNEL_SSI3TX,
            UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
    
        uDMAChannelControlSet(UDMA_CHANNEL_SSI3RX | UDMA_PRI_SELECT,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
    	uDMAChannelControlSet(UDMA_CHANNEL_SSI3RX | UDMA_ALT_SELECT,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        uDMAChannelTransferSet(UDMA_CHANNEL_SSI3RX | UDMA_PRI_SELECT,
            UDMA_MODE_PINGPONG,
            (void*)(SSI3_BASE + SSI_O_DR),
            (void*)voc_buf_rx_1,
            VOC_BUF_LEN);
    	uDMAChannelTransferSet(UDMA_CHANNEL_SSI3RX | UDMA_ALT_SELECT,
            UDMA_MODE_PINGPONG,
            (void*)(SSI3_BASE + SSI_O_DR),
            (void*)voc_buf_rx_2,
            VOC_BUF_LEN);
    	
    	uDMAChannelControlSet(UDMA_CHANNEL_SSI3TX | UDMA_PRI_SELECT,
            UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_1);
    	uDMAChannelControlSet(UDMA_CHANNEL_SSI3TX | UDMA_ALT_SELECT,
            UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_1);
        uDMAChannelTransferSet(UDMA_CHANNEL_SSI3TX | UDMA_PRI_SELECT,
            UDMA_MODE_PINGPONG,
            (void*)voc_buf_tx_1,
            (void*)(SSI3_BASE + SSI_O_DR),
            VOC_BUF_LEN);
    	uDMAChannelTransferSet(UDMA_CHANNEL_SSI3TX | UDMA_ALT_SELECT,
            UDMA_MODE_PINGPONG,
            (void*)voc_buf_tx_2,
    		(void*)(SSI3_BASE + SSI_O_DR),
            VOC_BUF_LEN);
    	
    	
    	uDMAChannelEnable(UDMA_CHANNEL_SSI3RX | UDMA_PRI_SELECT);
    	uDMAChannelEnable(UDMA_CHANNEL_SSI3TX | UDMA_PRI_SELECT);
    	
    	SSIDMAEnable(SSI3_BASE, SSI_DMA_RX | SSI_DMA_TX);
    	SSIEnable(SSI3_BASE);
    	
    	SSIIntClear(SSI3_BASE, SSI_DMA_RX | SSI_DMA_TX);
    	SSIIntEnable(SSI3_BASE, SSI_DMA_RX | SSI_DMA_TX);
    	IntEnable(INT_SSI3);
    }
    
    void store_buf(int16_t *data, int size)
    {
    	if((p_voc_buf_rx + size) < p_voc_buf_end)
    	{
    		memcpy(p_voc_buf_rx, data, size*sizeof(int16_t));
    		p_voc_buf_rx += size;
    	}
    	else
    	{
    		asm("	nop");
    	}
    }
    
    void SSI3_Handler(void)
    {
    	uint32_t ui32Status;
        uint32_t ui32Mode[4];
    	extern void put_semaphore(int16_t *buf);
    	extern void put_semaphore_dac(int16_t *buf);
    
        ui32Status = SSIIntStatus(SSI3_BASE, 1);
    
    	SSIIntClear(SSI3_BASE, ui32Status);
    
        ui32Mode[0] = uDMAChannelModeGet(UDMA_CHANNEL_SSI3RX | UDMA_PRI_SELECT);
    	ui32Mode[1] = uDMAChannelModeGet(UDMA_CHANNEL_SSI3RX | UDMA_ALT_SELECT);
    	ui32Mode[2] = uDMAChannelModeGet(UDMA_CHANNEL_SSI3TX | UDMA_PRI_SELECT);
    	ui32Mode[3] = uDMAChannelModeGet(UDMA_CHANNEL_SSI3TX | UDMA_ALT_SELECT);
        
    	if(ui32Mode[0] == UDMA_MODE_STOP)	// ���� ����������� ���������� �� ������ 1-��� ������...
        {
    		uDMAChannelTransferSet(UDMA_CHANNEL_SSI3RX | UDMA_PRI_SELECT,
            UDMA_MODE_PINGPONG,
            (void*)(SSI3_BASE + SSI_O_DR),
            (void*)voc_buf_rx_1,
            VOC_BUF_LEN);
    		put_semaphore(voc_buf_rx_1);
        }
        
        if(ui32Mode[1] == UDMA_MODE_STOP)	// ���� ����������� ���������� �� ������ 2-��� ������...
        {
    		uDMAChannelTransferSet(UDMA_CHANNEL_SSI3RX | UDMA_ALT_SELECT,
            UDMA_MODE_PINGPONG,
            (void*)(SSI3_BASE + SSI_O_DR),
            (void*)voc_buf_rx_2,
            VOC_BUF_LEN);
    		put_semaphore(voc_buf_rx_2);
        }
    	if(ui32Mode[2] == UDMA_MODE_STOP)	// ���� ����������� ���������� �� �������� 1-��� ������...
        {
    		uDMAChannelTransferSet(UDMA_CHANNEL_SSI3TX | UDMA_PRI_SELECT,
            UDMA_MODE_PINGPONG,
            (void*)voc_buf_tx_1,
    		(void*)(SSI3_BASE + SSI_O_DR),
            VOC_BUF_LEN);
    		put_semaphore_dac(voc_buf_tx_1);
        }
        
        if(ui32Mode[3] == UDMA_MODE_STOP)	// ���� ����������� ���������� �� �������� 2-��� ������...
        {
    		uDMAChannelTransferSet(UDMA_CHANNEL_SSI3TX | UDMA_ALT_SELECT,
            UDMA_MODE_PINGPONG,
            (void*)voc_buf_tx_2,
    		(void*)(SSI3_BASE + SSI_O_DR),
            VOC_BUF_LEN);
    		put_semaphore_dac(voc_buf_tx_2);
        }	
    	
    	
    	if(ui32Mode[0] != ui32Mode[1])
    	{
    		asm("	nop");
    	}
    }
    

  • Hello Tankist,

    Then can you use the same?

    Regards
    Amit
  • I don't exactly understand what you mean...
  • Hello Tankist

    You mentioned that you need some code for aic20k, and then have a post with some example code. Clearly you are reusing existing code, so what is the support of the forum you required. Note that if some one has the same project and be willing to share the same, you may get some code, but that is not how the forum ought to work. We collaborate on projects...

    Regards
    Amit
  • I just hope that my solution helps somebody who have the similar problem. All rights to this code belong to me as a developer it.
    I don't understand what the problem. I started this topic long time ago, I didn't get any advices, so this topic is empty. In general it's a good reason to share your solution if you find an answer. If you think in another way, you can remove my post.
  • Hello Tankist,

    Sorry, I misunderstood the post based on the time lines. Thanks for the contribution

    Regards
    Amit