AD9857 IQ DDS Digital Up Converter Experiment using Nucleo F401

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "pinmap.h"
00003 
00004 #include "dsp.h"
00005 
00006 I2C i2c(I2C_SDA, I2C_SCL);
00007 DigitalOut myled(PA_10);
00008 Serial pc(SERIAL_TX, SERIAL_RX);
00009 
00010 SPI dds_spi(PA_7, NC, PA_5);
00011 DigitalOut dds_reset(PA_0);
00012 DigitalOut dds_dpd(PA_1);
00013 DigitalOut dds_cs(PA_4);
00014 DigitalOut dds_txen(PA_6);
00015 DigitalIn dds_plllockdetect(PA_13);
00016 DigitalIn dds_cicoverflow(PA_14);
00017 PortOut data(PortC, 0x3fff);
00018 
00019 
00020 void
00021 dds_write(uint8_t reg, uint8_t value)
00022 {
00023     dds_spi.write(reg);
00024     dds_spi.write(value);
00025 }
00026 
00027 void
00028 dds_write4(uint8_t reg, uint32_t value)
00029 {
00030     dds_spi.write(reg | 0x60);    
00031     dds_spi.write(value >> 24);
00032     dds_spi.write(value >> 16);
00033     dds_spi.write(value >> 8);
00034     dds_spi.write(value >> 0);
00035 }
00036 
00037 void
00038 dds_init()
00039 {
00040     dds_dpd = 0;
00041     dds_txen = 0;
00042     dds_cs = 1;
00043     dds_reset = 1;
00044     wait_us(10);
00045     dds_reset = 0;
00046     wait_us(200);
00047     dds_cs = 0;
00048     //dds_write(0x01, 0x01); // Single Tone Mode
00049     dds_write(0x01, 0x00); // Quadrature Mode
00050     //dds_write(0x01, 0x02); // DAC Mode
00051     //dds_write(0x00, 0x20 | 0x08); // REFCLK MULTI 8
00052     //dds_write(0x00, 0x20 | 0x14); // REFCLK MULTI 20
00053     dds_write(0x00, 0x20 | 16); // REFCLK MULTI 16 (12MHz x 16 = 192MHz)
00054     //dds_write(0x06, 0x20 << 2); // CIC interpolation ratio: 32
00055     dds_write(0x06, 25 << 2); // CIC interpolation ratio: 25
00056     dds_write(0x07, 0xff); // Scale Output: 0xff
00057     dds_cs = 1;
00058     while (dds_plllockdetect == 0)
00059         ;
00060 }
00061 
00062 void
00063 dds_setup()
00064 {
00065     dds_cs = 0;
00066     dds_txen = 0;
00067     //dds_write4(0x05, 11e6 * (65536.0*65536.0) / (12e6 * 16));
00068     dds_write4(0x05, 51.5e6 * (65536.0*65536.0) / (12e6 * 16));
00069     //dds_write4(0x05, 13.85e6 * (65536.0*65536.0) / (12e6 * 16));
00070     //dds_write4(0x05, 82.5e6 * (65536.0*65536.0) / (12e6 * 16));
00071     //dds_write4(0x05, 21.5e6 * (65536.0*65536.0) / (12e6 * 16));
00072     //dds_write4(0x05, 82.5e6 * (65536.0*65536.0) / (12e6 * 20));
00073     dds_cs = 1;
00074 }
00075 
00076 #if 0
00077 void dma_transfer_complete(DMA_HandleTypeDef *hdma)
00078 {
00079     //dds_txen = 1;
00080     myled = 0;
00081 }
00082 
00083 void dma_error(DMA_HandleTypeDef *hdma)
00084 {
00085     //led = 0;
00086 }
00087 #endif
00088 
00089 DMA_HandleTypeDef DMA_HandleType ={
00090     DMA2_Stream1,
00091     {
00092         DMA_CHANNEL_6,  // Request source is TIM_CH1
00093         DMA_MEMORY_TO_PERIPH,
00094         DMA_PINC_DISABLE,
00095         DMA_MINC_ENABLE,             
00096         DMA_PDATAALIGN_HALFWORD,
00097         DMA_MDATAALIGN_WORD,
00098         DMA_CIRCULAR,//DMA_PFCTRL,//
00099         DMA_PRIORITY_HIGH,
00100         DMA_FIFOMODE_DISABLE,//DMA_FIFOMODE_ENABLE,
00101         DMA_FIFO_THRESHOLD_HALFFULL,
00102         DMA_MBURST_SINGLE,
00103         DMA_PBURST_SINGLE
00104     },
00105     HAL_UNLOCKED,
00106     HAL_DMA_STATE_RESET,//HAL_DMA_STATE_READY
00107     NULL, // parent
00108     NULL, //dma_transfer_complete, // XferCpltCallback
00109     NULL, // XferHalfCpltCallback
00110     NULL, // XferM1CpltCallback
00111     NULL, //dma_error, // XferErrorCallback
00112     NULL  // ErrorCode
00113 };
00114 
00115 TIM_HandleTypeDef         htim;
00116 
00117 #if 0
00118 extern "C" static void
00119 DMA_TIM_IRQHandler()
00120 {    
00121     HAL_DMA_IRQHandler(&DMA_HandleType);
00122 }
00123 #endif
00124 
00125 void dma_init(void)
00126 {
00127     TIM_IC_InitTypeDef       icconf;
00128     GPIO_InitTypeDef gpioconf;   
00129     __DMA2_CLK_ENABLE();
00130     __TIM1_CLK_ENABLE();
00131     __GPIOA_CLK_ENABLE();
00132 
00133     //NVIC_SetVector(DMA2_Stream1_IRQn, (uint32_t)DMA_TIM_IRQHandler);
00134     //HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
00135     
00136     /* PA8 -> TIM1_CH1  */
00137     gpioconf.Pin = GPIO_PIN_8;
00138     gpioconf.Mode = GPIO_MODE_AF_OD;
00139     gpioconf.Pull = GPIO_NOPULL;
00140     gpioconf.Speed = GPIO_SPEED_HIGH;
00141     gpioconf.Alternate = GPIO_AF1_TIM1;
00142     HAL_GPIO_Init(GPIOA, &gpioconf);
00143 
00144     HAL_DMA_Init(&DMA_HandleType);
00145     
00146     htim.Instance = TIM1;
00147     htim.Init.Period        = 1;
00148     htim.Init.Prescaler     = 0;
00149     htim.Init.ClockDivision = 0;
00150     htim.Init.CounterMode   = TIM_COUNTERMODE_UP;
00151     HAL_TIM_IC_Init(&htim);
00152     
00153     //icconf.ICPolarity  = TIM_ICPOLARITY_FALLING;
00154     icconf.ICPolarity  = TIM_ICPOLARITY_RISING;
00155     icconf.ICSelection = TIM_ICSELECTION_DIRECTTI;
00156     icconf.ICPrescaler = TIM_ICPSC_DIV1;
00157     icconf.ICFilter    = 0;
00158     HAL_TIM_IC_ConfigChannel(&htim, &icconf, TIM_CHANNEL_1);
00159     __HAL_TIM_ENABLE_DMA(&htim, TIM_DMA_CC1);
00160     
00161     /* Start the TIM1 Channel1 */
00162     HAL_TIM_IC_Start(&htim, TIM_CHANNEL_1);
00163 }
00164 
00165 void ddsdma_start()
00166 {
00167     dds_txen = 1;
00168     HAL_DMA_Start_IT(&DMA_HandleType, (uint32_t)dma_buf, (uint32_t)&GPIOC->ODR, DMA_DATALEN*2);
00169 }
00170 
00171 
00172 static void I2CWrite(int addr, char d0, char d1)
00173 {
00174     char buf[] = { d0, d1 };
00175     i2c.write(addr<<1, buf, 2);
00176 }
00177 
00178 static int I2CRead(int addr, char d0)
00179 {
00180     char buf[] = { d0 };
00181     i2c.write(addr<<1, buf, 1, true);
00182     i2c.read((addr<<1)+1, buf, 1);
00183     return (unsigned char)buf[0];
00184 }
00185 
00186 static void init_tlv320aic3204()
00187 {
00188     I2CWrite(0x18, 0x00, 0x00); /* Initialize to Page 0 */
00189     I2CWrite(0x18, 0x01, 0x01); /* Initialize the device through software reset */
00190     I2CWrite(0x18, 0x04, 0x43); /* PLL Clock High, MCLK, PLL */
00191     /* 12.000MHz*7.1680 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */
00192     I2CWrite(0x18, 0x05, 0x91); /* Power up PLL, P=1,R=1 */
00193     I2CWrite(0x18, 0x06, 0x07); /* J=7 */
00194     I2CWrite(0x18, 0x07, 6);    /* D=1680 = (6<<8) + 144 */
00195     I2CWrite(0x18, 0x08, 144);
00196     I2CWrite(0x18, 0x0b, 0x82); /* Power up the NDAC divider with value 2 */
00197     I2CWrite(0x18, 0x0c, 0x87); /* Power up the MDAC divider with value 7 */
00198     I2CWrite(0x18, 0x0d, 0x00); /* Program the OSR of DAC to 128 */
00199     I2CWrite(0x18, 0x0e, 0x80);
00200     I2CWrite(0x18, 0x3c, 0x08); /* Set the DAC Mode to PRB_P8 */
00201     I2CWrite(0x18, 0x1b, 0x0c); /* Set the BCLK,WCLK as output */    
00202     I2CWrite(0x18, 0x1e, 0x80 + 28); /* Enable the BCLKN divider with value 28 */
00203     I2CWrite(0x18, 0x25, 0xee); /* DAC power up */
00204     I2CWrite(0x18, 0x00, 0x01); /* Select Page 1 */
00205     I2CWrite(0x18, 0x01, 0x08); /* Disable Internal Crude AVdd in presence of external AVdd supply or before powering up internal AVdd LDO*/
00206     I2CWrite(0x18, 0x02, 0x01); /* Enable Master Analog Power Control */
00207     I2CWrite(0x18, 0x7b, 0x01); /* Set the REF charging time to 40ms */
00208     I2CWrite(0x18, 0x14, 0x25); /* HP soft stepping settings for optimal pop performance at power up Rpop used is 6k with N = 6 and soft step = 20usec. This should work with 47uF coupling capacitor. Can try N=5,6 or 7 time constants as well. Trade-off delay vs “pop” sound. */
00209 //  I2CWrite(0x18, 0x0a, 0x00); /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to Input Common Mode */
00210     I2CWrite(0x18, 0x0a, 0x33); /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to 1.65V */
00211     I2CWrite(0x18, 0x0c, 0x08); /* Route Left DAC to HPL */
00212     I2CWrite(0x18, 0x0d, 0x08); /* Route Right DAC to HPR */
00213     I2CWrite(0x18, 0x03, 0x00); /* Set the DAC PTM mode to PTM_P3/4 */
00214     I2CWrite(0x18, 0x04, 0x00);
00215     I2CWrite(0x18, 0x10, 0x0a); /* Set the HPL gain to 0dB */
00216     I2CWrite(0x18, 0x11, 0x0a); /* Set the HPR gain to 0dB */
00217     I2CWrite(0x18, 0x09, 0x30); /* Power up HPL and HPR drivers */
00218     
00219     I2CWrite(0x18, 0x00, 0x00); /* Select Page 0 */
00220     I2CWrite(0x18, 0x12, 0x87); /* Power up the NADC divider with value 7 */
00221     I2CWrite(0x18, 0x13, 0x82); /* Power up the MADC divider with value 2 */
00222     I2CWrite(0x18, 0x14, 0x80); /* Program the OSR of ADC to 128 */
00223     I2CWrite(0x18, 0x3d, 0x01); /* Select ADC PRB_R1 */
00224     I2CWrite(0x18, 0x00, 0x01); /* Select Page 1 */
00225     I2CWrite(0x18, 0x3d, 0x00); /* Select ADC PTM_R4 */
00226     I2CWrite(0x18, 0x47, 0x32); /* Set MicPGA startup delay to 3.1ms */
00227     I2CWrite(0x18, 0x7b, 0x01); /* Set the REF charging time to 40ms */
00228     I2CWrite(0x18, 0x34, 0x80); /* Route IN1L to LEFT_P with 20K input impedance */
00229     I2CWrite(0x18, 0x36, 0x80); /* Route CM and IN3R to LEFT_N with 20K */
00230     I2CWrite(0x18, 0x37, 0x80); /* Route IN1R and IN3R to RIGHT_P with input impedance of 20K */
00231     I2CWrite(0x18, 0x39, 0x80); /* Route CM to RIGHT_N with impedance of 20K */
00232     I2CWrite(0x18, 0x3b, 0x0); /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */
00233     I2CWrite(0x18, 0x3c, 0x0); /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */
00234     I2CWrite(0x18, 0x33, 0x60); /* Enable MIC bias, 2.5V */
00235 
00236     wait_ms(40);
00237     I2CWrite(0x18, 0x00, 0x00); /* Select Page 0 */
00238     I2CWrite(0x18, 0x3f, 0xd6); /* Power up the Left and Right DAC Channels with route the Left Audio digital data to Left Channel DAC and Right Audio digital data to Right Channel DAC */
00239     I2CWrite(0x18, 0x40, 0x00); /* Unmute the DAC digital volume control */
00240     I2CWrite(0x18, 0x51, 0xc0); /* Power up Left and Right ADC Channels */
00241     I2CWrite(0x18, 0x52, 0x00); /* Unmute Left and Right ADC Digital Volume Control */    
00242     
00243     I2CWrite(0x18, 0x43, 0x93); /* Enable Headphone detection, Debounce 256ms, Button Debounce 32ms */    
00244 }
00245 
00246 void route_dac_headset()
00247 {
00248     I2CWrite(0x18, 0x00, 0x01); /* Select Page 1 */
00249     I2CWrite(0x18, 0x34, 0x00); /* Route IN1L to LEFT_P with 20K input impedance */
00250     I2CWrite(0x18, 0x36, 0x08); /* Route IN3R to LEFT_N with 20K */
00251     I2CWrite(0x18, 0x37, 0x08); /* Route IN3R to RIGHT_P with input impedance of 20K */
00252     I2CWrite(0x18, 0x39, 0x80); /* Route CM to RIGHT_N with impedance of 20K */
00253     I2CWrite(0x18, 0x3b, 0x50); /* Unmute Left MICPGA, Gain selection of 40dB to make channel gain 0dB */
00254     I2CWrite(0x18, 0x3c, 0x50); /* Unmute Right MICPGA, Gain selection of 40dB to make channel gain 0dB */
00255     I2CWrite(0x18, 0x00, 0x00); /* Select Page 0 */
00256 }
00257 
00258 void route_dac_linein()
00259 {
00260     I2CWrite(0x18, 0x00, 0x01); /* Select Page 1 */
00261     I2CWrite(0x18, 0x34, 0x80); /* Route IN1L to LEFT_P with 20K input impedance */
00262     I2CWrite(0x18, 0x36, 0x80); /* Route CM and IN3R to LEFT_N with 20K */
00263     I2CWrite(0x18, 0x37, 0x80); /* Route IN1R and IN3R to RIGHT_P with input impedance of 20K */
00264     I2CWrite(0x18, 0x39, 0x80); /* Route CM to RIGHT_N with impedance of 20K */
00265     I2CWrite(0x18, 0x3b, 0x0); /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */
00266     I2CWrite(0x18, 0x3c, 0x0); /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */
00267     I2CWrite(0x18, 0x00, 0x00); /* Select Page 0 */
00268 }
00269 
00270 static const PinMap PinMap_I2S_CK[] = {
00271     {PB_10,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
00272     {PB_13,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
00273     {NC,    NC,    0}};
00274 static const PinMap PinMap_I2S_WS[] = {
00275     {PB_12,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
00276     {PB_9,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
00277     {NC,    NC,    0}};
00278 static const PinMap PinMap_I2S_SD[] = {
00279     {PC_3,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
00280     {PB_15,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
00281     {NC,    NC,    0}};
00282 static const PinMap PinMap_I2Sext_SD[] = {
00283     {PB_14,  SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_I2S2ext)},
00284     {NC,    NC,    0}};
00285 
00286 extern I2S_HandleTypeDef hi2s;
00287 
00288 DMA_HandleTypeDef hdmatx ={
00289     DMA1_Stream4,
00290     { /*DMA_InitTypeDef*/
00291         DMA_CHANNEL_0,
00292         DMA_MEMORY_TO_PERIPH,
00293         DMA_PINC_DISABLE,
00294         DMA_MINC_ENABLE,             
00295         DMA_PDATAALIGN_HALFWORD,
00296         DMA_MDATAALIGN_WORD,
00297         DMA_CIRCULAR,//DMA_PFCTRL,
00298         DMA_PRIORITY_HIGH,
00299         DMA_FIFOMODE_DISABLE,//DMA_FIFOMODE_ENABLE
00300         DMA_FIFO_THRESHOLD_HALFFULL,
00301         DMA_MBURST_SINGLE,
00302         DMA_PBURST_SINGLE
00303     },
00304     HAL_UNLOCKED,
00305     HAL_DMA_STATE_RESET,//HAL_DMA_STATE_READY
00306     &hi2s, //Parent
00307     NULL,
00308     NULL,
00309     NULL,
00310     NULL,
00311     NULL    
00312 };
00313 
00314 DMA_HandleTypeDef hdmarx ={
00315     DMA1_Stream3,
00316     { /*DMA_InitTypeDef*/
00317         DMA_CHANNEL_3,
00318         DMA_PERIPH_TO_MEMORY,
00319         DMA_PINC_DISABLE,
00320         DMA_MINC_ENABLE,             
00321         DMA_PDATAALIGN_HALFWORD,
00322         DMA_MDATAALIGN_WORD,
00323         DMA_CIRCULAR,//DMA_PFCTRL,
00324         DMA_PRIORITY_HIGH,
00325         DMA_FIFOMODE_ENABLE,//DMA_FIFOMODE_DISABLE,
00326         DMA_FIFO_THRESHOLD_HALFFULL,
00327         DMA_MBURST_SINGLE,
00328         DMA_PBURST_SINGLE
00329     },
00330     HAL_UNLOCKED,
00331     HAL_DMA_STATE_RESET,//HAL_DMA_STATE_READY
00332     &hi2s, //Parent
00333     NULL,
00334     NULL,
00335     NULL,
00336     NULL,
00337     NULL    
00338 };
00339 
00340 I2S_HandleTypeDef hi2s = {
00341      SPI2,
00342      { /*I2S_InitTypeDef*/
00343         I2S_MODE_SLAVE_TX,
00344         I2S_STANDARD_PHILLIPS,
00345         I2S_DATAFORMAT_16B,
00346         I2S_MCLKOUTPUT_DISABLE,
00347         I2S_AUDIOFREQ_48K,
00348         I2S_CPOL_LOW,
00349         I2S_CLOCK_EXTERNAL,
00350         I2S_FULLDUPLEXMODE_ENABLE
00351      },
00352      NULL,  
00353      0,
00354      NULL,
00355      NULL,
00356      NULL,
00357      NULL,
00358      &hdmatx,
00359      &hdmarx,
00360      HAL_UNLOCKED,
00361      HAL_I2S_STATE_RESET,
00362      HAL_I2S_ERROR_NONE
00363 };
00364 
00365 extern "C" static void
00366 DMATX_IRQHandler()
00367 {    
00368     HAL_DMA_IRQHandler(&hdmatx);
00369 }
00370 
00371 extern "C" static void
00372 DMARX_IRQHandler()
00373 {    
00374     HAL_DMA_IRQHandler(&hdmarx);
00375 }
00376 
00377 void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
00378 {
00379     NVIC_SetVector(DMA1_Stream4_IRQn, (uint32_t)DMATX_IRQHandler);
00380     NVIC_SetVector(DMA1_Stream3_IRQn, (uint32_t)DMARX_IRQHandler);
00381     HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
00382     HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
00383     //HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, );
00384 }
00385 
00386 void
00387 i2s_init()
00388 {
00389     __SPI2_CLK_ENABLE();
00390     __DMA1_CLK_ENABLE();
00391     pinmap_pinout(PB_12, PinMap_I2S_WS);
00392     pinmap_pinout(PB_13, PinMap_I2S_CK);
00393     pinmap_pinout(PB_14, PinMap_I2Sext_SD);
00394     pinmap_pinout(PB_15, PinMap_I2S_SD);
00395     pin_mode(PB_12, PullUp);
00396     pin_mode(PB_13, PullUp);
00397     pin_mode(PB_14, PullUp);
00398     pin_mode(PB_15, PullUp);
00399     if (HAL_DMA_Init(&hdmatx) != HAL_OK)
00400         pc.printf("Error:HAL_DMA_Init\n\r");
00401     if (HAL_DMA_Init(&hdmarx) != HAL_OK)
00402         pc.printf("Error:HAL_DMA_Init\n\r");
00403     if (HAL_I2S_Init(&hi2s) != HAL_OK)
00404         pc.printf("Error:HAL_I2S_Init\n\r");
00405 }
00406 
00407 void i2sdma_start() 
00408 {
00409     if (HAL_I2SEx_TransmitReceive_DMA(&hi2s, (uint16_t*)cap_buf, (uint16_t*)cap_buf, sizeof(cap_buf)/sizeof(uint16_t)) != HAL_OK)
00410         pc.printf("Error:HAL_I2S_Transmit_DMA\n\r");
00411 }
00412 
00413 static int first = true;
00414 
00415 uint32_t capbuf_average(int buf)
00416 {
00417     int32_t acc_i = 0;
00418     int32_t acc_q = 0;
00419     for (int i = 0; i < CAPTURE_LEN; i += 2){
00420         acc_i += cap_buf[buf][i+1];
00421         acc_q += cap_buf[buf][i];
00422     }
00423     acc_i /= CAPTURE_LEN/2;
00424     acc_q /= CAPTURE_LEN/2;
00425     return __PKHBT(acc_i, acc_q, 16);
00426 }
00427 
00428 uint32_t capbuf_ave;
00429 uint32_t decay_ave;
00430 
00431 void decay_average(uint32_t in)
00432 {
00433     uint32_t i = __PKHBT(decay_ave, in, 16);
00434     uint32_t q = __PKHTB(in, decay_ave, 16);
00435     int32_t sum_i = __SMUAD(0x0001000f, i) / 16;
00436     int32_t sum_q = __SMUAD(0x0001000f, q) / 16;
00437     decay_ave = __PKHBT(sum_i, sum_q, 16);
00438 }
00439 
00440 
00441 enum {
00442     EVT_NONE = 0,
00443     EVT_BUTTON_PRESSED,
00444     EVT_HEADPHONE_PLUGGED,
00445     EVT_HEADSET_PLUGGED,
00446     EVT_UNPLUGGED
00447 };
00448 
00449 int
00450 process_event()
00451 {
00452     int stat = I2CRead(0x18, 67) & 0x60;
00453     int flag = I2CRead(0x18, 44);
00454     char *msg = NULL;
00455     int evt = 0;
00456     if (flag & 0x10) {
00457         if (stat == 0x60) {
00458             msg = "Headset plugged";
00459             evt = EVT_HEADSET_PLUGGED;
00460         } else if (stat == 0x20) {
00461             msg = "Headphone plugged";
00462             evt = EVT_HEADPHONE_PLUGGED;
00463         } else if (stat == 0x00) {
00464             msg = "Unplugged";
00465             evt = EVT_UNPLUGGED;
00466         }
00467     } else if (flag & 0x20) {
00468         msg = "Button pressed";
00469         evt = EVT_BUTTON_PRESSED;
00470     }
00471     if (msg)
00472         pc.printf("%s\r\n", msg);
00473     return evt;
00474 }
00475 
00476 enum {
00477     MODE_NFM = 0,
00478     MODE_AM,
00479     MODE_USB,
00480     MODE_LSB,
00481     MODE_IQ,
00482     MODE_NUM
00483 };
00484 
00485 int mode = MODE_NFM;//MODE_USB;
00486 
00487 const char *mode_names[] = {
00488     "NFM", "AM", "USB", "LSB", "IQ"
00489 };
00490 
00491 
00492 void hilbert_transform_test();
00493 void pseudo_noise_test();
00494 
00495 
00496 int main()
00497 { 
00498     pc.baud(9600);
00499     pc.printf("AD9857 DDS IQ Synthesizer v0.0\r\n");
00500     pc.printf("SystemCoreClock: %dHz\r\n", SystemCoreClock);
00501     pc.printf("%s\r\n", mode_names[mode]);        
00502     //i2c.frequency(20000);
00503     // pullup I2C bus     
00504     pin_mode(PB_8, PullUp);
00505     pin_mode(PB_9, PullUp);
00506     
00507     dma_init();
00508     dds_init();
00509     dds_setup();
00510 
00511     fmmod_init(&fmmod);
00512     
00513     cic.s0 = __PKHBT(12, 0, 16); // adjust offset
00514     //pseudo_noise_test();
00515     //interpolate_test();
00516     //hilbert_transform_test();
00517     //ddsdma_start();   
00518 
00519     first = true;
00520     init_tlv320aic3204();
00521     i2s_init();
00522     i2sdma_start();
00523 
00524     while (1) {
00525         //pc.printf("%08x\r\n", fmmod.vec);
00526         //myled = !myled;
00527         wait(1);
00528         int evt = process_event();
00529         switch(evt) {
00530         case EVT_BUTTON_PRESSED:
00531             mode = (mode + 1) % MODE_NUM;
00532             pc.printf("%s\r\n", mode_names[mode]);        
00533             break;    
00534         case EVT_HEADSET_PLUGGED:
00535             route_dac_headset();
00536             break;
00537         case EVT_UNPLUGGED:
00538         case EVT_HEADPHONE_PLUGGED:
00539             route_dac_linein();
00540             break;    
00541         }
00542 
00543         //pc.printf("%08x %08x\r\n", decay_ave, capbuf_ave);
00544         //pc.printf("%02x %02x\r\n", I2CRead(0x18, 67), I2CRead(0x18, 44));
00545         if (pc.readable()) {
00546             pc.getc();
00547             uint32_t *buf = (uint32_t *)dma_buf;
00548             pc.printf("%08x %08x %08x %08x\r\n", buf[0], buf[1], buf[2], buf[3]);
00549         }
00550         //pc.printf("%04x %04x\r\n", (uint16_t)fir_buf[0], (uint16_t)fir_buf[1]);
00551         //pc.printf("%08x\r\n", *(uint32_t*)cap_buf[0]);
00552     } 
00553 }
00554 
00555 #if 0
00556 void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
00557 {
00558     //myled = 0;
00559 }
00560 
00561 void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
00562 {
00563     //myled = 1;
00564 }
00565 #endif
00566 
00567 void offset_capture_buffer(uint32_t offset, uint32_t *dst, int dst_len)
00568 {
00569     int i;
00570     for (i = 0; i < dst_len; i += 8) {
00571         dst[0] = __QSUB16(dst[0], offset);
00572         dst[1] = __QSUB16(dst[1], offset);
00573         dst[2] = __QSUB16(dst[2], offset);
00574         dst[3] = __QSUB16(dst[3], offset);
00575         dst[4] = __QSUB16(dst[4], offset);
00576         dst[5] = __QSUB16(dst[5], offset);
00577         dst[6] = __QSUB16(dst[6], offset);
00578         dst[7] = __QSUB16(dst[7], offset);
00579         dst += 8;
00580     }
00581 }
00582 
00583 static void
00584 mod_fm_func(int buf)
00585 {
00586     frequency_modulation(&fmmod, (uint32_t*)cap_buf[buf], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t));
00587 }
00588 static void
00589 mod_am_func(int buf)
00590 {
00591     amplitude_modulation((uint32_t*)cap_buf[buf], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t));
00592 }
00593 
00594 static void
00595 mod_usb_func(int buf)
00596 {
00597     hilbert_transform((uint32_t*)cap_buf[buf], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), 1);
00598     if (buf)
00599         hilbert_transform_save_fir_state((uint32_t*)cap_buf[2]);    
00600 }
00601 
00602 static void
00603 mod_lsb_func(int buf)
00604 {
00605     hilbert_transform((uint32_t*)cap_buf[buf], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), -1);
00606     if (buf)
00607         hilbert_transform_save_fir_state((uint32_t*)cap_buf[2]);    
00608 }
00609 
00610 static void
00611 mod_raw_func(int buf)
00612 {
00613     memcpy(fir_buf, cap_buf[buf], sizeof fir_buf);
00614 }
00615 
00616 void (*mod_funcs[])(int) = {
00617     mod_fm_func,
00618     mod_am_func,
00619     mod_usb_func,
00620     mod_lsb_func,
00621     mod_raw_func
00622 };
00623 
00624 void modulate_buffer_half(int buf)
00625 {
00626     myled = 1;
00627     offset_capture_buffer(decay_ave, (uint32_t*)cap_buf[buf], sizeof cap_buf[0] / sizeof(uint32_t));
00628     //offset_capture_buffer(0x00780088, (uint32_t*)cap_buf[buf], sizeof cap_buf[0] / sizeof(uint32_t));
00629     myled = 0;
00630     myled = 1;
00631     (*mod_funcs[mode])(buf);
00632     myled = 0;
00633     myled = 1;
00634     int cic_len = sizeof(cic_buf)/sizeof(uint32_t);
00635     fir_resample_x4((uint32_t*)fir_state, (uint32_t*)cic_buf, cic_len);
00636     myled = 0;
00637     myled = 1;
00638     cic_interpolate_x10(&cic, (uint32_t*)cic_buf, cic_len, (uint32_t*)dma_buf[buf]);
00639     myled = 0;
00640 }
00641 
00642 void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
00643 {
00644     capbuf_ave = capbuf_average(0);
00645     decay_average(capbuf_ave);
00646     modulate_buffer_half(0);
00647     if (first) {
00648         ddsdma_start();
00649         first = false;
00650     }
00651 }
00652 
00653 void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
00654 {
00655     capbuf_ave = capbuf_average(1);
00656     decay_average(capbuf_ave);
00657     modulate_buffer_half(1);
00658 }
00659 
00660 void
00661 pseudo_noise_test()
00662 {
00663 #define RAND(N)     ((((float)rand() / RAND_MAX) * 2 * N) - N)
00664     int ampl = 10000;
00665     for (int i = 0; i < CAPTURE_LEN/2; i++){
00666         cap_buf[0][i*2] = RAND(ampl);
00667         cap_buf[0][i*2+1] = RAND(ampl); // Rch
00668         cap_buf[1][i*2] = RAND(ampl); // Lch
00669         cap_buf[1][i*2+1] = RAND(ampl); // Rch
00670     }
00671     modulate_buffer_half(0);
00672     modulate_buffer_half(1);
00673     modulate_buffer_half(0);
00674     modulate_buffer_half(1);
00675     ddsdma_start();
00676     pc.printf("Pseudo noise test\r\n");
00677     while(1);
00678     /* no reach */
00679 }
00680 
00681 void
00682 hilbert_transform_test()
00683 {
00684 #if 1
00685     int freq = 800;
00686     int ampl = 3000;
00687     int rate = 48000;
00688     for (int i = 0; i < CAPTURE_LEN; i++){
00689         cap_buf[0][i*2] = sin(2*3.141592 * i * freq / rate) * ampl; // Lch
00690         cap_buf[0][i*2+1] = 0;//sin(2*3.141592 * i * freq / rate) * ampl; // Rch 
00691     }
00692 #endif
00693     int cic_len = sizeof(cic_buf)/sizeof(uint32_t);
00694     hilbert_transform_save_fir_state((uint32_t*)cap_buf[1]);
00695     hilbert_transform((uint32_t*)cap_buf[0], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), 1);
00696     hilbert_transform_save_fir_state((uint32_t*)cap_buf[1]);
00697     fir_resample_x4((uint32_t*)fir_state, (uint32_t*)cic_buf, cic_len);
00698     cic_interpolate_x10(&cic, (uint32_t*)cic_buf, cic_len, (uint32_t*)dma_buf[0]);
00699     
00700     hilbert_transform((uint32_t*)cap_buf[0], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), 1);
00701     hilbert_transform_save_fir_state((uint32_t*)cap_buf[1]);
00702     fir_resample_x4((uint32_t*)fir_state, (uint32_t*)cic_buf, cic_len);
00703     cic_interpolate_x10(&cic, (uint32_t*)cic_buf, cic_len, (uint32_t*)dma_buf[1]);
00704 
00705     hilbert_transform((uint32_t*)cap_buf[0], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), 1);
00706     hilbert_transform_save_fir_state((uint32_t*)cap_buf[1]);
00707     fir_resample_x4((uint32_t*)fir_state, (uint32_t*)cic_buf, cic_len);
00708     cic_interpolate_x10(&cic, (uint32_t*)cic_buf, cic_len, (uint32_t*)dma_buf[0]);
00709     
00710     hilbert_transform((uint32_t*)cap_buf[0], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), 1);
00711     hilbert_transform_save_fir_state((uint32_t*)cap_buf[1]);
00712     fir_resample_x4((uint32_t*)fir_state, (uint32_t*)cic_buf, cic_len);
00713     cic_interpolate_x10(&cic, (uint32_t*)cic_buf, cic_len, (uint32_t*)dma_buf[1]);
00714 #if 0
00715     for (int i = 0; i < 20; i++){
00716         pc.printf("%d, ", cic_buf[i*2]);
00717     }
00718     pc.printf("\n\r");
00719 #endif
00720 #if 1
00721     for (int i = 0; i < 30; i += 2) {
00722         pc.printf("%d:%d ", dma_buf[0][i], dma_buf[0][i+1]);
00723     }
00724     pc.printf("\n\r");
00725     int acc_i = 0;
00726     int acc_q = 0;
00727     for (int i = 0; i < DMA_DATALEN; i += 2){
00728         acc_i += dma_buf[0][i  ];
00729         acc_q += dma_buf[0][i+1];
00730     }
00731     pc.printf("dma acc %d %d\n\r", acc_i, acc_q);
00732 #endif
00733 }
00734