diff --git a/bsp/stm32_radio/codec.c b/bsp/stm32_radio/codec.c index b7f65a96cf6079bc7bc67eaabaea84dcb20dd8b3..6e03de8c2762373c4315dc823bbd1871b7bfbd68 100644 --- a/bsp/stm32_radio/codec.c +++ b/bsp/stm32_radio/codec.c @@ -1,37 +1,55 @@ #include #include #include "stm32f10x.h" - +#include "codec.h" /* SCLK PA5 SPI1_SCK SDIN PA7 SPI1_MOSI CSB PC5 */ -#define wm_csb_0 GPIO_ResetBits(GPIOC,GPIO_Pin_5) -#define wm_csb_1 GPIO_SetBits(GPIOC,GPIO_Pin_5) +#define CODEC_CSB_PORT GPIOC +#define CODEC_CSB_PIN GPIO_Pin_5 +#define codec_set_csb() do { CODEC_CSB_PORT->BSRR = CODEC_CSB_PIN; } while (0) +#define codec_reset_csb() do { CODEC_CSB_PORT->BRR = CODEC_CSB_PIN; } while (0) + +void vol(uint16_t v); #define DATA_NODE_MAX 5 /* data node for Tx Mode */ -struct wm8753_data_node +struct codec_data_node { rt_uint16_t *data_ptr; rt_size_t data_size; }; -struct wm8753_device +struct codec_device { /* inherit from rt_device */ struct rt_device parent; /* pcm data list */ - struct wm8753_data_node data_list[DATA_NODE_MAX]; + struct codec_data_node data_list[DATA_NODE_MAX]; rt_uint16_t read_index, put_index; /* transmitted offset of current data node */ rt_size_t offset; }; -struct wm8753_device wm8753; +struct codec_device codec; + +struct pll_ratio +{ + uint8_t n; + uint8_t k1; + uint16_t k2; + uint16_t k3; +}; + +static void delay_ms(unsigned int dt) +{ + volatile unsigned int u; + for (u = 0; u < dt * 30; u++); +} static void NVIC_Configuration(void) { @@ -56,332 +74,434 @@ static void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; - /* Disable the JTAG interface and enable the SWJ interface */ - GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); - - /* PC5 CODEC CS */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOC,&GPIO_InitStructure); - - /* Configure SPI2 pins: CK, WS and SD */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOB, &GPIO_InitStructure); - -#if 0 - /* MCO configure */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIOA,&GPIO_InitStructure); - - RCC_MCOConfig(RCC_MCO_HSE); + /* Disable the JTAG interface and enable the SWJ interface */ + GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); + + /* PC5 CODEC CS */ + GPIO_InitStructure.GPIO_Pin = CODEC_CSB_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_Init(CODEC_CSB_PORT, &GPIO_InitStructure); + + /* Configure SPI2 pins: CK, WS and SD */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOB, &GPIO_InitStructure); + +#ifdef CODEC_USE_MCO + /* MCO configure */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOA,&GPIO_InitStructure); + + RCC_MCOConfig(RCC_MCO_HSE); #endif } -#define SPI2_DR_Address 0x4000380C static void DMA_Configuration(rt_uint32_t addr, rt_size_t size) { - DMA_InitTypeDef DMA_InitStructure; - - /* DMA1 Channel2 configuration ----------------------------------------------*/ - DMA_Cmd(DMA1_Channel5, DISABLE); - DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SPI2_DR_Address; - DMA_InitStructure.DMA_MemoryBaseAddr = (u32)addr; - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; - DMA_InitStructure.DMA_BufferSize = size; - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; - DMA_InitStructure.DMA_Priority = DMA_Priority_Low; - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_Init(DMA1_Channel5, &DMA_InitStructure); - - /* Enable SPI2 DMA Tx request */ - SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); - - DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); - DMA_Cmd(DMA1_Channel5, ENABLE); + DMA_InitTypeDef DMA_InitStructure; + + /* DMA1 Channel2 configuration ----------------------------------------------*/ + DMA_Cmd(DMA1_Channel5, DISABLE); + DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(SPI2->DR)); + DMA_InitStructure.DMA_MemoryBaseAddr = (u32) addr; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + DMA_InitStructure.DMA_BufferSize = size; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + DMA_Init(DMA1_Channel5, &DMA_InitStructure); + + /* Enable SPI2 DMA Tx request */ + SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); + + DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); + DMA_Cmd(DMA1_Channel5, ENABLE); } static void I2S_Configuration(void) { - I2S_InitTypeDef I2S_InitStructure; - - /* I2S peripheral configuration */ - I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips; - I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b; - I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable; - I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_44k; - I2S_InitStructure.I2S_CPOL = I2S_CPOL_High;// I2S_CPOL_Low - - /* I2S2 Master Transmitter to I2S3 Slave Receiver communication -----------*/ - /* I2S2 configuration */ - I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;//I2S_Mode_MasterTx I2S_Mode_SlaveTx - I2S_Init(SPI2, &I2S_InitStructure); + I2S_InitTypeDef I2S_InitStructure; + + /* I2S peripheral configuration */ + I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips; + I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b; + I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable; + I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_44k; + I2S_InitStructure.I2S_CPOL = I2S_CPOL_High; // I2S_CPOL_Low + + /* I2S2 Master Transmitter to I2S3 Slave Receiver communication -----------*/ + /* I2S2 configuration */ + I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx; //I2S_Mode_MasterTx I2S_Mode_SlaveTx + I2S_Init(SPI2, &I2S_InitStructure); } -unsigned char SPI_WriteByte(unsigned char data) +uint8_t SPI_WriteByte(unsigned char data) { - unsigned char Data = 0; + //Wait until the transmit buffer is empty + while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); + // Send the byte + SPI_I2S_SendData(SPI1, data); + + //Wait until a data is received + while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); + // Get the received data + data = SPI_I2S_ReceiveData(SPI1); + + // Return the shifted data + return data; +} - //Wait until the transmit buffer is empty - while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET); - // Send the byte - SPI_I2S_SendData(SPI1,data); +static void codec_send(rt_uint16_t s_data) +{ + codec_reset_csb(); + SPI_WriteByte((s_data >> 8) & 0xFF); + SPI_WriteByte(s_data & 0xFF); + codec_set_csb(); +} - //Wait until a data is received - while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET); - // Get the received data - Data = SPI_I2S_ReceiveData(SPI1); +static rt_err_t codec_init(rt_device_t dev) +{ + codec_send(REG_SOFTWARE_RESET); + + // 1.5x boost power up sequence. + // Mute all outputs. + codec_send(REG_LOUT1_VOL | LOUT1MUTE); + codec_send(REG_ROUT1_VOL | ROUT1MUTE); + codec_send(REG_LOUT2_VOL | LOUT2MUTE); + codec_send(REG_ROUT2_VOL | ROUT2MUTE); + // Enable unused output chosen from L/ROUT2, OUT3 or OUT4. + codec_send(REG_POWER_MANAGEMENT3 | OUT4EN); + // Set BUFDCOPEN=1 and BUFIOEN=1 in register R1 + codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN); + // Set SPKBOOST=1 in register R49. + codec_send(REG_OUTPUT | SPKBOOST); + // Set VMIDSEL[1:0] to required value in register R1. + codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K); + // Wait for VMID supply to settle. + delay_ms(750); + // Set L/RMIXEN=1 and DACENL/R=1 in register R3. + codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR); + // Set BIASEN=1 in register R1. + codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN); + // Set L/ROUT2EN=1 in register R3. + codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR | LOUT2EN | ROUT2EN); + // Enable other mixers as required. + // Enable other outputs as required. + codec_send(REG_POWER_MANAGEMENT2 | LOUT1EN | ROUT1EN | BOOSTENL | BOOSTENR | INPPGAENL | INPPGAENR); + + // Digital inferface setup. + codec_send(REG_AUDIO_INTERFACE | BCP_NORMAL | LRP_NORMAL | WL_16BITS | FMT_I2S); + + // PLL setup. + // fs = 44.1KHz / 256fs = 11.2896MHz + // F_PLL = 11.2896MHz * 4 * 2 = 90.3168MHz + // R = 90.3168MHz / 12.288MHz = 7.35 + // PLL_N = 7 + // PLL_K = 5872026 + codec_send(REG_PLL_N | 7); + codec_send(REG_PLL_K1 | 0x16); + codec_send(REG_PLL_K2 | 0xCC); + codec_send(REG_PLL_K3 | 0x19A); + codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN | PLLEN); + codec_send(REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV2); + + // Enable DAC 128x oversampling. + codec_send(REG_DAC | DACOSR128); + + // Set LOUT2/ROUT2 in BTL operation. + codec_send(REG_BEEP | INVROUT2); + + // Set output volume to -22dB. + vol(35); + + return RT_EOK; +} + +// Exported functions +#include - // Return the shifted data - return Data; +void vol(uint16_t v) +{ + v = (v & VOL_MASK) << VOL_POS; + codec_send(REG_LOUT1_VOL | v); + codec_send(REG_ROUT1_VOL | HPVU | v); + codec_send(REG_LOUT2_VOL | v); + codec_send(REG_ROUT2_VOL | SPKVU | v); } -void wm8753_send(rt_uint16_t s_data) +void eq1(uint8_t freq, uint8_t gain, uint8_t mode) { - wm_csb_0; - SPI_WriteByte( (s_data>>8)&0xFF ); - SPI_WriteByte( s_data&0xFF ); - wm_csb_1; + codec_send(REG_EQ1 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (mode ? EQ3DMODE_DAC : EQ3DMODE_ADC)); } -static rt_err_t wm8753_init (rt_device_t dev) +void eq2(uint8_t freq, uint8_t gain, uint8_t bw) { - wm8753_send(0<<9 | 0xFF); // reset - - /* POWER manager */ - wm8753_send(1<<9 | (1<<8) | (0<<7) | (0<<6) | (0<<5) | (1<<4) | (1<<3) | (1<<2) | 2 );//电源设置 - wm8753_send(2<<9 | (1<<8) | (1<<7) | (1<<5) | (1<<4) | (1<<3) | (1<<2) ); // 打开电源 耳机输出 - wm8753_send(3<<9 | (0<<8) | (0<<7) | (1<<6) | (1<<5) | (1<<3) | (1<<2) | (1<<1) | 1 ); // 喇叭输出和DAC - - /* IIS DAC test */ - wm8753_send(4<<9 | (0<<7) | (2<<3) );//IIS 16BIT - // 12.288/3/8=512K - wm8753_send(6<<9 | (0<<5) | (3<<2)| 0);//0: slave 1: master | (3<<5) | (3<<2) - wm8753_send(43<<9 | (1<<4) );//INVROUT2 - - /* 设置初始化音量 */ - wm8753_send(52<<9 | (1<<8) | (1<<7) | 35 ); // LOUT1 0-57-63 - wm8753_send(53<<9 | (1<<8) | (1<<7) | 35 ); // ROUT1 0-57-63 - wm8753_send(54<<9 | (1<<8) | (1<<7) | 35 ); // LOUT2 0-57-63 - wm8753_send(55<<9 | (1<<8) | (1<<7) | 35 ); // ROUT2 0-57-63 - -#if 1 - /* LINE IN test */ - wm8753_send(47<<9 | (1<<8) | (1<<4) ); //L LINE_IN VOL (6:4)输入增益: 0-关 1-12DB 2-9DB 5-0db 7+6DB - wm8753_send(48<<9 | (1<<8) | (1<<4) ); //R LINE_IN VOL (6:4)输入增益: 0-关 1-12DB 2-9DB 5-0db 7+6DB - wm8753_send(50<<9 | (5<<2) | (1<<1) | (1<<0) );//打开左监听 (4:2)增益 0-关 1-12DB 2-9DB 5-0db 7+6DB - wm8753_send(51<<9 | (5<<2) | (1<<1) | (1<<0) );//打开右监听 (4:2)增益 0-关 1-12DB 2-9DB 5-0db 7+6DB - - /* MIC test */ - wm8753_send(44<<9 | (1<<8) | (1<<5) | (1<<4) | (0<<2) | (1<<1) | (1<<0) );//MIC输入选择 - wm8753_send(45<<9 | 50);//16-0 63-35 - wm8753_send(46<<9 | 50);//16-0 63-35 -#endif + codec_send(REG_EQ2 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ2BW_WIDE : EQ2BW_NARROW)); +} - return RT_EOK; +void eq3(uint8_t freq, uint8_t gain, uint8_t bw) +{ + codec_send(REG_EQ3 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ3BW_WIDE : EQ3BW_NARROW)); } -#include -//0~57~63 -void vol(int v) +void eq4(uint8_t freq, uint8_t gain, uint8_t bw) { - wm8753_send(52<<9 | (0<<8) | (1<<7) | v ); // LOUT1 0-57-63 - wm8753_send(53<<9 | (1<<8) | (1<<7) | v ); // ROUT1 0-57-63 - wm8753_send(54<<9 | (0<<8) | (1<<7) | v ); // LOUT2 0-57-63 - wm8753_send(55<<9 | (1<<8) | (1<<7) | v ); // ROUT2 0-57-63 + codec_send(REG_EQ4 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ4BW_WIDE : EQ4BW_NARROW)); } -FINSH_FUNCTION_EXPORT(vol, set volume) -static rt_err_t wm8753_open(rt_device_t dev, rt_uint16_t oflag) +void eq5(uint8_t freq, uint8_t gain) { - /* enable I2S */ - I2S_Cmd(SPI2, ENABLE); + codec_send(REG_EQ2 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS)); +} - return RT_EOK; +void eq3d(uint8_t depth) +{ + codec_send(REG_3D | ((depth & DEPTH3D_MASK) << DEPTH3D_POS)); } -static rt_err_t wm8753_close(rt_device_t dev) +void sample_rate(uint8_t sr) { - /* interrupt mode */ - if (dev->flag & RT_DEVICE_FLAG_INT_TX) - { - /* Disable the I2S2 */ - I2S_Cmd(SPI2, DISABLE); - } + if (sr == 44) + { + codec_send(REG_ADDITIONAL | SR_48KHZ); + codec_send(REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV2); + } + else + { + switch (sr) + { + case 8: + codec_send(REG_ADDITIONAL | SR_8KHZ); + break; + + case 12: + codec_send(REG_ADDITIONAL | SR_12KHZ); + break; + + case 16: + codec_send(REG_ADDITIONAL | SR_16KHZ); + break; + + case 24: + codec_send(REG_ADDITIONAL | SR_24KHZ); + break; + + case 32: + codec_send(REG_ADDITIONAL | SR_32KHZ); + break; + + case 48: + codec_send(REG_ADDITIONAL | SR_48KHZ); + break; + + default: + return; + } + codec_send(REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1); + } +} + +FINSH_FUNCTION_EXPORT(vol, Set volume); +FINSH_FUNCTION_EXPORT(eq1, Set EQ1(Cut-off, Gain, Mode)); +FINSH_FUNCTION_EXPORT(eq2, Set EQ2(Center, Gain, Bandwidth)); +FINSH_FUNCTION_EXPORT(eq3, Set EQ3(Center, Gain, Bandwidth)); +FINSH_FUNCTION_EXPORT(eq4, Set EQ4(Center, Gain, Bandwidth)); +FINSH_FUNCTION_EXPORT(eq5, Set EQ5(Cut-off, Gain)); +FINSH_FUNCTION_EXPORT(eq3d, Set 3D(Depth)); +FINSH_FUNCTION_EXPORT(sample_rate, Set sample rate); - /* remove all data node */ +static rt_err_t codec_open(rt_device_t dev, rt_uint16_t oflag) +{ + /* enable I2S */ + I2S_Cmd(SPI2, ENABLE); - return RT_EOK; + return RT_EOK; } -static rt_err_t wm8753_control(rt_device_t dev, rt_uint8_t cmd, void *args) +static rt_err_t codec_close(rt_device_t dev) { - /* rate control */ - return RT_EOK; + /* interrupt mode */ + if (dev->flag & RT_DEVICE_FLAG_INT_TX) + { + /* Disable the I2S2 */ + I2S_Cmd(SPI2, DISABLE); + } + + /* remove all data node */ + + return RT_EOK; } -static rt_size_t wm8753_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +static rt_err_t codec_control(rt_device_t dev, rt_uint8_t cmd, void *args) { - struct wm8753_device* device; - struct wm8753_data_node* node; - rt_uint32_t level; - rt_uint16_t next_index; - - device = (struct wm8753_device*)dev; - RT_ASSERT(device != RT_NULL); - - next_index = device->put_index + 1; - if (next_index >= DATA_NODE_MAX) next_index = 0; - - /* check data_list full */ - if (next_index == device->read_index) - { - rt_set_errno(-RT_EFULL); - return 0; - } - - level = rt_hw_interrupt_disable(); - node = &device->data_list[device->put_index]; - device->put_index = next_index; - - // rt_kprintf("+\n"); - /* set node attribute */ - node->data_ptr = (rt_uint16_t*)buffer; - node->data_size = size >> 1; /* size is byte unit, convert to half word unit */ - - next_index = device->read_index + 1; - if (next_index >= DATA_NODE_MAX) next_index = 0; - - /* check data list whether is empty */ - if (next_index == device->put_index) - { - if (dev->flag & RT_DEVICE_FLAG_INT_TX) - { - device->offset = 0; - /* enable I2S interrupt */ - SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE); - } - else if (dev->flag & RT_DEVICE_FLAG_DMA_TX) - { - DMA_Configuration((rt_uint32_t)node->data_ptr, node->data_size); - } - } - rt_hw_interrupt_enable(level); - - return size; + /* rate control */ + return RT_EOK; } -rt_err_t wm8753_hw_init(void) +static rt_size_t codec_write(rt_device_t dev, rt_off_t pos, + const void* buffer, rt_size_t size) { - rt_device_t dev; - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); - RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); - - NVIC_Configuration(); - GPIO_Configuration(); - I2S_Configuration(); - - dev = (rt_device_t)&wm8753; - dev->type = RT_Device_Class_Unknown; - dev->rx_indicate = RT_NULL; - dev->tx_complete = RT_NULL; - dev->init = wm8753_init; - dev->open = wm8753_open; - dev->close = wm8753_close; - dev->read = RT_NULL; - dev->write = wm8753_write; - dev->control = wm8753_control; - dev->private = RT_NULL; - - /* set read_index and put index to 0 */ - wm8753.read_index = 0; - wm8753.put_index = 0; - - /* unselect */ - wm_csb_1; - - /* register the device */ - return rt_device_register(&wm8753.parent, "snd", - RT_DEVICE_FLAG_WRONLY | RT_DEVICE_FLAG_DMA_TX); + struct codec_device* device; + struct codec_data_node* node; + rt_uint32_t level; + rt_uint16_t next_index; + + device = (struct codec_device*) dev; + RT_ASSERT(device != RT_NULL); + + next_index = device->put_index + 1; + if (next_index >= DATA_NODE_MAX) + next_index = 0; + + /* check data_list full */ + if (next_index == device->read_index) + { + rt_set_errno(-RT_EFULL); + return 0; + } + + level = rt_hw_interrupt_disable(); + node = &device->data_list[device->put_index]; + device->put_index = next_index; + + // rt_kprintf("+\n"); + /* set node attribute */ + node->data_ptr = (rt_uint16_t*) buffer; + node->data_size = size >> 1; /* size is byte unit, convert to half word unit */ + + next_index = device->read_index + 1; + if (next_index >= DATA_NODE_MAX) + next_index = 0; + + /* check data list whether is empty */ + if (next_index == device->put_index) + { + if (dev->flag & RT_DEVICE_FLAG_INT_TX) + { + device->offset = 0; + /* enable I2S interrupt */ + SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE); + } + else if (dev->flag & RT_DEVICE_FLAG_DMA_TX) + { + DMA_Configuration((rt_uint32_t) node->data_ptr, node->data_size); + } + } + rt_hw_interrupt_enable(level); + + return size; } -void wm8753_isr() +rt_err_t codec_hw_init(void) { - struct wm8753_data_node* node; - node = &wm8753.data_list[wm8753.read_index]; /* get current data node */ - - if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_TXE) == SET) - { - SPI_I2S_SendData(SPI2, node->data_ptr[wm8753.offset++]); - } - - if (wm8753.offset == node->data_size) - { - /* move to next node */ - rt_uint16_t next_index; - - next_index = wm8753.read_index + 1; - if (next_index >= DATA_NODE_MAX) next_index = 0; - - /* notify transmitted complete. */ - if (wm8753.parent.tx_complete != RT_NULL) - { - wm8753.parent.tx_complete (&wm8753.parent, wm8753.data_list[wm8753.read_index].data_ptr); - rt_kprintf("-\n"); - } - - wm8753.offset = 0; - wm8753.read_index = next_index; - if (next_index == wm8753.put_index) - { - /* no data on the list, disable I2S interrupt */ - SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE); - - rt_kprintf("*\n"); - } - } + rt_device_t dev; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); + + NVIC_Configuration(); + GPIO_Configuration(); + I2S_Configuration(); + + dev = (rt_device_t) &codec; + dev->type = RT_Device_Class_Unknown; + dev->rx_indicate = RT_NULL; + dev->tx_complete = RT_NULL; + dev->init = codec_init; + dev->open = codec_open; + dev->close = codec_close; + dev->read = RT_NULL; + dev->write = codec_write; + dev->control = codec_control; + dev->private = RT_NULL; + + /* set read_index and put index to 0 */ + codec.read_index = 0; + codec.put_index = 0; + + /* unselect */ + codec_set_csb(); + + /* register the device */ + return rt_device_register(&codec.parent, "snd", RT_DEVICE_FLAG_WRONLY | RT_DEVICE_FLAG_DMA_TX); } -void wm8753_dma_isr() +void codec_isr() { - /* switch to next buffer */ - rt_uint16_t next_index; - void* data_ptr; - - next_index = wm8753.read_index + 1; - if (next_index >= DATA_NODE_MAX) next_index = 0; - - /* save current data pointer */ - data_ptr = wm8753.data_list[wm8753.read_index].data_ptr; - - wm8753.read_index = next_index; - if (next_index != wm8753.put_index) - { - /* enable next dma request */ - DMA_Configuration((rt_uint32_t)wm8753.data_list[wm8753.read_index].data_ptr, - wm8753.data_list[wm8753.read_index].data_size); - } - else - { - rt_kprintf("*\n"); - } - - /* notify transmitted complete. */ - if (wm8753.parent.tx_complete != RT_NULL) - { - wm8753.parent.tx_complete (&wm8753.parent, data_ptr); - // rt_kprintf("-\n"); - } + struct codec_data_node* node; + node = &codec.data_list[codec.read_index]; /* get current data node */ + + if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_TXE) == SET) + { + SPI_I2S_SendData(SPI2, node->data_ptr[codec.offset++]); + } + + if (codec.offset == node->data_size) + { + /* move to next node */ + rt_uint16_t next_index; + + next_index = codec.read_index + 1; + if (next_index >= DATA_NODE_MAX) + next_index = 0; + + /* notify transmitted complete. */ + if (codec.parent.tx_complete != RT_NULL) + { + codec.parent.tx_complete(&codec.parent, + codec.data_list[codec.read_index].data_ptr); + rt_kprintf("-\n"); + } + + codec.offset = 0; + codec.read_index = next_index; + if (next_index == codec.put_index) + { + /* no data on the list, disable I2S interrupt */ + SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE); + + rt_kprintf("*\n"); + } + } } +void codec_dma_isr() +{ + /* switch to next buffer */ + rt_uint16_t next_index; + void* data_ptr; + + next_index = codec.read_index + 1; + if (next_index >= DATA_NODE_MAX) + next_index = 0; + + /* save current data pointer */ + data_ptr = codec.data_list[codec.read_index].data_ptr; + + codec.read_index = next_index; + if (next_index != codec.put_index) + { + /* enable next dma request */ + DMA_Configuration((rt_uint32_t) codec.data_list[codec.read_index].data_ptr, codec.data_list[codec.read_index].data_size); + } + else + { + rt_kprintf("*\n"); + } + + /* notify transmitted complete. */ + if (codec.parent.tx_complete != RT_NULL) + { + codec.parent.tx_complete(&codec.parent, data_ptr); + // rt_kprintf("-\n"); + } +} diff --git a/bsp/stm32_radio/codec.h b/bsp/stm32_radio/codec.h new file mode 100644 index 0000000000000000000000000000000000000000..0ea64079b7bb75c96f44b5ebd9784c0b05424192 --- /dev/null +++ b/bsp/stm32_radio/codec.h @@ -0,0 +1,627 @@ +#ifndef __CODEC_H__ +#define __CODEC_H__ + +#include + +#define REG_SOFTWARE_RESET ((uint16_t)0) +#define REG_POWER_MANAGEMENT1 ((uint16_t)(1 << 9)) +#define REG_POWER_MANAGEMENT2 ((uint16_t)(2 << 9)) +#define REG_POWER_MANAGEMENT3 ((uint16_t)(3 << 9)) +#define REG_AUDIO_INTERFACE ((uint16_t)(4 << 9)) +#define REG_COMPANDING ((uint16_t)(5 << 9)) +#define REG_CLOCK_GEN ((uint16_t)(6 << 9)) +#define REG_ADDITIONAL ((uint16_t)(7 << 9)) +#define REG_GPIO ((uint16_t)(8 << 9)) +#define REG_JACK_DETECT1 ((uint16_t)(9 << 9)) +#define REG_DAC ((uint16_t)(10 << 9)) +#define REG_LEFT_DAC_VOL ((uint16_t)(11 << 9)) +#define REG_RIGHT_DAC_VOL ((uint16_t)(12 << 9)) +#define REG_JACK_DETECT2 ((uint16_t)(13 << 9)) +#define REG_ADC ((uint16_t)(14 << 9)) +#define REG_LEFT_ADC_VOL ((uint16_t)(15 << 9)) +#define REG_RIGHT_ADC_VOL ((uint16_t)(16 << 9)) +#define REG_EQ1 ((uint16_t)(18 << 9)) +#define REG_EQ2 ((uint16_t)(19 << 9)) +#define REG_EQ3 ((uint16_t)(20 << 9)) +#define REG_EQ4 ((uint16_t)(21 << 9)) +#define REG_EQ5 ((uint16_t)(22 << 9)) +#define REG_DAC_LIMITER1 ((uint16_t)(24 << 9)) +#define REG_DAC_LIMITER2 ((uint16_t)(25 << 9)) +#define REG_NOTCH_FILTER1 ((uint16_t)(27 << 9)) +#define REG_NOTCH_FILTER2 ((uint16_t)(28 << 9)) +#define REG_NOTCH_FILTER3 ((uint16_t)(29 << 9)) +#define REG_NOTCH_FILTER4 ((uint16_t)(30 << 9)) +#define REG_ALC1 ((uint16_t)(32 << 9)) +#define REG_ALC2 ((uint16_t)(33 << 9)) +#define REG_ALC3 ((uint16_t)(34 << 9)) +#define REG_NOISE_GATE ((uint16_t)(35 << 9)) +#define REG_PLL_N ((uint16_t)(36 << 9)) +#define REG_PLL_K1 ((uint16_t)(37 << 9)) +#define REG_PLL_K2 ((uint16_t)(38 << 9)) +#define REG_PLL_K3 ((uint16_t)(39 << 9)) +#define REG_3D ((uint16_t)(41 << 9)) +#define REG_BEEP ((uint16_t)(43 << 9)) +#define REG_INPUT ((uint16_t)(44 << 9)) +#define REG_LEFT_PGA_GAIN ((uint16_t)(45 << 9)) +#define REG_RIGHT_PGA_GAIN ((uint16_t)(46 << 9)) +#define REG_LEFT_ADC_BOOST ((uint16_t)(47 << 9)) +#define REG_RIGHT_ADC_BOOST ((uint16_t)(48 << 9)) +#define REG_OUTPUT ((uint16_t)(49 << 9)) +#define REG_LEFT_MIXER ((uint16_t)(50 << 9)) +#define REG_RIGHT_MIXER ((uint16_t)(51 << 9)) +#define REG_LOUT1_VOL ((uint16_t)(52 << 9)) +#define REG_ROUT1_VOL ((uint16_t)(53 << 9)) +#define REG_LOUT2_VOL ((uint16_t)(54 << 9)) +#define REG_ROUT2_VOL ((uint16_t)(55 << 9)) +#define REG_OUT3_MIXER ((uint16_t)(56 << 9)) +#define REG_OUT4_MIXER ((uint16_t)(57 << 9)) + +// R01 REG_POWER_MANAGEMENT1 +#define BUFDCOPEN (1 << 8) +#define OUT4MIXEN (1 << 7) +#define OUT3MIXEN (1 << 6) +#define PLLEN (1 << 5) +#define MICBEN (1 << 4) +#define BIASEN (1 << 3) +#define BUFIOEN (1 << 2) +#define VMIDSEL_OFF (0) +#define VMIDSEL_75K (1) +#define VMIDSEL_300K (2) +#define VMIDSEL_5K (3) + +// R02 REG_POWER_MANAGEMENT2 +#define ROUT1EN (1 << 8) +#define LOUT1EN (1 << 7) +#define SLEEP (1 << 6) +#define BOOSTENR (1 << 5) +#define BOOSTENL (1 << 4) +#define INPPGAENR (1 << 3) +#define INPPGAENL (1 << 2) +#define ADCENR (1 << 1) +#define ADCENL (1) + +// R03 REG_POWER_MANAGEMENT3 +#define OUT4EN (1 << 8) +#define OUT3EN (1 << 7) +#define LOUT2EN (1 << 6) +#define ROUT2EN (1 << 5) +#define RMIXEN (1 << 3) +#define LMIXEN (1 << 2) +#define DACENR (1 << 1) +#define DACENL (1) + +// R04 REG_AUDIO_INTERFACE +#define BCP_NORMAL (0) +#define BCP_INVERTED (1 << 8) +#define LRP_NORMAL (0) +#define LRP_INVERTED (1 << 7) +#define WL_16BITS (0) +#define WL_20BITS (1 << 5) +#define WL_24BITS (2 << 5) // Default value +#define WL_32BITS (3 << 5) +#define FMT_RIGHT_JUSTIFIED (0) +#define FMT_LEFT_JUSTIFIED (1 << 3) +#define FMT_I2S (2 << 3) // Default value +#define FMT_PCM (3 << 3) +#define DACLRSWAP (1 << 2) +#define ADCLRSWAP (1 << 1) +#define MONO (1) + +// R05 REG_COMPANDING +#define WL8 (1 << 5) +#define DAC_COMP_OFF (0) // Default value +#define DAC_COMP_ULAW (2 << 3) +#define DAC_COMP_ALAW (3 << 3) +#define ADC_COMP_OFF (0) // Default value +#define ADC_COMP_ULAW (2 << 1) +#define ADC_COMP_ALAW (3 << 1) +#define LOOPBACK (1) + +// R06 REG_CLOCK_GEN +#define CLKSEL_MCLK (0) +#define CLKSEL_PLL (1 << 8) // Default value +#define MCLK_DIV1 (0) +#define MCLK_DIV1_5 (1 << 5) +#define MCLK_DIV2 (2 << 5) // Default value +#define MCLK_DIV3 (3 << 5) +#define MCLK_DIV4 (4 << 5) +#define MCLK_DIV6 (5 << 5) +#define MCLK_DIV8 (6 << 5) +#define MCLK_DIV12 (7 << 5) +#define BCLK_DIV1 (0) // Default value +#define BCLK_DIV2 (1 << 2) +#define BCLK_DIV4 (2 << 2) +#define BCLK_DIV8 (3 << 2) +#define BCLK_DIV16 (4 << 2) +#define BCLK_DIV32 (5 << 2) +#define MS (1) + +// R07 REG_ADDITIONAL +#define SR_48KHZ (0) // Default value +#define SR_32KHZ (1 << 1) +#define SR_24KHZ (2 << 1) +#define SR_16KHZ (3 << 1) +#define SR_12KHZ (4 << 1) +#define SR_8KHZ (5 << 1) +#define SLOWCLKEN (1) + +// R08 REG_GPIO +#define OPCLK_DIV1 (0) // Default value +#define OPCLK_DIV2 (1 << 4) +#define OPCLK_DIV3 (2 << 4) +#define OPCLK_DIV4 (3 << 4) +#define GPIO1POL_NONINVERTED (0) // Default value +#define GPIO1POL_INVERTED (1 << 3) +#define GPIO1SEL_INPUT (0) // Default value +#define GPIO1SEL_TEMP_OK (2) +#define GPIO1SEL_AMUTE_ACTIVE (3) +#define GPIO1SEL_PLL_CLK_OP (4) +#define GPIO1SEL_PLL_LOCK (5) +#define GPIO1SEL_LOGIC1 (6) +#define GPIO1SEL_LOGIC0 (7) + +// R09 REG_JACK_DETECT1 +#define JD_VMID_EN1 (1 << 8) +#define JD_VMID_EN0 (1 << 7) +#define JD_EN (1 << 6) +#define JD_SEL_GPIO1 (0 << 4) // Default value +#define JD_SEL_GPIO2 (1 << 4) +#define JD_SEL_GPIO3 (2 << 4) + +// R10 REG_DAC +#define SOFTMUTE (1 << 6) +#define DACOSR128 (1 << 3) +#define AMUTE (1 << 2) +#define DACPOLR (1 << 1) +#define DACPOLL (1) + +// R11 & R12 REG_LEFT_DAC_VOL & REG_RIGHT_DAC_VOL +#define DACVU (1 << 8) +#define DACVOL_POS (0) +#define DACVOL_MASK (0xFF) + +// R13 REG_JACK_DETECT2 +#define JD_OUT4_EN1 (1 << 7) +#define JD_OUT3_EN1 (1 << 6) +#define JD_OUT2_EN1 (1 << 5) +#define JD_OUT1_EN1 (1 << 4) +#define JD_OUT4_EN0 (1 << 3) +#define JD_OUT3_EN0 (1 << 2) +#define JD_OUT2_EN0 (1 << 1) +#define JD_OUT1_EN0 (1) + +// R14 REG_ADC +#define HPFEN (1 << 8) +#define HPFAPP (1 << 7) +#define HPFCUT_POS (4) +#define HPFCUT_MASK (7) +#define HPFCUT_0 (0) +#define HPFCUT_1 (1 << 4) +#define HPFCUT_2 (2 << 4) +#define HPFCUT_3 (3 << 4) +#define HPFCUT_4 (4 << 4) +#define HPFCUT_5 (5 << 4) +#define HPFCUT_6 (6 << 4) +#define HPFCUT_7 (7 << 4) +#define ADCOSR128 (1 << 3) +#define ADCRPOL (1 << 1) +#define ADCLPOL (1) + +// R15 & R16 REG_LEFT_ADC_VOL & REG_RIGHT_ADC_VOL +#define ADCVU (1 << 8) +#define ADCVOL_POS (0) +#define ADCVOL_MASK (0xFF) + +// R18 REG_EQ1 +#define EQ3DMODE_ADC (0) +#define EQ3DMODE_DAC (1 << 8) // Default value +#define EQ1C_80HZ (0) +#define EQ1C_105HZ (1 << 5) // Default value +#define EQ1C_135HZ (2 << 5) +#define EQ1C_175HZ (3 << 5) + +// R19 REG_EQ2 +#define EQ2BW_NARROW (0) // Default value +#define EQ2BW_WIDE (1 << 8) +#define EQ2C_230HZ (0) +#define EQ2C_300HZ (1 << 5) // Default value +#define EQ2C_385HZ (2 << 5) +#define EQ2C_500HZ (3 << 5) + +// R20 REG_EQ3 +#define EQ3BW_NARROW (0) // Default value +#define EQ3BW_WIDE (1 << 8) +#define EQ3C_650HZ (0) +#define EQ3C_850HZ (1 << 5) // Default value +#define EQ3C_1_1KHZ (2 << 5) +#define EQ3C_1_4KHZ (3 << 5) + +// R21 REG_EQ4 +#define EQ4BW_NARROW (0) // Default value +#define EQ4BW_WIDE (1 << 8) +#define EQ4C_1_8KHZ (0) +#define EQ4C_2_4KHZ (1 << 5) // Default value +#define EQ4C_3_2KHZ (2 << 5) +#define EQ4C_4_1KHZ (3 << 5) + +// R22 REG_EQ5 +#define EQ5C_5_3KHZ (0) +#define EQ5C_6_9KHZ (1 << 5) // Default value +#define EQ5C_9KHZ (2 << 5) +#define EQ5C_11_7KHZ (3 << 5) + +// R18 - R22 +#define EQC_POS (5) +#define EQC_MASK (3) +#define EQG_POS (0) +#define EQG_MASK (31) + +// R24 REG_DAC_LIMITER1 +#define LIMEN (1 << 8) +#define LIMDCY_POS (4) +#define LIMDCY_MASK (15) +#define LIMDCY_750US (0) +#define LIMDCY_1_5MS (1 << 4) +#define LIMDCY_3MS (2 << 4) +#define LIMDCY_6MS (3 << 4) // Default value +#define LIMDCY_12MS (4 << 4) +#define LIMDCY_24MS (5 << 4) +#define LIMDCY_48MS (6 << 4) +#define LIMDCY_96MS (7 << 4) +#define LIMDCY_192MS (8 << 4) +#define LIMDCY_384MS (9 << 4) +#define LIMDCY_768MS (10 << 4) +#define LIMATK_POS (0) +#define LIMATK_MASK (15) +#define LIMATK_94US (0) +#define LIMATK_188US (1) +#define LIMATK_375US (2) // Default value +#define LIMATK_750US (3) +#define LIMATK_1_5MS (4) +#define LIMATK_3MS (5) +#define LIMATK_6MS (6) +#define LIMATK_12MS (7) +#define LIMATK_24MS (8) +#define LIMATK_48MS (9) +#define LIMATK_96MS (10) +#define LIMATK_192MS (11) + +// R25 REG_DAC_LIMITER2 +#define LIMLVL_POS (4) +#define LIMLVL_MASK (7) +#define LIMLVL_N1DB (0) // Default value +#define LIMLVL_N2DB (1 << 4) +#define LIMLVL_N3DB (2 << 4) +#define LIMLVL_N4DB (3 << 4) +#define LIMLVL_N5DB (4 << 4) +#define LIMLVL_N6DB (5 << 4) +#define LIMBOOST_POS (0) +#define LIMBOOST_MASK (15) +#define LIMBOOST_0DB (0) +#define LIMBOOST_1DB (1) +#define LIMBOOST_2DB (2) +#define LIMBOOST_3DB (3) +#define LIMBOOST_4DB (4) +#define LIMBOOST_5DB (5) +#define LIMBOOST_6DB (6) +#define LIMBOOST_7DB (7) +#define LIMBOOST_8DB (8) +#define LIMBOOST_9DB (9) +#define LIMBOOST_10DB (10) +#define LIMBOOST_11DB (11) +#define LIMBOOST_12DB (12) + +// R27 - R30 REG_NOTCH_FILTER1 - REG_NOTCH_FILTER4 +#define NFU (1 << 8) +#define NFEN (1 << 7) +#define NFA_POS (0) +#define NFA_MASK (127) + +// R32 REG_ALC1 +#define ALCSEL_OFF (0) // Default value +#define ALCSEL_RIGHT_ONLY (1 << 7) +#define ALCSEL_LEFT_ONLY (2 << 7) +#define ALCSEL_BOTH_ON (3 << 7) +#define ALCMAXGAIN_POS (3) +#define ALCMAXGAIN_MASK (7) +#define ALCMAXGAIN_N6_75DB (0) +#define ALCMAXGAIN_N0_75DB (1 << 3) +#define ALCMAXGAIN_5_25DB (2 << 3) +#define ALCMAXGAIN_11_25DB (3 << 3) +#define ALCMAXGAIN_17_25DB (4 << 3) +#define ALCMAXGAIN_23_25DB (5 << 3) +#define ALCMAXGAIN_29_25DB (6 << 3) +#define ALCMAXGAIN_35_25DB (7 << 3) // Default value +#define ALCMINGAIN_POS (0) +#define ALCMINGAIN_MASK (7) +#define ALCMINGAIN_N12DB (0) // Default value +#define ALCMINGAIN_N6DB (1) +#define ALCMINGAIN_0DB (2) +#define ALCMINGAIN_6DB (3) +#define ALCMINGAIN_12DB (4) +#define ALCMINGAIN_18DB (5) +#define ALCMINGAIN_24DB (6) +#define ALCMINGAIN_30DB (7) + +// R33 REG_ALC2 +#define ALCHLD_POS (4) +#define ALCHLD_MASK (15) +#define ALCHLD_0MS (0) // Default value +#define ALCHLD_2_67MS (1 << 4) +#define ALCHLD_5_33MS (2 << 4) +#define ALCHLD_10_67MS (3 << 4) +#define ALCHLD_21_33MS (4 << 4) +#define ALCHLD_42_67MS (5 << 4) +#define ALCHLD_85_33MS (6 << 4) +#define ALCHLD_170_67MS (7 << 4) +#define ALCHLD_341_33MS (8 << 4) +#define ALCHLD_682_67MS (9 << 4) +#define ALCHLD_1_36S (10 << 4) +#define ALCLVL_POS (0) +#define ALCLVL_MASK (15) +#define ALCLVL_N22_5DBFS (0) +#define ALCLVL_N21DBFS (1) +#define ALCLVL_N19_5DBFS (2) +#define ALCLVL_N18DBFS (3) +#define ALCLVL_N16_5DBFS (4) +#define ALCLVL_N15DBFS (5) +#define ALCLVL_N13_5DBFS (6) +#define ALCLVL_N12DBFS (7) +#define ALCLVL_N10_5DBFS (8) +#define ALCLVL_N9DBFS (9) +#define ALCLVL_N7_5DBFS (10) +#define ALCLVL_N6DBFS (11) // Default value +#define ALCLVL_N4_5DBFS (12) +#define ALCLVL_N3DBFS (13) +#define ALCLVL_N1_5DBFS (14) + +// R34 REG_ALC3 +#define ALCMODE_ALC (0) // Default value +#define ALCMODE_LIMITER (1 << 8) +#define ALCDCY_POS (4) +#define ALCDCY_MASK (15) +#define ALCDCY_0 (0) +#define ALCDCY_1 (1 << 4) +#define ALCDCY_2 (2 << 4) +#define ALCDCY_3 (3 << 4) // Default value +#define ALCDCY_4 (4 << 4) +#define ALCDCY_5 (5 << 4) +#define ALCDCY_6 (6 << 4) +#define ALCDCY_7 (7 << 4) +#define ALCDCY_8 (8 << 4) +#define ALCDCY_9 (9 << 4) +#define ALCDCY_10 (10 << 4) +#define ALCATK_POS (0) +#define ALCATK_MASK (15) +#define ALCATK_0 (0) +#define ALCATK_1 (1) +#define ALCATK_2 (2) // Default value +#define ALCATK_3 (3) +#define ALCATK_4 (4) +#define ALCATK_5 (5) +#define ALCATK_6 (6) +#define ALCATK_7 (7) +#define ALCATK_8 (8) +#define ALCATK_9 (9) +#define ALCATK_10 (10) + +// R35 REG_NOISE_GATE +#define NGEN (1 << 3) +#define NGTH_POS (0) +#define NGTH_MASK (7) +#define NGTH_N39DB (0) // Default value +#define NGTH_N45DB (1) +#define NGTH_N51DB (2) +#define NGTH_N57DB (3) +#define NGTH_N63DB (4) +#define NGTH_N69DB (5) +#define NGTH_N75DB (6) +#define NGTH_N81DB (7) + +// R36 REG_PLL_N +#define PLLPRESCALE (1 << 4) +#define PLLN_POS (0) +#define PLLN_MASK (15) + +// R37 - R39 REG_PLL_K1 - REG_PLL_K3 +#define PLLK1_POS (0) +#define PLLK1_MASK (63) +#define PLLK2_POS (0) +#define PLLK2_MASK (511) +#define PLLK3_POS (0) +#define PLLK3_MASK (511) + +// R41 REG_3D +#define DEPTH3D_POS (0) +#define DEPTH3D_MASK (15) +#define DEPTH3D_0 (0) // Default value +#define DEPTH3D_6_67 (1) +#define DEPTH3D_13_33 (2) +#define DEPTH3D_20 (3) +#define DEPTH3D_26_67 (4) +#define DEPTH3D_33_33 (5) +#define DEPTH3D_40 (6) +#define DEPTH3D_46_67 (7) +#define DEPTH3D_53_33 (8) +#define DEPTH3D_60 (9) +#define DEPTH3D_66_67 (10) +#define DEPTH3D_73_33 (11) +#define DEPTH3D_80 (12) +#define DEPTH3D_86_67 (13) +#define DEPTH3D_93_33 (14) +#define DEPTH3D_100 (15) + +// R43 REG_BEEP +#define MUTERPGA2INV (1 << 5) +#define INVROUT2 (1 << 4) +#define BEEPVOL_POS (1) +#define BEEPVOL_MASK (7) +#define BEEPVOL_N15DB (0) +#define BEEPVOL_N12DB (1 << 1) +#define BEEPVOL_N9DB (2 << 1) +#define BEEPVOL_N6DB (3 << 1) +#define BEEPVOL_N3DB (4 << 1) +#define BEEPVOL_0DB (5 << 1) +#define BEEPVOL_3DB (6 << 1) +#define BEEPVOL_6DB (7 << 1) +#define BEEPEN (1) + +// R44 REG_INPUT +#define MBVSEL_0_9AVDD (0) // Default value +#define MBVSEL_0_65AVDD (1 << 8) +#define R2_2INPVGA (1 << 6) +#define RIN2INPVGA (1 << 5) // Default value +#define RIP2INPVGA (1 << 4) // Default value +#define L2_2INPVGA (1 << 2) +#define LIN2INPVGA (1 << 1) // Default value +#define LIP2INPVGA (1) // Default value + +// R45 REG_LEFT_PGA_GAIN +#define INPPGAUPDATE (1 << 8) +#define INPPGAZCL (1 << 7) +#define INPPGAMUTEL (1 << 6) + +// R46 REG_RIGHT_PGA_GAIN +#define INPPGAZCR (1 << 7) +#define INPPGAMUTER (1 << 6) + +// R45 - R46 +#define INPPGAVOL_POS (0) +#define INPPGAVOL_MASK (63) + +// R47 REG_LEFT_ADC_BOOST +#define PGABOOSTL (1 << 8) // Default value +#define L2_2BOOSTVOL_POS (4) +#define L2_2BOOSTVOL_MASK (7) +#define L2_2BOOSTVOL_DISABLED (0) // Default value +#define L2_2BOOSTVOL_N12DB (1 << 4) +#define L2_2BOOSTVOL_N9DB (2 << 4) +#define L2_2BOOSTVOL_N6DB (3 << 4) +#define L2_2BOOSTVOL_N3DB (4 << 4) +#define L2_2BOOSTVOL_0DB (5 << 4) +#define L2_2BOOSTVOL_3DB (6 << 4) +#define L2_2BOOSTVOL_6DB (7 << 4) +#define AUXL2BOOSTVOL_POS (0) +#define AUXL2BOOSTVOL_MASK (7) +#define AUXL2BOOSTVOL_DISABLED (0) // Default value +#define AUXL2BOOSTVOL_N12DB (1) +#define AUXL2BOOSTVOL_N9DB (2) +#define AUXL2BOOSTVOL_N6DB (3) +#define AUXL2BOOSTVOL_N3DB (4) +#define AUXL2BOOSTVOL_0DB (5) +#define AUXL2BOOSTVOL_3DB (6) +#define AUXL2BOOSTVOL_6DB (7) + +// R48 REG_RIGHT_ADC_BOOST +#define PGABOOSTR (1 << 8) // Default value +#define R2_2BOOSTVOL_POS (4) +#define R2_2BOOSTVOL_MASK (7) +#define R2_2BOOSTVOL_DISABLED (0) // Default value +#define R2_2BOOSTVOL_N12DB (1 << 4) +#define R2_2BOOSTVOL_N9DB (2 << 4) +#define R2_2BOOSTVOL_N6DB (3 << 4) +#define R2_2BOOSTVOL_N3DB (4 << 4) +#define R2_2BOOSTVOL_0DB (5 << 4) +#define R2_2BOOSTVOL_3DB (6 << 4) +#define R2_2BOOSTVOL_6DB (7 << 4) +#define AUXR2BOOSTVOL_POS (0) +#define AUXR2BOOSTVOL_MASK (7) +#define AUXR2BOOSTVOL_DISABLED (0) // Default value +#define AUXR2BOOSTVOL_N12DB (1) +#define AUXR2BOOSTVOL_N9DB (2) +#define AUXR2BOOSTVOL_N6DB (3) +#define AUXR2BOOSTVOL_N3DB (4) +#define AUXR2BOOSTVOL_0DB (5) +#define AUXR2BOOSTVOL_3DB (6) +#define AUXR2BOOSTVOL_6DB (7) + +// R49 REG_OUTPUT +#define DACL2RMIX (1 << 6) +#define DACR2LMIX (1 << 5) +#define OUT4BOOST (1 << 4) +#define OUT3BOOST (1 << 3) +#define SPKBOOST (1 << 2) +#define TSDEN (1 << 1) +#define VROI (1) + +// R50 REG_LEFT_MIXER +#define AUXLMIXVOL_POS (6) +#define AUXLMIXVOL_MASK (7) +#define AUXLMIXVOL_N15DB (0) // Default value +#define AUXLMIXVOL_N12DB (1 << 6) +#define AUXLMIXVOL_N9DB (2 << 6) +#define AUXLMIXVOL_N6DB (3 << 6) +#define AUXLMIXVOL_N3DB (4 << 6) +#define AUXLMIXVOL_0DB (5 << 6) +#define AUXLMIXVOL_3DB (6 << 6) +#define AUXLMIXVOL_6DB (7 << 6) +#define AUXL2LMIX (1 << 5) +#define BYPLMIXVOL_POS (2) +#define BYPLMIXVOL_MASK (7) +#define BYPLMIXVOL_N15DB (0) // Default value +#define BYPLMIXVOL_N12DB (1 << 2) +#define BYPLMIXVOL_N9DB (2 << 2) +#define BYPLMIXVOL_N6DB (3 << 2) +#define BYPLMIXVOL_N3DB (4 << 2) +#define BYPLMIXVOL_0DB (5 << 2) +#define BYPLMIXVOL_3DB (6 << 2) +#define BYPLMIXVOL_6DB (7 << 2) +#define BYPL2LMIX (1 << 1) +#define DACL2LMIX (1) + +// R51 REG_RIGHT_MIXER +#define AUXRMIXVOL_POS (6) +#define AUXRMIXVOL_MASK (7) +#define AUXRMIXVOL_N15DB (0) // Default value +#define AUXRMIXVOL_N12DB (1 << 6) +#define AUXRMIXVOL_N9DB (2 << 6) +#define AUXRMIXVOL_N6DB (3 << 6) +#define AUXRMIXVOL_N3DB (4 << 6) +#define AUXRMIXVOL_0DB (5 << 6) +#define AUXRMIXVOL_3DB (6 << 6) +#define AUXRMIXVOL_6DB (7 << 6) +#define AUXR2RMIX (1 << 5) +#define BYPRMIXVOL_POS (2) +#define BYPRMIXVOL_MASK (7) +#define BYPRMIXVOL_N15DB (0) // Default value +#define BYPRMIXVOL_N12DB (1 << 2) +#define BYPRMIXVOL_N9DB (2 << 2) +#define BYPRMIXVOL_N6DB (3 << 2) +#define BYPRMIXVOL_N3DB (4 << 2) +#define BYPRMIXVOL_0DB (5 << 2) +#define BYPRMIXVOL_3DB (6 << 2) +#define BYPRMIXVOL_6DB (7 << 2) +#define BYPR2RMIX (1 << 1) +#define DACR2RMIX (1) + +// R52 - R55 REG_LOUT1_VOL - REG_ROUT2_VOL +#define HPVU (1 << 8) +#define SPKVU (1 << 8) +#define LOUT1ZC (1 << 7) +#define LOUT1MUTE (1 << 6) +#define ROUT1ZC (1 << 7) +#define ROUT1MUTE (1 << 6) +#define LOUT2ZC (1 << 7) +#define LOUT2MUTE (1 << 6) +#define ROUT2ZC (1 << 7) +#define ROUT2MUTE (1 << 6) +#define VOL_POS (0) +#define VOL_MASK (63) + +// R56 REG_OUT3_MIXER +#define OUT3MUTE (1 << 6) +#define OUT4_2OUT3 (1 << 3) +#define BYPL2OUT3 (1 << 2) +#define LMIX2OUT3 (1 << 1) +#define LDAC2OUT3 (1) + +// R57 REG_OUT4_MIXER +#define OUT4MUTE (1 << 6) +#define HALFSIG (1 << 5) +#define LMIX2OUT4 (1 << 4) +#define LDAC2OUT4 (1 << 3) +#define BYPR2OUT4 (1 << 2) +#define RMIX2OUT4 (1 << 1) +#define RDAC2OUT4 (1) + +#endif // #ifndef __CODEC_H__ diff --git a/bsp/stm32_radio/startup.c b/bsp/stm32_radio/startup.c index a60789c99bfc4454619a0cc3e6fa6bd0a22b93e2..fe82f6aba05feafd11c558ef0536cc389be1258c 100644 --- a/bsp/stm32_radio/startup.c +++ b/bsp/stm32_radio/startup.c @@ -44,8 +44,8 @@ extern void finsh_system_init(void); extern void finsh_set_device(const char* device); #endif extern int rt_application_init(void); -extern rt_err_t wm8753_hw_init(void); -extern rt_err_t wm8978_hw_init(void); +extern rt_err_t codec_hw_init(void); +extern rt_err_t codec_hw_init(void); #ifdef DEBUG /******************************************************************************* * Function Name : assert_failed @@ -104,11 +104,7 @@ void rtthread_startup(void) /* init scheduler system */ rt_system_scheduler_init(); -#if CODEC_VERSION == 1 - wm8753_hw_init(); -#elif CODEC_VERSION == 2 - wm8978_hw_init(); -#endif + codec_hw_init(); /* init hardware serial device */ rt_hw_usart_init(); diff --git a/bsp/stm32_radio/stm32f10x_it.c b/bsp/stm32_radio/stm32f10x_it.c index 1738be8618ffa5709a435e3d89d07a28c7170714..7b73cdc9e6c7e38a8a7712351198eb5e9372dc30 100644 --- a/bsp/stm32_radio/stm32f10x_it.c +++ b/bsp/stm32_radio/stm32f10x_it.c @@ -365,7 +365,7 @@ void DMA1_Channel4_IRQHandler(void) *******************************************************************************/ void DMA1_Channel5_IRQHandler(void) { - extern void wm8753_dma_isr(void); + extern void codec_dma_isr(void); /* enter interrupt */ rt_interrupt_enter(); @@ -377,7 +377,7 @@ void DMA1_Channel5_IRQHandler(void) // rt_kprintf("DMA\n"); /* transmission complete, invoke serial dma tx isr */ - wm8753_dma_isr(); + codec_dma_isr(); } /* leave interrupt */ @@ -446,12 +446,12 @@ void EXTI9_5_IRQHandler(void) *******************************************************************************/ void SPI2_IRQHandler(void) { - extern void wm8753_isr(void); + extern void codec_isr(void); /* enter interrupt */ rt_interrupt_enter(); - wm8753_isr(); + codec_isr(); /* leave interrupt */ rt_interrupt_leave();