摘自:https://e2e.ti.com/support/wireless_connectivity/zigbee_6lowpan_802-15-4_mac/f/158/p/462156/1746186
/*
* main.c
*
* Created on: 4 Apr, 2016
* Author: Lenovo
*/
/* Board Header files */
#include "Board.h"
/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Clock.h>
/* XDCtools Header files */
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.h>
/* HW Header files */
#include <inc/hw_types.h>
#include <inc/hw_ints.h>
/* RF Header files */
#include "rfEasyLinkTx.h"
/* UART Header files */
#include <ti/drivers/UART.h> //RTOS
/* AON IOC Header files */
#include <driverlib/aon_ioc.h>
#include <inc/hw_aon_ioc.h>
/* I2S Header files */
#include <driverlib/i2s.h>
#include <driverlib/prcm.h>
#include <ti/drivers/pin/PINCC26XX.h>
/* Power Header files */
#include <ti/drivers/Power.h> //RTOS
#include <ti/drivers/power/PowerCC26XX.h>
/* SSI Header files */
#include <ti/drivers/SPI.h>
#include <ti/drivers/spi/SPICC26XXDMA.h>
#include <ti/drivers/dma/UDMACC26XX.h>
#define BCLK_DIV (16) //BCLK division 48MHz/16 = 3MHz
//#define BCLK_DIV (24) //BCLK division 48MHz/16 = 2MHz
//#define BCLK_DIV (48) //BCLK division 48MHz/16 = 1MHz
#define WCLK (IOID_6)
#define BCLK (IOID_7)
#define MISO (IOID_1)
#define I2S_BUFF_SIZE (512)
#define I2S_BUFF_IN_NUM (2)
#define I2S_BUFF_OUT_NUM (1)
int32_t i2s_in[I2S_BUFF_SIZE];
int32_t i2s_out[I2S_BUFF_SIZE];
int32_t mic_out[I2S_BUFF_SIZE];
/* Pin driver handle */
static PIN_Handle pinHandle;
static PIN_State pinState;
static ti_sysbios_family_arm_m3_Hwi_Struct hwiStruct;
uint32_t mic_buffer_size = 0;
int32_t mic_output = 0;
/* Debug */
volatile unsigned char text[100] = {"\0"};
Task_Struct myTask;
UART_Handle uart;
///* Pin Table */
PIN_Config PinTable[] =
{
WCLK | PIN_INPUT_DIS | PIN_PUSHPULL | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH,
BCLK | PIN_INPUT_DIS | PIN_PUSHPULL | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW ,
MISO | PIN_INPUT_EN | PIN_PULLDOWN,
PIN_TERMINATE /* Terminate list */
};
Char myTaskStack[512];
static void i2s_terminate(void)
{
HWREG(I2S0_BASE + I2S_O_AIFDMACFG) = 0;
HWREG(I2S0_BASE + I2S_O_STMPCTL) = 0;
HWREG(I2S0_BASE + I2S_O_IRQCLR) = 0x3F;
HWREG(PRCM_BASE + PRCM_O_I2SCLKCTL) = 0;
HWREG(PRCM_BASE + PRCM_O_CLKLOADCTL) = PRCM_CLKLOADCTL_LOAD;
HWREG(I2S0_BASE + I2S_O_IRQMASK) = 0;
}
static void i2s_extract(void)
{
sprintf(text, "%d\r", HWREG(I2S0_BASE + I2S_O_STMPWCNT));
UART_write(uart, (const long*)text, sizeof(text));
}
static void i2s_ihandler(UArg arg)
{
// I2SEnable(I2S0_BASE);
I2SPointerUpdate(I2S0_BASE, true);
I2SPointerUpdate(I2S0_BASE, false);
i2s_extract();
}
void Uart_init(void)
{
UART_Params uartParams;
/* Create a UART with data processing off. */
UART_Params_init(&uartParams);
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.readDataMode = UART_DATA_BINARY;
uartParams.readReturnMode = UART_RETURN_FULL;
uartParams.readEcho = UART_ECHO_OFF;
uartParams.baudRate = 19200;
uart = UART_open(Board_UART0, &uartParams);
if (uart == NULL) {
System_abort("Error opening the UART");
}
}
void i2s_init(void)
{
/* 1. Set up and configure required ADx and clock pins */
pinHandle = PIN_open(&pinState, PinTable);
if(NULL == pinHandle)
{
while(1);
}
IOCPortConfigureSet(BCLK, IOC_PORT_MCU_I2S_BCLK, IOC_STD_OUTPUT);
IOCPortConfigureSet(WCLK, IOC_PORT_MCU_I2S_WCLK, IOC_STD_OUTPUT);
IOCPortConfigureSet(MISO, IOC_PORT_MCU_I2S_AD0, IOC_STD_INPUT );
/* 2. Enable I2S peripheral & configure WCLK and MCLK audio clocks */
Power_setConstraint(PowerCC26XX_SB_DISALLOW);
Power_setDependency(PowerCC26XX_PERIPH_I2S);
// I2S Clock Gate Gate For Run mode
HWREG(PRCM_BASE + PRCM_O_I2SCLKGR) = PRCM_I2SCLKGR_CLK_EN;
// I2S Clock gate for Sleep mode
HWREG(PRCM_BASE + PRCM_O_I2SCLKGS) = PRCM_I2SCLKGS_CLK_EN;
// I2S Clock Control (data and WCLK are sampled on the positive edge of BCLK, USER defined WCLK, CLK disabled)
HWREG(PRCM_BASE + PRCM_O_I2SCLKCTL) = (PRCM_I2SCLKCTL_SMPL_ON_POSEDGE | (2 << PRCM_I2SCLKCTL_WCLK_PHASE_S));
// WCLK Division Ratio. (WCLK = MCUCLK/(BDIV*(WDIV[7:0] + WDIV[15:8]) [Hz])) = 48kHz
HWREG(PRCM_BASE + PRCM_O_I2SWCLKDIV) = 0x2020;
// MCLK Division Ratio. (MCLK = MCUCLK/MDIV [Hz] = 48MHz/24 = 2MHz)
HWREG(PRCM_BASE + PRCM_O_I2SMCLKDIV) = 94;
// Load settings from buffers to actual registers
HWREG(PRCM_BASE + PRCM_O_CLKLOADCTL) = PRCM_CLKLOADCTL_LOAD;
/* 3. Configure the serial audio interface format and the memory interface controller
* Set the following registers: I2S:AIFWCLKSRC, I2S:AIFDIRCFG,
* I2S:AIFFMTCFG, I2S:AIFWMSK0, I2S:AIFWMSK1, and I2S:AIFWMSK2.
* BCLK must not be running when changing the I2S:AIFWCLKSRC register. */
I2SControlTable g_controlTable; // Define global
g_pControlTable = &g_controlTable; // Assign pointer
I2SClockConfigure( I2S0_BASE,
I2S_INT_WCLK | // Clock source (internal)
I2S_INVERT_WCLK); // Clock polarity (not inverted)
I2SChannelConfigure(I2S0_BASE,
I2S_MONO_MODE | // single phase chan 0
I2S_LINE_INPUT,
I2S_LINE_UNUSED, // null for chan 1
I2S_LINE_UNUSED); // null for chan 2
I2SAudioFormatConfigure(I2S0_BASE,
I2S_MEM_LENGTH_24 | // Sample size
I2S_POS_EDGE | // Positive Clock edge sampling
I2S_DUAL_PHASE_FMT | // Phase
I2S_WORD_LENGTH_24, // Word length
1);
I2SBufferConfig( I2S0_BASE,
(uint32_t)&i2s_in, // address of input buffer
(uint32_t)&i2s_out, // address of output buffer
I2S_DMA_BUF_SIZE_256, // size of DMA buffer: 256
I2S_BUFF_SIZE);
/* 4. Enable BCLK (set externally in the PRCM module) */
// I2S clock control
HWREG(PRCM_BASE + PRCM_O_I2SCLKCTL) = (PRCM_I2SCLKCTL_SMPL_ON_POSEDGE | (2 << PRCM_I2SCLKCTL_WCLK_PHASE_S) | PRCM_I2SCLKCTL_EN);
// I2S clock control (Use internally generated clock
HWREG(PRCM_BASE + PRCM_O_I2SBCLKSEL) = PRCM_I2SBCLKSEL_SRC;
// BCLK division ratio (BCLK = MCUCLK/BDIV[Hz] = 48MHz/16 = 3MHz)
HWREG(PRCM_BASE + PRCM_O_I2SBCLKDIV) = BCLK_DIV;
//Load setting from buffers to actual registers
HWREG(PRCM_BASE + PRCM_O_CLKLOADCTL) = PRCM_CLKLOADCTL_LOAD;
/* 5. Configure and prepare and samplestamp generator */
// Set the I2S:STMPWPER register.
uint16_t tmp = I2S_BUFF_SIZE;
/* This number corresponds to the total size of the sample ring buffer used by the system.
Set the two registers I2S:STMPINTRIG and I2S:STMPOUTTRIG > I2S:STMPWPER
to avoid false triggers before the samplestamp generator is started.
*/
//WCLK Counter period value
HWREG(PRCM_BASE + I2S_O_STMPWPER) = tmp;
//WCLK Counter trigger value for input pins
HWREG(PRCM_BASE + I2S_O_STMPINTRIG) = tmp + 1;
//WCLK counter trigger value for output pins
HWREG(PRCM_BASE + I2S_O_STMPOUTTRIG) = tmp + 1;
/* 6. Enable the samplestamp generator */
I2SSampleStampEnable(I2S0_BASE);
/* 7. Enable the serial audio interface */
// Set the I2S:AIFPTRNEXT and the I2S:AIFOUTPTRNEXT registers for first memory interface buffers
// Set the I2S:AIFDMACFG register; This number corresponds to the length of each block in the sample ring buffer used by the system
I2SEnable(I2S0_BASE);
// Set the I2S:AIFINPTRNEXT and the I2S:AIFOUTPTRNEXT registers for second memory interface buffers.
I2SPointerUpdate(I2S0_BASE, true);
I2SPointerUpdate(I2S0_BASE, false);
Hwi_Params hwiParams;
// Setup HWI Handler
Hwi_Params_init(&hwiParams);
Hwi_construct(&hwiStruct, INT_I2S_IRQ, i2s_ihandler, &hwiParams, NULL);
// Enable DMA_IN interrupt
I2SIntEnable(I2S0_BASE, I2S_INT_DMA_IN);
I2SPointerUpdate(I2S0_BASE, true);
I2SPointerUpdate(I2S0_BASE, false);
/* 8. START INPUT AND OUTPUT AUDIO STREAMING */
// Set the I2S:STMPINTRIG and the I2S:STMPOUTTRIG registers so they correctly match the I2S:AIFINPTR and the I2S:AIFOUTPTR registers
I2SSampleStampConfigure(I2S0_BASE, true, false);
// Interrupt clear register
I2SIntClear(I2S0_BASE, I2S_INT_DMA_IN);
}
static void taskFxn(UArg a0, UArg a1)
{
i2s_init();
}
int main(void)
{
Task_Params taskParams;
/* Call board init functions. */
Board_initGeneral();
Board_initUART();
/* Initialize UART peripheral */
Uart_init();
/* Configure task. */
Task_Params_init(&taskParams);
taskParams.stack = myTaskStack;
taskParams.stackSize = sizeof(myTaskStack);
Task_construct(&myTask, taskFxn, &taskParams, NULL);
/* Start BIOS */
BIOS_start();
return (0);
}