AD9857 IQ DDS Digital Up Converter Experiment using Nucleo F401
Digital Signal Processing for IQ Quadradure Modulation DDS AD9857 using Nucleo F401.
see http://ttrftech.tumblr.com/post/114310226891/
main.cpp@6:ed82052bd505, 2015-03-23 (annotated)
- Committer:
- edy555
- Date:
- Mon Mar 23 21:53:48 2015 +0000
- Revision:
- 6:ed82052bd505
- Parent:
- 5:75c26157a53a
use phase accumration in fm modulation, archive very good result!
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
edy555 | 0:55201637d936 | 1 | #include "mbed.h" |
edy555 | 0:55201637d936 | 2 | #include "pinmap.h" |
edy555 | 0:55201637d936 | 3 | |
edy555 | 0:55201637d936 | 4 | #include "dsp.h" |
edy555 | 0:55201637d936 | 5 | |
edy555 | 0:55201637d936 | 6 | I2C i2c(I2C_SDA, I2C_SCL); |
edy555 | 0:55201637d936 | 7 | DigitalOut myled(PA_10); |
edy555 | 0:55201637d936 | 8 | Serial pc(SERIAL_TX, SERIAL_RX); |
edy555 | 0:55201637d936 | 9 | |
edy555 | 0:55201637d936 | 10 | SPI dds_spi(PA_7, NC, PA_5); |
edy555 | 0:55201637d936 | 11 | DigitalOut dds_reset(PA_0); |
edy555 | 0:55201637d936 | 12 | DigitalOut dds_dpd(PA_1); |
edy555 | 0:55201637d936 | 13 | DigitalOut dds_cs(PA_4); |
edy555 | 0:55201637d936 | 14 | DigitalOut dds_txen(PA_6); |
edy555 | 0:55201637d936 | 15 | DigitalIn dds_plllockdetect(PA_13); |
edy555 | 0:55201637d936 | 16 | DigitalIn dds_cicoverflow(PA_14); |
edy555 | 0:55201637d936 | 17 | PortOut data(PortC, 0x3fff); |
edy555 | 0:55201637d936 | 18 | |
edy555 | 0:55201637d936 | 19 | |
edy555 | 0:55201637d936 | 20 | void |
edy555 | 0:55201637d936 | 21 | dds_write(uint8_t reg, uint8_t value) |
edy555 | 0:55201637d936 | 22 | { |
edy555 | 0:55201637d936 | 23 | dds_spi.write(reg); |
edy555 | 0:55201637d936 | 24 | dds_spi.write(value); |
edy555 | 0:55201637d936 | 25 | } |
edy555 | 0:55201637d936 | 26 | |
edy555 | 0:55201637d936 | 27 | void |
edy555 | 0:55201637d936 | 28 | dds_write4(uint8_t reg, uint32_t value) |
edy555 | 0:55201637d936 | 29 | { |
edy555 | 0:55201637d936 | 30 | dds_spi.write(reg | 0x60); |
edy555 | 0:55201637d936 | 31 | dds_spi.write(value >> 24); |
edy555 | 0:55201637d936 | 32 | dds_spi.write(value >> 16); |
edy555 | 0:55201637d936 | 33 | dds_spi.write(value >> 8); |
edy555 | 0:55201637d936 | 34 | dds_spi.write(value >> 0); |
edy555 | 0:55201637d936 | 35 | } |
edy555 | 0:55201637d936 | 36 | |
edy555 | 0:55201637d936 | 37 | void |
edy555 | 0:55201637d936 | 38 | dds_init() |
edy555 | 0:55201637d936 | 39 | { |
edy555 | 0:55201637d936 | 40 | dds_dpd = 0; |
edy555 | 0:55201637d936 | 41 | dds_txen = 0; |
edy555 | 0:55201637d936 | 42 | dds_cs = 1; |
edy555 | 0:55201637d936 | 43 | dds_reset = 1; |
edy555 | 0:55201637d936 | 44 | wait_us(10); |
edy555 | 0:55201637d936 | 45 | dds_reset = 0; |
edy555 | 0:55201637d936 | 46 | wait_us(200); |
edy555 | 0:55201637d936 | 47 | dds_cs = 0; |
edy555 | 0:55201637d936 | 48 | //dds_write(0x01, 0x01); // Single Tone Mode |
edy555 | 0:55201637d936 | 49 | dds_write(0x01, 0x00); // Quadrature Mode |
edy555 | 0:55201637d936 | 50 | //dds_write(0x01, 0x02); // DAC Mode |
edy555 | 0:55201637d936 | 51 | //dds_write(0x00, 0x20 | 0x08); // REFCLK MULTI 8 |
edy555 | 0:55201637d936 | 52 | //dds_write(0x00, 0x20 | 0x14); // REFCLK MULTI 20 |
edy555 | 0:55201637d936 | 53 | dds_write(0x00, 0x20 | 16); // REFCLK MULTI 16 (12MHz x 16 = 192MHz) |
edy555 | 0:55201637d936 | 54 | //dds_write(0x06, 0x20 << 2); // CIC interpolation ratio: 32 |
edy555 | 0:55201637d936 | 55 | dds_write(0x06, 25 << 2); // CIC interpolation ratio: 25 |
edy555 | 0:55201637d936 | 56 | dds_write(0x07, 0xff); // Scale Output: 0xff |
edy555 | 0:55201637d936 | 57 | dds_cs = 1; |
edy555 | 0:55201637d936 | 58 | while (dds_plllockdetect == 0) |
edy555 | 0:55201637d936 | 59 | ; |
edy555 | 0:55201637d936 | 60 | } |
edy555 | 0:55201637d936 | 61 | |
edy555 | 0:55201637d936 | 62 | void |
edy555 | 0:55201637d936 | 63 | dds_setup() |
edy555 | 0:55201637d936 | 64 | { |
edy555 | 0:55201637d936 | 65 | dds_cs = 0; |
edy555 | 0:55201637d936 | 66 | dds_txen = 0; |
edy555 | 0:55201637d936 | 67 | //dds_write4(0x05, 11e6 * (65536.0*65536.0) / (12e6 * 16)); |
edy555 | 2:57e603a26534 | 68 | dds_write4(0x05, 51.5e6 * (65536.0*65536.0) / (12e6 * 16)); |
edy555 | 2:57e603a26534 | 69 | //dds_write4(0x05, 13.85e6 * (65536.0*65536.0) / (12e6 * 16)); |
edy555 | 0:55201637d936 | 70 | //dds_write4(0x05, 82.5e6 * (65536.0*65536.0) / (12e6 * 16)); |
edy555 | 0:55201637d936 | 71 | //dds_write4(0x05, 21.5e6 * (65536.0*65536.0) / (12e6 * 16)); |
edy555 | 0:55201637d936 | 72 | //dds_write4(0x05, 82.5e6 * (65536.0*65536.0) / (12e6 * 20)); |
edy555 | 0:55201637d936 | 73 | dds_cs = 1; |
edy555 | 0:55201637d936 | 74 | } |
edy555 | 0:55201637d936 | 75 | |
edy555 | 0:55201637d936 | 76 | #if 0 |
edy555 | 0:55201637d936 | 77 | void dma_transfer_complete(DMA_HandleTypeDef *hdma) |
edy555 | 0:55201637d936 | 78 | { |
edy555 | 0:55201637d936 | 79 | //dds_txen = 1; |
edy555 | 0:55201637d936 | 80 | myled = 0; |
edy555 | 0:55201637d936 | 81 | } |
edy555 | 0:55201637d936 | 82 | |
edy555 | 0:55201637d936 | 83 | void dma_error(DMA_HandleTypeDef *hdma) |
edy555 | 0:55201637d936 | 84 | { |
edy555 | 0:55201637d936 | 85 | //led = 0; |
edy555 | 0:55201637d936 | 86 | } |
edy555 | 0:55201637d936 | 87 | #endif |
edy555 | 0:55201637d936 | 88 | |
edy555 | 0:55201637d936 | 89 | DMA_HandleTypeDef DMA_HandleType ={ |
edy555 | 0:55201637d936 | 90 | DMA2_Stream1, |
edy555 | 0:55201637d936 | 91 | { |
edy555 | 0:55201637d936 | 92 | DMA_CHANNEL_6, // Request source is TIM_CH1 |
edy555 | 0:55201637d936 | 93 | DMA_MEMORY_TO_PERIPH, |
edy555 | 0:55201637d936 | 94 | DMA_PINC_DISABLE, |
edy555 | 0:55201637d936 | 95 | DMA_MINC_ENABLE, |
edy555 | 0:55201637d936 | 96 | DMA_PDATAALIGN_HALFWORD, |
edy555 | 0:55201637d936 | 97 | DMA_MDATAALIGN_WORD, |
edy555 | 0:55201637d936 | 98 | DMA_CIRCULAR,//DMA_PFCTRL,// |
edy555 | 0:55201637d936 | 99 | DMA_PRIORITY_HIGH, |
edy555 | 0:55201637d936 | 100 | DMA_FIFOMODE_DISABLE,//DMA_FIFOMODE_ENABLE, |
edy555 | 0:55201637d936 | 101 | DMA_FIFO_THRESHOLD_HALFFULL, |
edy555 | 0:55201637d936 | 102 | DMA_MBURST_SINGLE, |
edy555 | 0:55201637d936 | 103 | DMA_PBURST_SINGLE |
edy555 | 0:55201637d936 | 104 | }, |
edy555 | 0:55201637d936 | 105 | HAL_UNLOCKED, |
edy555 | 0:55201637d936 | 106 | HAL_DMA_STATE_RESET,//HAL_DMA_STATE_READY |
edy555 | 0:55201637d936 | 107 | NULL, // parent |
edy555 | 0:55201637d936 | 108 | NULL, //dma_transfer_complete, // XferCpltCallback |
edy555 | 0:55201637d936 | 109 | NULL, // XferHalfCpltCallback |
edy555 | 0:55201637d936 | 110 | NULL, // XferM1CpltCallback |
edy555 | 0:55201637d936 | 111 | NULL, //dma_error, // XferErrorCallback |
edy555 | 0:55201637d936 | 112 | NULL // ErrorCode |
edy555 | 0:55201637d936 | 113 | }; |
edy555 | 0:55201637d936 | 114 | |
edy555 | 0:55201637d936 | 115 | TIM_HandleTypeDef htim; |
edy555 | 0:55201637d936 | 116 | |
edy555 | 0:55201637d936 | 117 | #if 0 |
edy555 | 0:55201637d936 | 118 | extern "C" static void |
edy555 | 0:55201637d936 | 119 | DMA_TIM_IRQHandler() |
edy555 | 0:55201637d936 | 120 | { |
edy555 | 0:55201637d936 | 121 | HAL_DMA_IRQHandler(&DMA_HandleType); |
edy555 | 0:55201637d936 | 122 | } |
edy555 | 0:55201637d936 | 123 | #endif |
edy555 | 0:55201637d936 | 124 | |
edy555 | 0:55201637d936 | 125 | void dma_init(void) |
edy555 | 0:55201637d936 | 126 | { |
edy555 | 0:55201637d936 | 127 | TIM_IC_InitTypeDef icconf; |
edy555 | 0:55201637d936 | 128 | GPIO_InitTypeDef gpioconf; |
edy555 | 0:55201637d936 | 129 | __DMA2_CLK_ENABLE(); |
edy555 | 0:55201637d936 | 130 | __TIM1_CLK_ENABLE(); |
edy555 | 0:55201637d936 | 131 | __GPIOA_CLK_ENABLE(); |
edy555 | 0:55201637d936 | 132 | |
edy555 | 0:55201637d936 | 133 | //NVIC_SetVector(DMA2_Stream1_IRQn, (uint32_t)DMA_TIM_IRQHandler); |
edy555 | 0:55201637d936 | 134 | //HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn); |
edy555 | 0:55201637d936 | 135 | |
edy555 | 0:55201637d936 | 136 | /* PA8 -> TIM1_CH1 */ |
edy555 | 0:55201637d936 | 137 | gpioconf.Pin = GPIO_PIN_8; |
edy555 | 0:55201637d936 | 138 | gpioconf.Mode = GPIO_MODE_AF_OD; |
edy555 | 0:55201637d936 | 139 | gpioconf.Pull = GPIO_NOPULL; |
edy555 | 0:55201637d936 | 140 | gpioconf.Speed = GPIO_SPEED_HIGH; |
edy555 | 0:55201637d936 | 141 | gpioconf.Alternate = GPIO_AF1_TIM1; |
edy555 | 0:55201637d936 | 142 | HAL_GPIO_Init(GPIOA, &gpioconf); |
edy555 | 0:55201637d936 | 143 | |
edy555 | 0:55201637d936 | 144 | HAL_DMA_Init(&DMA_HandleType); |
edy555 | 0:55201637d936 | 145 | |
edy555 | 0:55201637d936 | 146 | htim.Instance = TIM1; |
edy555 | 0:55201637d936 | 147 | htim.Init.Period = 1; |
edy555 | 0:55201637d936 | 148 | htim.Init.Prescaler = 0; |
edy555 | 0:55201637d936 | 149 | htim.Init.ClockDivision = 0; |
edy555 | 0:55201637d936 | 150 | htim.Init.CounterMode = TIM_COUNTERMODE_UP; |
edy555 | 0:55201637d936 | 151 | HAL_TIM_IC_Init(&htim); |
edy555 | 0:55201637d936 | 152 | |
edy555 | 0:55201637d936 | 153 | //icconf.ICPolarity = TIM_ICPOLARITY_FALLING; |
edy555 | 0:55201637d936 | 154 | icconf.ICPolarity = TIM_ICPOLARITY_RISING; |
edy555 | 0:55201637d936 | 155 | icconf.ICSelection = TIM_ICSELECTION_DIRECTTI; |
edy555 | 0:55201637d936 | 156 | icconf.ICPrescaler = TIM_ICPSC_DIV1; |
edy555 | 0:55201637d936 | 157 | icconf.ICFilter = 0; |
edy555 | 0:55201637d936 | 158 | HAL_TIM_IC_ConfigChannel(&htim, &icconf, TIM_CHANNEL_1); |
edy555 | 0:55201637d936 | 159 | __HAL_TIM_ENABLE_DMA(&htim, TIM_DMA_CC1); |
edy555 | 0:55201637d936 | 160 | |
edy555 | 0:55201637d936 | 161 | /* Start the TIM1 Channel1 */ |
edy555 | 0:55201637d936 | 162 | HAL_TIM_IC_Start(&htim, TIM_CHANNEL_1); |
edy555 | 0:55201637d936 | 163 | } |
edy555 | 0:55201637d936 | 164 | |
edy555 | 0:55201637d936 | 165 | void ddsdma_start() |
edy555 | 0:55201637d936 | 166 | { |
edy555 | 0:55201637d936 | 167 | dds_txen = 1; |
edy555 | 0:55201637d936 | 168 | HAL_DMA_Start_IT(&DMA_HandleType, (uint32_t)dma_buf, (uint32_t)&GPIOC->ODR, DMA_DATALEN*2); |
edy555 | 0:55201637d936 | 169 | } |
edy555 | 0:55201637d936 | 170 | |
edy555 | 0:55201637d936 | 171 | |
edy555 | 0:55201637d936 | 172 | static void I2CWrite(int addr, char d0, char d1) |
edy555 | 0:55201637d936 | 173 | { |
edy555 | 0:55201637d936 | 174 | char buf[] = { d0, d1 }; |
edy555 | 0:55201637d936 | 175 | i2c.write(addr<<1, buf, 2); |
edy555 | 0:55201637d936 | 176 | } |
edy555 | 0:55201637d936 | 177 | |
edy555 | 0:55201637d936 | 178 | static int I2CRead(int addr, char d0) |
edy555 | 0:55201637d936 | 179 | { |
edy555 | 0:55201637d936 | 180 | char buf[] = { d0 }; |
edy555 | 0:55201637d936 | 181 | i2c.write(addr<<1, buf, 1, true); |
edy555 | 0:55201637d936 | 182 | i2c.read((addr<<1)+1, buf, 1); |
edy555 | 0:55201637d936 | 183 | return (unsigned char)buf[0]; |
edy555 | 0:55201637d936 | 184 | } |
edy555 | 0:55201637d936 | 185 | |
edy555 | 0:55201637d936 | 186 | static void init_tlv320aic3204() |
edy555 | 0:55201637d936 | 187 | { |
edy555 | 0:55201637d936 | 188 | I2CWrite(0x18, 0x00, 0x00); /* Initialize to Page 0 */ |
edy555 | 0:55201637d936 | 189 | I2CWrite(0x18, 0x01, 0x01); /* Initialize the device through software reset */ |
edy555 | 0:55201637d936 | 190 | I2CWrite(0x18, 0x04, 0x43); /* PLL Clock High, MCLK, PLL */ |
edy555 | 0:55201637d936 | 191 | /* 12.000MHz*7.1680 = 86.016MHz, 86.016MHz/(2*7*128) = 48kHz */ |
edy555 | 0:55201637d936 | 192 | I2CWrite(0x18, 0x05, 0x91); /* Power up PLL, P=1,R=1 */ |
edy555 | 0:55201637d936 | 193 | I2CWrite(0x18, 0x06, 0x07); /* J=7 */ |
edy555 | 0:55201637d936 | 194 | I2CWrite(0x18, 0x07, 6); /* D=1680 = (6<<8) + 144 */ |
edy555 | 0:55201637d936 | 195 | I2CWrite(0x18, 0x08, 144); |
edy555 | 0:55201637d936 | 196 | I2CWrite(0x18, 0x0b, 0x82); /* Power up the NDAC divider with value 2 */ |
edy555 | 0:55201637d936 | 197 | I2CWrite(0x18, 0x0c, 0x87); /* Power up the MDAC divider with value 7 */ |
edy555 | 0:55201637d936 | 198 | I2CWrite(0x18, 0x0d, 0x00); /* Program the OSR of DAC to 128 */ |
edy555 | 0:55201637d936 | 199 | I2CWrite(0x18, 0x0e, 0x80); |
edy555 | 0:55201637d936 | 200 | I2CWrite(0x18, 0x3c, 0x08); /* Set the DAC Mode to PRB_P8 */ |
edy555 | 0:55201637d936 | 201 | I2CWrite(0x18, 0x1b, 0x0c); /* Set the BCLK,WCLK as output */ |
edy555 | 0:55201637d936 | 202 | I2CWrite(0x18, 0x1e, 0x80 + 28); /* Enable the BCLKN divider with value 28 */ |
edy555 | 0:55201637d936 | 203 | I2CWrite(0x18, 0x25, 0xee); /* DAC power up */ |
edy555 | 0:55201637d936 | 204 | I2CWrite(0x18, 0x00, 0x01); /* Select Page 1 */ |
edy555 | 0:55201637d936 | 205 | I2CWrite(0x18, 0x01, 0x08); /* Disable Internal Crude AVdd in presence of external AVdd supply or before powering up internal AVdd LDO*/ |
edy555 | 0:55201637d936 | 206 | I2CWrite(0x18, 0x02, 0x01); /* Enable Master Analog Power Control */ |
edy555 | 0:55201637d936 | 207 | I2CWrite(0x18, 0x7b, 0x01); /* Set the REF charging time to 40ms */ |
edy555 | 0:55201637d936 | 208 | 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. */ |
edy555 | 0:55201637d936 | 209 | // I2CWrite(0x18, 0x0a, 0x00); /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to Input Common Mode */ |
edy555 | 0:55201637d936 | 210 | I2CWrite(0x18, 0x0a, 0x33); /* Set the Input Common Mode to 0.9V and Output Common Mode for Headphone to 1.65V */ |
edy555 | 0:55201637d936 | 211 | I2CWrite(0x18, 0x0c, 0x08); /* Route Left DAC to HPL */ |
edy555 | 0:55201637d936 | 212 | I2CWrite(0x18, 0x0d, 0x08); /* Route Right DAC to HPR */ |
edy555 | 0:55201637d936 | 213 | I2CWrite(0x18, 0x03, 0x00); /* Set the DAC PTM mode to PTM_P3/4 */ |
edy555 | 0:55201637d936 | 214 | I2CWrite(0x18, 0x04, 0x00); |
edy555 | 0:55201637d936 | 215 | I2CWrite(0x18, 0x10, 0x0a); /* Set the HPL gain to 0dB */ |
edy555 | 0:55201637d936 | 216 | I2CWrite(0x18, 0x11, 0x0a); /* Set the HPR gain to 0dB */ |
edy555 | 0:55201637d936 | 217 | I2CWrite(0x18, 0x09, 0x30); /* Power up HPL and HPR drivers */ |
edy555 | 0:55201637d936 | 218 | |
edy555 | 0:55201637d936 | 219 | I2CWrite(0x18, 0x00, 0x00); /* Select Page 0 */ |
edy555 | 0:55201637d936 | 220 | I2CWrite(0x18, 0x12, 0x87); /* Power up the NADC divider with value 7 */ |
edy555 | 0:55201637d936 | 221 | I2CWrite(0x18, 0x13, 0x82); /* Power up the MADC divider with value 2 */ |
edy555 | 0:55201637d936 | 222 | I2CWrite(0x18, 0x14, 0x80); /* Program the OSR of ADC to 128 */ |
edy555 | 0:55201637d936 | 223 | I2CWrite(0x18, 0x3d, 0x01); /* Select ADC PRB_R1 */ |
edy555 | 0:55201637d936 | 224 | I2CWrite(0x18, 0x00, 0x01); /* Select Page 1 */ |
edy555 | 0:55201637d936 | 225 | I2CWrite(0x18, 0x3d, 0x00); /* Select ADC PTM_R4 */ |
edy555 | 0:55201637d936 | 226 | I2CWrite(0x18, 0x47, 0x32); /* Set MicPGA startup delay to 3.1ms */ |
edy555 | 0:55201637d936 | 227 | I2CWrite(0x18, 0x7b, 0x01); /* Set the REF charging time to 40ms */ |
edy555 | 0:55201637d936 | 228 | I2CWrite(0x18, 0x34, 0x80); /* Route IN1L to LEFT_P with 20K input impedance */ |
edy555 | 0:55201637d936 | 229 | I2CWrite(0x18, 0x36, 0x80); /* Route CM and IN3R to LEFT_N with 20K */ |
edy555 | 0:55201637d936 | 230 | I2CWrite(0x18, 0x37, 0x80); /* Route IN1R and IN3R to RIGHT_P with input impedance of 20K */ |
edy555 | 0:55201637d936 | 231 | I2CWrite(0x18, 0x39, 0x80); /* Route CM to RIGHT_N with impedance of 20K */ |
edy555 | 0:55201637d936 | 232 | I2CWrite(0x18, 0x3b, 0x0); /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */ |
edy555 | 0:55201637d936 | 233 | I2CWrite(0x18, 0x3c, 0x0); /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */ |
edy555 | 0:55201637d936 | 234 | I2CWrite(0x18, 0x33, 0x60); /* Enable MIC bias, 2.5V */ |
edy555 | 0:55201637d936 | 235 | |
edy555 | 0:55201637d936 | 236 | wait_ms(40); |
edy555 | 0:55201637d936 | 237 | I2CWrite(0x18, 0x00, 0x00); /* Select Page 0 */ |
edy555 | 0:55201637d936 | 238 | 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 */ |
edy555 | 0:55201637d936 | 239 | I2CWrite(0x18, 0x40, 0x00); /* Unmute the DAC digital volume control */ |
edy555 | 0:55201637d936 | 240 | I2CWrite(0x18, 0x51, 0xc0); /* Power up Left and Right ADC Channels */ |
edy555 | 0:55201637d936 | 241 | I2CWrite(0x18, 0x52, 0x00); /* Unmute Left and Right ADC Digital Volume Control */ |
edy555 | 0:55201637d936 | 242 | |
edy555 | 0:55201637d936 | 243 | I2CWrite(0x18, 0x43, 0x93); /* Enable Headphone detection, Debounce 256ms, Button Debounce 32ms */ |
edy555 | 0:55201637d936 | 244 | } |
edy555 | 0:55201637d936 | 245 | |
edy555 | 0:55201637d936 | 246 | void route_dac_headset() |
edy555 | 0:55201637d936 | 247 | { |
edy555 | 0:55201637d936 | 248 | I2CWrite(0x18, 0x00, 0x01); /* Select Page 1 */ |
edy555 | 0:55201637d936 | 249 | I2CWrite(0x18, 0x34, 0x00); /* Route IN1L to LEFT_P with 20K input impedance */ |
edy555 | 0:55201637d936 | 250 | I2CWrite(0x18, 0x36, 0x08); /* Route IN3R to LEFT_N with 20K */ |
edy555 | 0:55201637d936 | 251 | I2CWrite(0x18, 0x37, 0x08); /* Route IN3R to RIGHT_P with input impedance of 20K */ |
edy555 | 0:55201637d936 | 252 | I2CWrite(0x18, 0x39, 0x80); /* Route CM to RIGHT_N with impedance of 20K */ |
edy555 | 0:55201637d936 | 253 | I2CWrite(0x18, 0x3b, 0x50); /* Unmute Left MICPGA, Gain selection of 40dB to make channel gain 0dB */ |
edy555 | 0:55201637d936 | 254 | I2CWrite(0x18, 0x3c, 0x50); /* Unmute Right MICPGA, Gain selection of 40dB to make channel gain 0dB */ |
edy555 | 0:55201637d936 | 255 | I2CWrite(0x18, 0x00, 0x00); /* Select Page 0 */ |
edy555 | 0:55201637d936 | 256 | } |
edy555 | 0:55201637d936 | 257 | |
edy555 | 0:55201637d936 | 258 | void route_dac_linein() |
edy555 | 0:55201637d936 | 259 | { |
edy555 | 0:55201637d936 | 260 | I2CWrite(0x18, 0x00, 0x01); /* Select Page 1 */ |
edy555 | 0:55201637d936 | 261 | I2CWrite(0x18, 0x34, 0x80); /* Route IN1L to LEFT_P with 20K input impedance */ |
edy555 | 0:55201637d936 | 262 | I2CWrite(0x18, 0x36, 0x80); /* Route CM and IN3R to LEFT_N with 20K */ |
edy555 | 0:55201637d936 | 263 | I2CWrite(0x18, 0x37, 0x80); /* Route IN1R and IN3R to RIGHT_P with input impedance of 20K */ |
edy555 | 0:55201637d936 | 264 | I2CWrite(0x18, 0x39, 0x80); /* Route CM to RIGHT_N with impedance of 20K */ |
edy555 | 0:55201637d936 | 265 | I2CWrite(0x18, 0x3b, 0x0); /* Unmute Left MICPGA, Gain selection of 32dB to make channel gain 0dB */ |
edy555 | 0:55201637d936 | 266 | I2CWrite(0x18, 0x3c, 0x0); /* Unmute Right MICPGA, Gain selection of 32dB to make channel gain 0dB */ |
edy555 | 0:55201637d936 | 267 | I2CWrite(0x18, 0x00, 0x00); /* Select Page 0 */ |
edy555 | 0:55201637d936 | 268 | } |
edy555 | 0:55201637d936 | 269 | |
edy555 | 0:55201637d936 | 270 | static const PinMap PinMap_I2S_CK[] = { |
edy555 | 0:55201637d936 | 271 | {PB_10, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, |
edy555 | 0:55201637d936 | 272 | {PB_13, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, |
edy555 | 0:55201637d936 | 273 | {NC, NC, 0}}; |
edy555 | 0:55201637d936 | 274 | static const PinMap PinMap_I2S_WS[] = { |
edy555 | 0:55201637d936 | 275 | {PB_12, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, |
edy555 | 0:55201637d936 | 276 | {PB_9, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, |
edy555 | 0:55201637d936 | 277 | {NC, NC, 0}}; |
edy555 | 0:55201637d936 | 278 | static const PinMap PinMap_I2S_SD[] = { |
edy555 | 0:55201637d936 | 279 | {PC_3, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, |
edy555 | 0:55201637d936 | 280 | {PB_15, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, |
edy555 | 0:55201637d936 | 281 | {NC, NC, 0}}; |
edy555 | 0:55201637d936 | 282 | static const PinMap PinMap_I2Sext_SD[] = { |
edy555 | 0:55201637d936 | 283 | {PB_14, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_I2S2ext)}, |
edy555 | 0:55201637d936 | 284 | {NC, NC, 0}}; |
edy555 | 0:55201637d936 | 285 | |
edy555 | 0:55201637d936 | 286 | extern I2S_HandleTypeDef hi2s; |
edy555 | 0:55201637d936 | 287 | |
edy555 | 0:55201637d936 | 288 | DMA_HandleTypeDef hdmatx ={ |
edy555 | 0:55201637d936 | 289 | DMA1_Stream4, |
edy555 | 0:55201637d936 | 290 | { /*DMA_InitTypeDef*/ |
edy555 | 0:55201637d936 | 291 | DMA_CHANNEL_0, |
edy555 | 0:55201637d936 | 292 | DMA_MEMORY_TO_PERIPH, |
edy555 | 0:55201637d936 | 293 | DMA_PINC_DISABLE, |
edy555 | 0:55201637d936 | 294 | DMA_MINC_ENABLE, |
edy555 | 0:55201637d936 | 295 | DMA_PDATAALIGN_HALFWORD, |
edy555 | 0:55201637d936 | 296 | DMA_MDATAALIGN_WORD, |
edy555 | 0:55201637d936 | 297 | DMA_CIRCULAR,//DMA_PFCTRL, |
edy555 | 0:55201637d936 | 298 | DMA_PRIORITY_HIGH, |
edy555 | 0:55201637d936 | 299 | DMA_FIFOMODE_DISABLE,//DMA_FIFOMODE_ENABLE |
edy555 | 0:55201637d936 | 300 | DMA_FIFO_THRESHOLD_HALFFULL, |
edy555 | 0:55201637d936 | 301 | DMA_MBURST_SINGLE, |
edy555 | 0:55201637d936 | 302 | DMA_PBURST_SINGLE |
edy555 | 0:55201637d936 | 303 | }, |
edy555 | 0:55201637d936 | 304 | HAL_UNLOCKED, |
edy555 | 0:55201637d936 | 305 | HAL_DMA_STATE_RESET,//HAL_DMA_STATE_READY |
edy555 | 0:55201637d936 | 306 | &hi2s, //Parent |
edy555 | 0:55201637d936 | 307 | NULL, |
edy555 | 0:55201637d936 | 308 | NULL, |
edy555 | 0:55201637d936 | 309 | NULL, |
edy555 | 0:55201637d936 | 310 | NULL, |
edy555 | 0:55201637d936 | 311 | NULL |
edy555 | 0:55201637d936 | 312 | }; |
edy555 | 0:55201637d936 | 313 | |
edy555 | 0:55201637d936 | 314 | DMA_HandleTypeDef hdmarx ={ |
edy555 | 0:55201637d936 | 315 | DMA1_Stream3, |
edy555 | 0:55201637d936 | 316 | { /*DMA_InitTypeDef*/ |
edy555 | 0:55201637d936 | 317 | DMA_CHANNEL_3, |
edy555 | 0:55201637d936 | 318 | DMA_PERIPH_TO_MEMORY, |
edy555 | 0:55201637d936 | 319 | DMA_PINC_DISABLE, |
edy555 | 0:55201637d936 | 320 | DMA_MINC_ENABLE, |
edy555 | 0:55201637d936 | 321 | DMA_PDATAALIGN_HALFWORD, |
edy555 | 0:55201637d936 | 322 | DMA_MDATAALIGN_WORD, |
edy555 | 0:55201637d936 | 323 | DMA_CIRCULAR,//DMA_PFCTRL, |
edy555 | 0:55201637d936 | 324 | DMA_PRIORITY_HIGH, |
edy555 | 0:55201637d936 | 325 | DMA_FIFOMODE_ENABLE,//DMA_FIFOMODE_DISABLE, |
edy555 | 0:55201637d936 | 326 | DMA_FIFO_THRESHOLD_HALFFULL, |
edy555 | 0:55201637d936 | 327 | DMA_MBURST_SINGLE, |
edy555 | 0:55201637d936 | 328 | DMA_PBURST_SINGLE |
edy555 | 0:55201637d936 | 329 | }, |
edy555 | 0:55201637d936 | 330 | HAL_UNLOCKED, |
edy555 | 0:55201637d936 | 331 | HAL_DMA_STATE_RESET,//HAL_DMA_STATE_READY |
edy555 | 0:55201637d936 | 332 | &hi2s, //Parent |
edy555 | 0:55201637d936 | 333 | NULL, |
edy555 | 0:55201637d936 | 334 | NULL, |
edy555 | 0:55201637d936 | 335 | NULL, |
edy555 | 0:55201637d936 | 336 | NULL, |
edy555 | 0:55201637d936 | 337 | NULL |
edy555 | 0:55201637d936 | 338 | }; |
edy555 | 0:55201637d936 | 339 | |
edy555 | 0:55201637d936 | 340 | I2S_HandleTypeDef hi2s = { |
edy555 | 0:55201637d936 | 341 | SPI2, |
edy555 | 0:55201637d936 | 342 | { /*I2S_InitTypeDef*/ |
edy555 | 0:55201637d936 | 343 | I2S_MODE_SLAVE_TX, |
edy555 | 0:55201637d936 | 344 | I2S_STANDARD_PHILLIPS, |
edy555 | 0:55201637d936 | 345 | I2S_DATAFORMAT_16B, |
edy555 | 0:55201637d936 | 346 | I2S_MCLKOUTPUT_DISABLE, |
edy555 | 0:55201637d936 | 347 | I2S_AUDIOFREQ_48K, |
edy555 | 0:55201637d936 | 348 | I2S_CPOL_LOW, |
edy555 | 0:55201637d936 | 349 | I2S_CLOCK_EXTERNAL, |
edy555 | 0:55201637d936 | 350 | I2S_FULLDUPLEXMODE_ENABLE |
edy555 | 0:55201637d936 | 351 | }, |
edy555 | 0:55201637d936 | 352 | NULL, |
edy555 | 0:55201637d936 | 353 | 0, |
edy555 | 0:55201637d936 | 354 | NULL, |
edy555 | 0:55201637d936 | 355 | NULL, |
edy555 | 0:55201637d936 | 356 | NULL, |
edy555 | 0:55201637d936 | 357 | NULL, |
edy555 | 0:55201637d936 | 358 | &hdmatx, |
edy555 | 0:55201637d936 | 359 | &hdmarx, |
edy555 | 0:55201637d936 | 360 | HAL_UNLOCKED, |
edy555 | 0:55201637d936 | 361 | HAL_I2S_STATE_RESET, |
edy555 | 0:55201637d936 | 362 | HAL_I2S_ERROR_NONE |
edy555 | 0:55201637d936 | 363 | }; |
edy555 | 0:55201637d936 | 364 | |
edy555 | 0:55201637d936 | 365 | extern "C" static void |
edy555 | 0:55201637d936 | 366 | DMATX_IRQHandler() |
edy555 | 0:55201637d936 | 367 | { |
edy555 | 0:55201637d936 | 368 | HAL_DMA_IRQHandler(&hdmatx); |
edy555 | 0:55201637d936 | 369 | } |
edy555 | 0:55201637d936 | 370 | |
edy555 | 0:55201637d936 | 371 | extern "C" static void |
edy555 | 0:55201637d936 | 372 | DMARX_IRQHandler() |
edy555 | 0:55201637d936 | 373 | { |
edy555 | 0:55201637d936 | 374 | HAL_DMA_IRQHandler(&hdmarx); |
edy555 | 0:55201637d936 | 375 | } |
edy555 | 0:55201637d936 | 376 | |
edy555 | 0:55201637d936 | 377 | void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s) |
edy555 | 0:55201637d936 | 378 | { |
edy555 | 0:55201637d936 | 379 | NVIC_SetVector(DMA1_Stream4_IRQn, (uint32_t)DMATX_IRQHandler); |
edy555 | 0:55201637d936 | 380 | NVIC_SetVector(DMA1_Stream3_IRQn, (uint32_t)DMARX_IRQHandler); |
edy555 | 0:55201637d936 | 381 | HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn); |
edy555 | 0:55201637d936 | 382 | HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn); |
edy555 | 0:55201637d936 | 383 | //HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, ); |
edy555 | 0:55201637d936 | 384 | } |
edy555 | 0:55201637d936 | 385 | |
edy555 | 0:55201637d936 | 386 | void |
edy555 | 0:55201637d936 | 387 | i2s_init() |
edy555 | 0:55201637d936 | 388 | { |
edy555 | 0:55201637d936 | 389 | __SPI2_CLK_ENABLE(); |
edy555 | 0:55201637d936 | 390 | __DMA1_CLK_ENABLE(); |
edy555 | 0:55201637d936 | 391 | pinmap_pinout(PB_12, PinMap_I2S_WS); |
edy555 | 0:55201637d936 | 392 | pinmap_pinout(PB_13, PinMap_I2S_CK); |
edy555 | 0:55201637d936 | 393 | pinmap_pinout(PB_14, PinMap_I2Sext_SD); |
edy555 | 0:55201637d936 | 394 | pinmap_pinout(PB_15, PinMap_I2S_SD); |
edy555 | 0:55201637d936 | 395 | pin_mode(PB_12, PullUp); |
edy555 | 0:55201637d936 | 396 | pin_mode(PB_13, PullUp); |
edy555 | 0:55201637d936 | 397 | pin_mode(PB_14, PullUp); |
edy555 | 0:55201637d936 | 398 | pin_mode(PB_15, PullUp); |
edy555 | 0:55201637d936 | 399 | if (HAL_DMA_Init(&hdmatx) != HAL_OK) |
edy555 | 0:55201637d936 | 400 | pc.printf("Error:HAL_DMA_Init\n\r"); |
edy555 | 0:55201637d936 | 401 | if (HAL_DMA_Init(&hdmarx) != HAL_OK) |
edy555 | 0:55201637d936 | 402 | pc.printf("Error:HAL_DMA_Init\n\r"); |
edy555 | 0:55201637d936 | 403 | if (HAL_I2S_Init(&hi2s) != HAL_OK) |
edy555 | 0:55201637d936 | 404 | pc.printf("Error:HAL_I2S_Init\n\r"); |
edy555 | 0:55201637d936 | 405 | } |
edy555 | 0:55201637d936 | 406 | |
edy555 | 0:55201637d936 | 407 | void i2sdma_start() |
edy555 | 0:55201637d936 | 408 | { |
edy555 | 0:55201637d936 | 409 | if (HAL_I2SEx_TransmitReceive_DMA(&hi2s, (uint16_t*)cap_buf, (uint16_t*)cap_buf, sizeof(cap_buf)/sizeof(uint16_t)) != HAL_OK) |
edy555 | 0:55201637d936 | 410 | pc.printf("Error:HAL_I2S_Transmit_DMA\n\r"); |
edy555 | 0:55201637d936 | 411 | } |
edy555 | 0:55201637d936 | 412 | |
edy555 | 0:55201637d936 | 413 | static int first = true; |
edy555 | 0:55201637d936 | 414 | |
edy555 | 0:55201637d936 | 415 | uint32_t capbuf_average(int buf) |
edy555 | 0:55201637d936 | 416 | { |
edy555 | 0:55201637d936 | 417 | int32_t acc_i = 0; |
edy555 | 0:55201637d936 | 418 | int32_t acc_q = 0; |
edy555 | 0:55201637d936 | 419 | for (int i = 0; i < CAPTURE_LEN; i += 2){ |
edy555 | 0:55201637d936 | 420 | acc_i += cap_buf[buf][i+1]; |
edy555 | 0:55201637d936 | 421 | acc_q += cap_buf[buf][i]; |
edy555 | 0:55201637d936 | 422 | } |
edy555 | 0:55201637d936 | 423 | acc_i /= CAPTURE_LEN/2; |
edy555 | 0:55201637d936 | 424 | acc_q /= CAPTURE_LEN/2; |
edy555 | 0:55201637d936 | 425 | return __PKHBT(acc_i, acc_q, 16); |
edy555 | 0:55201637d936 | 426 | } |
edy555 | 0:55201637d936 | 427 | |
edy555 | 0:55201637d936 | 428 | uint32_t capbuf_ave; |
edy555 | 0:55201637d936 | 429 | uint32_t decay_ave; |
edy555 | 0:55201637d936 | 430 | |
edy555 | 0:55201637d936 | 431 | void decay_average(uint32_t in) |
edy555 | 0:55201637d936 | 432 | { |
edy555 | 0:55201637d936 | 433 | uint32_t i = __PKHBT(decay_ave, in, 16); |
edy555 | 0:55201637d936 | 434 | uint32_t q = __PKHTB(in, decay_ave, 16); |
edy555 | 3:e6897d74d6bf | 435 | int32_t sum_i = __SMUAD(0x0001000f, i) / 16; |
edy555 | 3:e6897d74d6bf | 436 | int32_t sum_q = __SMUAD(0x0001000f, q) / 16; |
edy555 | 3:e6897d74d6bf | 437 | decay_ave = __PKHBT(sum_i, sum_q, 16); |
edy555 | 0:55201637d936 | 438 | } |
edy555 | 0:55201637d936 | 439 | |
edy555 | 0:55201637d936 | 440 | |
edy555 | 0:55201637d936 | 441 | enum { |
edy555 | 0:55201637d936 | 442 | EVT_NONE = 0, |
edy555 | 0:55201637d936 | 443 | EVT_BUTTON_PRESSED, |
edy555 | 0:55201637d936 | 444 | EVT_HEADPHONE_PLUGGED, |
edy555 | 0:55201637d936 | 445 | EVT_HEADSET_PLUGGED, |
edy555 | 0:55201637d936 | 446 | EVT_UNPLUGGED |
edy555 | 0:55201637d936 | 447 | }; |
edy555 | 0:55201637d936 | 448 | |
edy555 | 0:55201637d936 | 449 | int |
edy555 | 0:55201637d936 | 450 | process_event() |
edy555 | 0:55201637d936 | 451 | { |
edy555 | 0:55201637d936 | 452 | int stat = I2CRead(0x18, 67) & 0x60; |
edy555 | 0:55201637d936 | 453 | int flag = I2CRead(0x18, 44); |
edy555 | 0:55201637d936 | 454 | char *msg = NULL; |
edy555 | 0:55201637d936 | 455 | int evt = 0; |
edy555 | 0:55201637d936 | 456 | if (flag & 0x10) { |
edy555 | 0:55201637d936 | 457 | if (stat == 0x60) { |
edy555 | 0:55201637d936 | 458 | msg = "Headset plugged"; |
edy555 | 0:55201637d936 | 459 | evt = EVT_HEADSET_PLUGGED; |
edy555 | 0:55201637d936 | 460 | } else if (stat == 0x20) { |
edy555 | 0:55201637d936 | 461 | msg = "Headphone plugged"; |
edy555 | 0:55201637d936 | 462 | evt = EVT_HEADPHONE_PLUGGED; |
edy555 | 0:55201637d936 | 463 | } else if (stat == 0x00) { |
edy555 | 0:55201637d936 | 464 | msg = "Unplugged"; |
edy555 | 0:55201637d936 | 465 | evt = EVT_UNPLUGGED; |
edy555 | 0:55201637d936 | 466 | } |
edy555 | 0:55201637d936 | 467 | } else if (flag & 0x20) { |
edy555 | 0:55201637d936 | 468 | msg = "Button pressed"; |
edy555 | 0:55201637d936 | 469 | evt = EVT_BUTTON_PRESSED; |
edy555 | 0:55201637d936 | 470 | } |
edy555 | 0:55201637d936 | 471 | if (msg) |
edy555 | 0:55201637d936 | 472 | pc.printf("%s\r\n", msg); |
edy555 | 0:55201637d936 | 473 | return evt; |
edy555 | 0:55201637d936 | 474 | } |
edy555 | 0:55201637d936 | 475 | |
edy555 | 0:55201637d936 | 476 | enum { |
edy555 | 0:55201637d936 | 477 | MODE_NFM = 0, |
edy555 | 0:55201637d936 | 478 | MODE_AM, |
edy555 | 0:55201637d936 | 479 | MODE_USB, |
edy555 | 0:55201637d936 | 480 | MODE_LSB, |
edy555 | 0:55201637d936 | 481 | MODE_IQ, |
edy555 | 0:55201637d936 | 482 | MODE_NUM |
edy555 | 0:55201637d936 | 483 | }; |
edy555 | 0:55201637d936 | 484 | |
edy555 | 5:75c26157a53a | 485 | int mode = MODE_NFM;//MODE_USB; |
edy555 | 0:55201637d936 | 486 | |
edy555 | 0:55201637d936 | 487 | const char *mode_names[] = { |
edy555 | 0:55201637d936 | 488 | "NFM", "AM", "USB", "LSB", "IQ" |
edy555 | 0:55201637d936 | 489 | }; |
edy555 | 0:55201637d936 | 490 | |
edy555 | 1:457ef59cce95 | 491 | |
edy555 | 1:457ef59cce95 | 492 | void hilbert_transform_test(); |
edy555 | 1:457ef59cce95 | 493 | void pseudo_noise_test(); |
edy555 | 1:457ef59cce95 | 494 | |
edy555 | 1:457ef59cce95 | 495 | |
edy555 | 0:55201637d936 | 496 | int main() |
edy555 | 0:55201637d936 | 497 | { |
edy555 | 0:55201637d936 | 498 | pc.baud(9600); |
edy555 | 0:55201637d936 | 499 | pc.printf("AD9857 DDS IQ Synthesizer v0.0\r\n"); |
edy555 | 0:55201637d936 | 500 | pc.printf("SystemCoreClock: %dHz\r\n", SystemCoreClock); |
edy555 | 0:55201637d936 | 501 | pc.printf("%s\r\n", mode_names[mode]); |
edy555 | 0:55201637d936 | 502 | //i2c.frequency(20000); |
edy555 | 0:55201637d936 | 503 | // pullup I2C bus |
edy555 | 0:55201637d936 | 504 | pin_mode(PB_8, PullUp); |
edy555 | 0:55201637d936 | 505 | pin_mode(PB_9, PullUp); |
edy555 | 0:55201637d936 | 506 | |
edy555 | 0:55201637d936 | 507 | dma_init(); |
edy555 | 0:55201637d936 | 508 | dds_init(); |
edy555 | 0:55201637d936 | 509 | dds_setup(); |
edy555 | 0:55201637d936 | 510 | |
edy555 | 0:55201637d936 | 511 | fmmod_init(&fmmod); |
edy555 | 0:55201637d936 | 512 | |
edy555 | 3:e6897d74d6bf | 513 | cic.s0 = __PKHBT(12, 0, 16); // adjust offset |
edy555 | 1:457ef59cce95 | 514 | //pseudo_noise_test(); |
edy555 | 1:457ef59cce95 | 515 | //interpolate_test(); |
edy555 | 0:55201637d936 | 516 | //hilbert_transform_test(); |
edy555 | 0:55201637d936 | 517 | //ddsdma_start(); |
edy555 | 0:55201637d936 | 518 | |
edy555 | 0:55201637d936 | 519 | first = true; |
edy555 | 0:55201637d936 | 520 | init_tlv320aic3204(); |
edy555 | 0:55201637d936 | 521 | i2s_init(); |
edy555 | 0:55201637d936 | 522 | i2sdma_start(); |
edy555 | 0:55201637d936 | 523 | |
edy555 | 0:55201637d936 | 524 | while (1) { |
edy555 | 0:55201637d936 | 525 | //pc.printf("%08x\r\n", fmmod.vec); |
edy555 | 0:55201637d936 | 526 | //myled = !myled; |
edy555 | 0:55201637d936 | 527 | wait(1); |
edy555 | 0:55201637d936 | 528 | int evt = process_event(); |
edy555 | 0:55201637d936 | 529 | switch(evt) { |
edy555 | 0:55201637d936 | 530 | case EVT_BUTTON_PRESSED: |
edy555 | 0:55201637d936 | 531 | mode = (mode + 1) % MODE_NUM; |
edy555 | 0:55201637d936 | 532 | pc.printf("%s\r\n", mode_names[mode]); |
edy555 | 0:55201637d936 | 533 | break; |
edy555 | 0:55201637d936 | 534 | case EVT_HEADSET_PLUGGED: |
edy555 | 0:55201637d936 | 535 | route_dac_headset(); |
edy555 | 0:55201637d936 | 536 | break; |
edy555 | 0:55201637d936 | 537 | case EVT_UNPLUGGED: |
edy555 | 0:55201637d936 | 538 | case EVT_HEADPHONE_PLUGGED: |
edy555 | 0:55201637d936 | 539 | route_dac_linein(); |
edy555 | 0:55201637d936 | 540 | break; |
edy555 | 0:55201637d936 | 541 | } |
edy555 | 0:55201637d936 | 542 | |
edy555 | 0:55201637d936 | 543 | //pc.printf("%08x %08x\r\n", decay_ave, capbuf_ave); |
edy555 | 0:55201637d936 | 544 | //pc.printf("%02x %02x\r\n", I2CRead(0x18, 67), I2CRead(0x18, 44)); |
edy555 | 3:e6897d74d6bf | 545 | if (pc.readable()) { |
edy555 | 3:e6897d74d6bf | 546 | pc.getc(); |
edy555 | 3:e6897d74d6bf | 547 | uint32_t *buf = (uint32_t *)dma_buf; |
edy555 | 3:e6897d74d6bf | 548 | pc.printf("%08x %08x %08x %08x\r\n", buf[0], buf[1], buf[2], buf[3]); |
edy555 | 3:e6897d74d6bf | 549 | } |
edy555 | 0:55201637d936 | 550 | //pc.printf("%04x %04x\r\n", (uint16_t)fir_buf[0], (uint16_t)fir_buf[1]); |
edy555 | 0:55201637d936 | 551 | //pc.printf("%08x\r\n", *(uint32_t*)cap_buf[0]); |
edy555 | 0:55201637d936 | 552 | } |
edy555 | 0:55201637d936 | 553 | } |
edy555 | 0:55201637d936 | 554 | |
edy555 | 0:55201637d936 | 555 | #if 0 |
edy555 | 0:55201637d936 | 556 | void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) |
edy555 | 0:55201637d936 | 557 | { |
edy555 | 0:55201637d936 | 558 | //myled = 0; |
edy555 | 0:55201637d936 | 559 | } |
edy555 | 0:55201637d936 | 560 | |
edy555 | 0:55201637d936 | 561 | void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) |
edy555 | 0:55201637d936 | 562 | { |
edy555 | 0:55201637d936 | 563 | //myled = 1; |
edy555 | 0:55201637d936 | 564 | } |
edy555 | 0:55201637d936 | 565 | #endif |
edy555 | 0:55201637d936 | 566 | |
edy555 | 0:55201637d936 | 567 | void offset_capture_buffer(uint32_t offset, uint32_t *dst, int dst_len) |
edy555 | 0:55201637d936 | 568 | { |
edy555 | 0:55201637d936 | 569 | int i; |
edy555 | 0:55201637d936 | 570 | for (i = 0; i < dst_len; i += 8) { |
edy555 | 0:55201637d936 | 571 | dst[0] = __QSUB16(dst[0], offset); |
edy555 | 0:55201637d936 | 572 | dst[1] = __QSUB16(dst[1], offset); |
edy555 | 0:55201637d936 | 573 | dst[2] = __QSUB16(dst[2], offset); |
edy555 | 0:55201637d936 | 574 | dst[3] = __QSUB16(dst[3], offset); |
edy555 | 0:55201637d936 | 575 | dst[4] = __QSUB16(dst[4], offset); |
edy555 | 0:55201637d936 | 576 | dst[5] = __QSUB16(dst[5], offset); |
edy555 | 0:55201637d936 | 577 | dst[6] = __QSUB16(dst[6], offset); |
edy555 | 0:55201637d936 | 578 | dst[7] = __QSUB16(dst[7], offset); |
edy555 | 0:55201637d936 | 579 | dst += 8; |
edy555 | 0:55201637d936 | 580 | } |
edy555 | 0:55201637d936 | 581 | } |
edy555 | 0:55201637d936 | 582 | |
edy555 | 0:55201637d936 | 583 | static void |
edy555 | 0:55201637d936 | 584 | mod_fm_func(int buf) |
edy555 | 0:55201637d936 | 585 | { |
edy555 | 0:55201637d936 | 586 | frequency_modulation(&fmmod, (uint32_t*)cap_buf[buf], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t)); |
edy555 | 0:55201637d936 | 587 | } |
edy555 | 0:55201637d936 | 588 | static void |
edy555 | 0:55201637d936 | 589 | mod_am_func(int buf) |
edy555 | 0:55201637d936 | 590 | { |
edy555 | 0:55201637d936 | 591 | amplitude_modulation((uint32_t*)cap_buf[buf], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t)); |
edy555 | 0:55201637d936 | 592 | } |
edy555 | 0:55201637d936 | 593 | |
edy555 | 0:55201637d936 | 594 | static void |
edy555 | 0:55201637d936 | 595 | mod_usb_func(int buf) |
edy555 | 0:55201637d936 | 596 | { |
edy555 | 0:55201637d936 | 597 | hilbert_transform((uint32_t*)cap_buf[buf], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), 1); |
edy555 | 0:55201637d936 | 598 | if (buf) |
edy555 | 0:55201637d936 | 599 | hilbert_transform_save_fir_state((uint32_t*)cap_buf[2]); |
edy555 | 0:55201637d936 | 600 | } |
edy555 | 0:55201637d936 | 601 | |
edy555 | 0:55201637d936 | 602 | static void |
edy555 | 0:55201637d936 | 603 | mod_lsb_func(int buf) |
edy555 | 0:55201637d936 | 604 | { |
edy555 | 0:55201637d936 | 605 | hilbert_transform((uint32_t*)cap_buf[buf], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), -1); |
edy555 | 0:55201637d936 | 606 | if (buf) |
edy555 | 0:55201637d936 | 607 | hilbert_transform_save_fir_state((uint32_t*)cap_buf[2]); |
edy555 | 0:55201637d936 | 608 | } |
edy555 | 0:55201637d936 | 609 | |
edy555 | 0:55201637d936 | 610 | static void |
edy555 | 0:55201637d936 | 611 | mod_raw_func(int buf) |
edy555 | 0:55201637d936 | 612 | { |
edy555 | 0:55201637d936 | 613 | memcpy(fir_buf, cap_buf[buf], sizeof fir_buf); |
edy555 | 0:55201637d936 | 614 | } |
edy555 | 0:55201637d936 | 615 | |
edy555 | 0:55201637d936 | 616 | void (*mod_funcs[])(int) = { |
edy555 | 0:55201637d936 | 617 | mod_fm_func, |
edy555 | 0:55201637d936 | 618 | mod_am_func, |
edy555 | 0:55201637d936 | 619 | mod_usb_func, |
edy555 | 0:55201637d936 | 620 | mod_lsb_func, |
edy555 | 0:55201637d936 | 621 | mod_raw_func |
edy555 | 0:55201637d936 | 622 | }; |
edy555 | 0:55201637d936 | 623 | |
edy555 | 0:55201637d936 | 624 | void modulate_buffer_half(int buf) |
edy555 | 0:55201637d936 | 625 | { |
edy555 | 0:55201637d936 | 626 | myled = 1; |
edy555 | 0:55201637d936 | 627 | offset_capture_buffer(decay_ave, (uint32_t*)cap_buf[buf], sizeof cap_buf[0] / sizeof(uint32_t)); |
edy555 | 0:55201637d936 | 628 | //offset_capture_buffer(0x00780088, (uint32_t*)cap_buf[buf], sizeof cap_buf[0] / sizeof(uint32_t)); |
edy555 | 0:55201637d936 | 629 | myled = 0; |
edy555 | 0:55201637d936 | 630 | myled = 1; |
edy555 | 0:55201637d936 | 631 | (*mod_funcs[mode])(buf); |
edy555 | 0:55201637d936 | 632 | myled = 0; |
edy555 | 0:55201637d936 | 633 | myled = 1; |
edy555 | 0:55201637d936 | 634 | int cic_len = sizeof(cic_buf)/sizeof(uint32_t); |
edy555 | 0:55201637d936 | 635 | fir_resample_x4((uint32_t*)fir_state, (uint32_t*)cic_buf, cic_len); |
edy555 | 0:55201637d936 | 636 | myled = 0; |
edy555 | 0:55201637d936 | 637 | myled = 1; |
edy555 | 0:55201637d936 | 638 | cic_interpolate_x10(&cic, (uint32_t*)cic_buf, cic_len, (uint32_t*)dma_buf[buf]); |
edy555 | 0:55201637d936 | 639 | myled = 0; |
edy555 | 0:55201637d936 | 640 | } |
edy555 | 0:55201637d936 | 641 | |
edy555 | 0:55201637d936 | 642 | void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s) |
edy555 | 0:55201637d936 | 643 | { |
edy555 | 0:55201637d936 | 644 | capbuf_ave = capbuf_average(0); |
edy555 | 0:55201637d936 | 645 | decay_average(capbuf_ave); |
edy555 | 0:55201637d936 | 646 | modulate_buffer_half(0); |
edy555 | 0:55201637d936 | 647 | if (first) { |
edy555 | 0:55201637d936 | 648 | ddsdma_start(); |
edy555 | 0:55201637d936 | 649 | first = false; |
edy555 | 0:55201637d936 | 650 | } |
edy555 | 0:55201637d936 | 651 | } |
edy555 | 0:55201637d936 | 652 | |
edy555 | 0:55201637d936 | 653 | void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) |
edy555 | 0:55201637d936 | 654 | { |
edy555 | 1:457ef59cce95 | 655 | capbuf_ave = capbuf_average(1); |
edy555 | 0:55201637d936 | 656 | decay_average(capbuf_ave); |
edy555 | 0:55201637d936 | 657 | modulate_buffer_half(1); |
edy555 | 0:55201637d936 | 658 | } |
edy555 | 1:457ef59cce95 | 659 | |
edy555 | 1:457ef59cce95 | 660 | void |
edy555 | 1:457ef59cce95 | 661 | pseudo_noise_test() |
edy555 | 1:457ef59cce95 | 662 | { |
edy555 | 1:457ef59cce95 | 663 | #define RAND(N) ((((float)rand() / RAND_MAX) * 2 * N) - N) |
edy555 | 1:457ef59cce95 | 664 | int ampl = 10000; |
edy555 | 1:457ef59cce95 | 665 | for (int i = 0; i < CAPTURE_LEN/2; i++){ |
edy555 | 1:457ef59cce95 | 666 | cap_buf[0][i*2] = RAND(ampl); |
edy555 | 1:457ef59cce95 | 667 | cap_buf[0][i*2+1] = RAND(ampl); // Rch |
edy555 | 1:457ef59cce95 | 668 | cap_buf[1][i*2] = RAND(ampl); // Lch |
edy555 | 1:457ef59cce95 | 669 | cap_buf[1][i*2+1] = RAND(ampl); // Rch |
edy555 | 1:457ef59cce95 | 670 | } |
edy555 | 1:457ef59cce95 | 671 | modulate_buffer_half(0); |
edy555 | 1:457ef59cce95 | 672 | modulate_buffer_half(1); |
edy555 | 1:457ef59cce95 | 673 | modulate_buffer_half(0); |
edy555 | 1:457ef59cce95 | 674 | modulate_buffer_half(1); |
edy555 | 1:457ef59cce95 | 675 | ddsdma_start(); |
edy555 | 1:457ef59cce95 | 676 | pc.printf("Pseudo noise test\r\n"); |
edy555 | 1:457ef59cce95 | 677 | while(1); |
edy555 | 1:457ef59cce95 | 678 | /* no reach */ |
edy555 | 1:457ef59cce95 | 679 | } |
edy555 | 1:457ef59cce95 | 680 | |
edy555 | 1:457ef59cce95 | 681 | void |
edy555 | 1:457ef59cce95 | 682 | hilbert_transform_test() |
edy555 | 1:457ef59cce95 | 683 | { |
edy555 | 1:457ef59cce95 | 684 | #if 1 |
edy555 | 1:457ef59cce95 | 685 | int freq = 800; |
edy555 | 1:457ef59cce95 | 686 | int ampl = 3000; |
edy555 | 1:457ef59cce95 | 687 | int rate = 48000; |
edy555 | 1:457ef59cce95 | 688 | for (int i = 0; i < CAPTURE_LEN; i++){ |
edy555 | 1:457ef59cce95 | 689 | cap_buf[0][i*2] = sin(2*3.141592 * i * freq / rate) * ampl; // Lch |
edy555 | 1:457ef59cce95 | 690 | cap_buf[0][i*2+1] = 0;//sin(2*3.141592 * i * freq / rate) * ampl; // Rch |
edy555 | 1:457ef59cce95 | 691 | } |
edy555 | 1:457ef59cce95 | 692 | #endif |
edy555 | 1:457ef59cce95 | 693 | int cic_len = sizeof(cic_buf)/sizeof(uint32_t); |
edy555 | 1:457ef59cce95 | 694 | hilbert_transform_save_fir_state((uint32_t*)cap_buf[1]); |
edy555 | 1:457ef59cce95 | 695 | hilbert_transform((uint32_t*)cap_buf[0], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), 1); |
edy555 | 1:457ef59cce95 | 696 | hilbert_transform_save_fir_state((uint32_t*)cap_buf[1]); |
edy555 | 1:457ef59cce95 | 697 | fir_resample_x4((uint32_t*)fir_state, (uint32_t*)cic_buf, cic_len); |
edy555 | 1:457ef59cce95 | 698 | cic_interpolate_x10(&cic, (uint32_t*)cic_buf, cic_len, (uint32_t*)dma_buf[0]); |
edy555 | 1:457ef59cce95 | 699 | |
edy555 | 1:457ef59cce95 | 700 | hilbert_transform((uint32_t*)cap_buf[0], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), 1); |
edy555 | 1:457ef59cce95 | 701 | hilbert_transform_save_fir_state((uint32_t*)cap_buf[1]); |
edy555 | 1:457ef59cce95 | 702 | fir_resample_x4((uint32_t*)fir_state, (uint32_t*)cic_buf, cic_len); |
edy555 | 1:457ef59cce95 | 703 | cic_interpolate_x10(&cic, (uint32_t*)cic_buf, cic_len, (uint32_t*)dma_buf[1]); |
edy555 | 1:457ef59cce95 | 704 | |
edy555 | 1:457ef59cce95 | 705 | hilbert_transform((uint32_t*)cap_buf[0], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), 1); |
edy555 | 1:457ef59cce95 | 706 | hilbert_transform_save_fir_state((uint32_t*)cap_buf[1]); |
edy555 | 1:457ef59cce95 | 707 | fir_resample_x4((uint32_t*)fir_state, (uint32_t*)cic_buf, cic_len); |
edy555 | 1:457ef59cce95 | 708 | cic_interpolate_x10(&cic, (uint32_t*)cic_buf, cic_len, (uint32_t*)dma_buf[0]); |
edy555 | 1:457ef59cce95 | 709 | |
edy555 | 1:457ef59cce95 | 710 | hilbert_transform((uint32_t*)cap_buf[0], (uint32_t*)fir_buf, sizeof fir_buf / sizeof(uint32_t), 1); |
edy555 | 1:457ef59cce95 | 711 | hilbert_transform_save_fir_state((uint32_t*)cap_buf[1]); |
edy555 | 1:457ef59cce95 | 712 | fir_resample_x4((uint32_t*)fir_state, (uint32_t*)cic_buf, cic_len); |
edy555 | 1:457ef59cce95 | 713 | cic_interpolate_x10(&cic, (uint32_t*)cic_buf, cic_len, (uint32_t*)dma_buf[1]); |
edy555 | 1:457ef59cce95 | 714 | #if 0 |
edy555 | 1:457ef59cce95 | 715 | for (int i = 0; i < 20; i++){ |
edy555 | 1:457ef59cce95 | 716 | pc.printf("%d, ", cic_buf[i*2]); |
edy555 | 1:457ef59cce95 | 717 | } |
edy555 | 1:457ef59cce95 | 718 | pc.printf("\n\r"); |
edy555 | 1:457ef59cce95 | 719 | #endif |
edy555 | 1:457ef59cce95 | 720 | #if 1 |
edy555 | 1:457ef59cce95 | 721 | for (int i = 0; i < 30; i += 2) { |
edy555 | 1:457ef59cce95 | 722 | pc.printf("%d:%d ", dma_buf[0][i], dma_buf[0][i+1]); |
edy555 | 1:457ef59cce95 | 723 | } |
edy555 | 1:457ef59cce95 | 724 | pc.printf("\n\r"); |
edy555 | 1:457ef59cce95 | 725 | int acc_i = 0; |
edy555 | 1:457ef59cce95 | 726 | int acc_q = 0; |
edy555 | 1:457ef59cce95 | 727 | for (int i = 0; i < DMA_DATALEN; i += 2){ |
edy555 | 1:457ef59cce95 | 728 | acc_i += dma_buf[0][i ]; |
edy555 | 1:457ef59cce95 | 729 | acc_q += dma_buf[0][i+1]; |
edy555 | 1:457ef59cce95 | 730 | } |
edy555 | 1:457ef59cce95 | 731 | pc.printf("dma acc %d %d\n\r", acc_i, acc_q); |
edy555 | 1:457ef59cce95 | 732 | #endif |
edy555 | 1:457ef59cce95 | 733 | } |
edy555 | 1:457ef59cce95 | 734 |