Could anybody give me an example of configuring microcontroller to use with aic20k codec (dma in scatter-gather mode, 2 channels)?
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.
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");
}
}