CC26xx I2S

摘自: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);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值