codec.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. #include <rthw.h>
  2. #include <rtthread.h>
  3. #include "stm32f10x.h"
  4. #include "codec.h"
  5. #define CODEC_MASTER_MODE 0
  6. /*
  7. SCLK PA5 SPI1_SCK
  8. SDIN PA7 SPI1_MOSI
  9. CSB PC5
  10. */
  11. #define CODEC_CSB_PORT GPIOC
  12. #define CODEC_CSB_PIN GPIO_Pin_5
  13. #define codec_set_csb() do { CODEC_CSB_PORT->BSRR = CODEC_CSB_PIN; } while (0)
  14. #define codec_reset_csb() do { CODEC_CSB_PORT->BRR = CODEC_CSB_PIN; } while (0)
  15. void vol(uint16_t v);
  16. static void codec_send(rt_uint16_t s_data);
  17. #define DATA_NODE_MAX 5
  18. /* data node for Tx Mode */
  19. struct codec_data_node
  20. {
  21. rt_uint16_t *data_ptr;
  22. rt_size_t data_size;
  23. };
  24. struct codec_device
  25. {
  26. /* inherit from rt_device */
  27. struct rt_device parent;
  28. /* pcm data list */
  29. struct codec_data_node data_list[DATA_NODE_MAX];
  30. rt_uint16_t read_index, put_index;
  31. /* transmitted offset of current data node */
  32. rt_size_t offset;
  33. };
  34. struct codec_device codec;
  35. static uint16_t r06 = REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV2 | BCLK_DIV8;
  36. static uint16_t zero = 0;
  37. static void NVIC_Configuration(void)
  38. {
  39. NVIC_InitTypeDef NVIC_InitStructure;
  40. /* SPI2 IRQ Channel configuration */
  41. NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
  42. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  43. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  44. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  45. NVIC_Init(&NVIC_InitStructure);
  46. /* DMA1 IRQ Channel configuration */
  47. NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
  48. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  49. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  50. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  51. NVIC_Init(&NVIC_InitStructure);
  52. }
  53. static void GPIO_Configuration(void)
  54. {
  55. GPIO_InitTypeDef GPIO_InitStructure;
  56. /* Disable the JTAG interface and enable the SWJ interface */
  57. GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
  58. /* PC5 CODEC CS */
  59. GPIO_InitStructure.GPIO_Pin = CODEC_CSB_PIN;
  60. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  61. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  62. GPIO_Init(CODEC_CSB_PORT, &GPIO_InitStructure);
  63. #if CODEC_MASTER_MODE
  64. // WS, CK
  65. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;
  66. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  67. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  68. GPIO_Init(GPIOB, &GPIO_InitStructure);
  69. // SD
  70. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  71. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  72. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  73. GPIO_Init(GPIOB, &GPIO_InitStructure);
  74. #else
  75. /* Configure SPI2 pins: CK, WS and SD */
  76. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15;
  77. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  78. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  79. GPIO_Init(GPIOB, &GPIO_InitStructure);
  80. #endif
  81. #ifdef CODEC_USE_MCO
  82. /* MCO configure */
  83. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  84. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  85. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  86. GPIO_Init(GPIOA,&GPIO_InitStructure);
  87. RCC_MCOConfig(RCC_MCO_HSE);
  88. #endif
  89. }
  90. static void DMA_Configuration(rt_uint32_t addr, rt_size_t size)
  91. {
  92. DMA_InitTypeDef DMA_InitStructure;
  93. /* DMA1 Channel2 configuration ----------------------------------------------*/
  94. DMA_Cmd(DMA1_Channel5, DISABLE);
  95. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(SPI2->DR));
  96. DMA_InitStructure.DMA_MemoryBaseAddr = (u32) addr;
  97. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  98. DMA_InitStructure.DMA_BufferSize = size;
  99. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  100. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  101. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  102. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  103. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  104. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  105. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  106. #if CODEC_MASTER_MODE
  107. while ((SPI2->SR & SPI_SR_CHSIDE) == 1);
  108. DMA_ClearFlag(DMA1_FLAG_TC5);
  109. #endif
  110. DMA_Init(DMA1_Channel5, &DMA_InitStructure);
  111. /* Enable SPI2 DMA Tx request */
  112. SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
  113. DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
  114. DMA_Cmd(DMA1_Channel5, ENABLE);
  115. }
  116. #if CODEC_MASTER_MODE
  117. static void DMA_ZeroFill_I2S()
  118. {
  119. DMA_InitTypeDef DMA_InitStructure;
  120. /* DMA1 Channel2 configuration ----------------------------------------------*/
  121. DMA_Cmd(DMA1_Channel5, DISABLE);
  122. DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, DISABLE);
  123. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&(SPI2->DR));
  124. DMA_InitStructure.DMA_MemoryBaseAddr = (u32) &zero;
  125. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  126. DMA_InitStructure.DMA_BufferSize = 1;
  127. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  128. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  129. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  130. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  131. DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  132. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  133. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  134. DMA_Init(DMA1_Channel5, &DMA_InitStructure);
  135. /* Enable SPI2 DMA Tx request */
  136. SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
  137. //DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
  138. DMA_Cmd(DMA1_Channel5, ENABLE);
  139. }
  140. #endif
  141. static void I2S_Configuration(void)
  142. {
  143. I2S_InitTypeDef I2S_InitStructure;
  144. /* I2S peripheral configuration */
  145. I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
  146. I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
  147. I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
  148. I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_44k;
  149. I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
  150. /* I2S2 configuration */
  151. #if CODEC_MASTER_MODE
  152. I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveTx;
  153. #else
  154. I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
  155. #endif
  156. I2S_Init(SPI2, &I2S_InitStructure);
  157. }
  158. uint8_t SPI_WriteByte(unsigned char data)
  159. {
  160. //Wait until the transmit buffer is empty
  161. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  162. // Send the byte
  163. SPI_I2S_SendData(SPI1, data);
  164. //Wait until a data is received
  165. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
  166. // Get the received data
  167. data = SPI_I2S_ReceiveData(SPI1);
  168. // Return the shifted data
  169. return data;
  170. }
  171. static void codec_send(rt_uint16_t s_data)
  172. {
  173. codec_reset_csb();
  174. SPI_WriteByte((s_data >> 8) & 0xFF);
  175. SPI_WriteByte(s_data & 0xFF);
  176. codec_set_csb();
  177. }
  178. static rt_err_t codec_init(rt_device_t dev)
  179. {
  180. codec_send(REG_SOFTWARE_RESET);
  181. // 1.5x boost power up sequence.
  182. // Mute all outputs.
  183. codec_send(REG_LOUT1_VOL | LOUT1MUTE);
  184. codec_send(REG_ROUT1_VOL | ROUT1MUTE);
  185. codec_send(REG_LOUT2_VOL | LOUT2MUTE);
  186. codec_send(REG_ROUT2_VOL | ROUT2MUTE);
  187. // Enable unused output chosen from L/ROUT2, OUT3 or OUT4.
  188. codec_send(REG_POWER_MANAGEMENT3 | OUT4EN);
  189. // Set BUFDCOPEN=1 and BUFIOEN=1 in register R1
  190. codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN);
  191. // Set SPKBOOST=1 in register R49.
  192. codec_send(REG_OUTPUT | SPKBOOST);
  193. // Set VMIDSEL[1:0] to required value in register R1.
  194. codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K);
  195. // Set L/RMIXEN=1 and DACENL/R=1 in register R3.
  196. codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR);
  197. // Set BIASEN=1 in register R1.
  198. codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN);
  199. // Set L/ROUT2EN=1 in register R3.
  200. codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR | LOUT2EN | ROUT2EN);
  201. // Enable other mixers as required.
  202. // Enable other outputs as required.
  203. codec_send(REG_POWER_MANAGEMENT2 | LOUT1EN | ROUT1EN | BOOSTENL | BOOSTENR | INPPGAENL | INPPGAENR);
  204. // Digital inferface setup.
  205. codec_send(REG_AUDIO_INTERFACE | BCP_NORMAL | LRP_NORMAL | WL_16BITS | FMT_I2S);
  206. // PLL setup.
  207. // fs = 44.1KHz / 256fs = 11.2896MHz
  208. // F_PLL = 11.2896MHz * 4 * 2 = 90.3168MHz
  209. // R = 90.3168MHz / 12.288MHz = 7.35
  210. // PLL_N = 7
  211. // PLL_K = 5872026 (5921370 for STM32's 44.117KHz fs generated from 72MHz clock)
  212. codec_send(REG_PLL_N | 7);
  213. codec_send(REG_PLL_K1 | 0x16);
  214. codec_send(REG_PLL_K2 | 0x12D);
  215. codec_send(REG_PLL_K3 | 0x5A);
  216. codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN | PLLEN);
  217. codec_send(r06);
  218. // Enable DAC 128x oversampling.
  219. codec_send(REG_DAC | DACOSR128);
  220. // Set LOUT2/ROUT2 in BTL operation.
  221. codec_send(REG_BEEP | INVROUT2);
  222. // Set output volume to -22dB.
  223. vol(20);
  224. return RT_EOK;
  225. }
  226. // Exported functions
  227. #include <finsh.h>
  228. void vol(uint16_t v)
  229. {
  230. v = (v & VOL_MASK) << VOL_POS;
  231. codec_send(REG_LOUT1_VOL | v);
  232. codec_send(REG_ROUT1_VOL | HPVU | v);
  233. codec_send(REG_LOUT2_VOL | v);
  234. codec_send(REG_ROUT2_VOL | SPKVU | v);
  235. }
  236. void eq1(uint8_t freq, uint8_t gain, uint8_t mode)
  237. {
  238. codec_send(REG_EQ1 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (mode ? EQ3DMODE_DAC : EQ3DMODE_ADC));
  239. }
  240. void eq2(uint8_t freq, uint8_t gain, uint8_t bw)
  241. {
  242. codec_send(REG_EQ2 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ2BW_WIDE : EQ2BW_NARROW));
  243. }
  244. void eq3(uint8_t freq, uint8_t gain, uint8_t bw)
  245. {
  246. codec_send(REG_EQ3 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ3BW_WIDE : EQ3BW_NARROW));
  247. }
  248. void eq4(uint8_t freq, uint8_t gain, uint8_t bw)
  249. {
  250. codec_send(REG_EQ4 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS) | (bw ? EQ4BW_WIDE : EQ4BW_NARROW));
  251. }
  252. void eq5(uint8_t freq, uint8_t gain)
  253. {
  254. codec_send(REG_EQ2 | ((freq & EQC_MASK) << EQC_POS) | ((gain & EQG_MASK) << EQG_POS));
  255. }
  256. void eq3d(uint8_t depth)
  257. {
  258. codec_send(REG_3D | ((depth & DEPTH3D_MASK) << DEPTH3D_POS));
  259. }
  260. void sample_rate(uint8_t sr)
  261. {
  262. if (sr == 44)
  263. {
  264. codec_send(REG_ADDITIONAL | SR_48KHZ);
  265. r06 = REG_CLOCK_GEN | CLKSEL_PLL | MCLK_DIV2 | BCLK_DIV8 | (r06 & MS);
  266. codec_send(r06);
  267. }
  268. else
  269. {
  270. switch (sr)
  271. {
  272. case 8:
  273. codec_send(REG_ADDITIONAL | SR_8KHZ);
  274. r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV6 | BCLK_DIV8 | (r06 & MS);
  275. break;
  276. case 12:
  277. codec_send(REG_ADDITIONAL | SR_12KHZ);
  278. r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV4 | BCLK_DIV8 | (r06 & MS);
  279. break;
  280. case 16:
  281. codec_send(REG_ADDITIONAL | SR_16KHZ);
  282. r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV3 | BCLK_DIV8 | (r06 & MS);
  283. break;
  284. case 24:
  285. codec_send(REG_ADDITIONAL | SR_24KHZ);
  286. r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV2 | BCLK_DIV8 | (r06 & MS);
  287. break;
  288. case 32:
  289. codec_send(REG_ADDITIONAL | SR_32KHZ);
  290. r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1_5 | BCLK_DIV8 | (r06 & MS);
  291. break;
  292. case 48:
  293. codec_send(REG_ADDITIONAL | SR_48KHZ);
  294. r06 = REG_CLOCK_GEN | CLKSEL_MCLK | MCLK_DIV1 | BCLK_DIV8 | (r06 & MS);
  295. break;
  296. default:
  297. return;
  298. }
  299. codec_send(r06);
  300. }
  301. }
  302. FINSH_FUNCTION_EXPORT(vol, Set volume);
  303. FINSH_FUNCTION_EXPORT(eq1, Set EQ1(Cut-off, Gain, Mode));
  304. FINSH_FUNCTION_EXPORT(eq2, Set EQ2(Center, Gain, Bandwidth));
  305. FINSH_FUNCTION_EXPORT(eq3, Set EQ3(Center, Gain, Bandwidth));
  306. FINSH_FUNCTION_EXPORT(eq4, Set EQ4(Center, Gain, Bandwidth));
  307. FINSH_FUNCTION_EXPORT(eq5, Set EQ5(Cut-off, Gain));
  308. FINSH_FUNCTION_EXPORT(eq3d, Set 3D(Depth));
  309. FINSH_FUNCTION_EXPORT(sample_rate, Set sample rate);
  310. static rt_err_t codec_open(rt_device_t dev, rt_uint16_t oflag)
  311. {
  312. /* enable I2S */
  313. I2S_Cmd(SPI2, ENABLE);
  314. #if CODEC_MASTER_MODE
  315. DMA_ZeroFill_I2S();
  316. r06 |= MS;
  317. codec_send(r06);
  318. #endif
  319. return RT_EOK;
  320. }
  321. static rt_err_t codec_close(rt_device_t dev)
  322. {
  323. /* interrupt mode */
  324. if (dev->flag & RT_DEVICE_FLAG_INT_TX)
  325. {
  326. /* Disable the I2S2 */
  327. I2S_Cmd(SPI2, DISABLE);
  328. }
  329. #if CODEC_MASTER_MODE
  330. else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
  331. {
  332. DMA_Cmd(DMA1_Channel5, DISABLE);
  333. I2S_Cmd(SPI2, DISABLE);
  334. r06 &= ~MS;
  335. codec_send(r06);
  336. }
  337. #endif
  338. /* remove all data node */
  339. return RT_EOK;
  340. }
  341. static rt_err_t codec_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  342. {
  343. /* rate control */
  344. return RT_EOK;
  345. }
  346. static rt_size_t codec_write(rt_device_t dev, rt_off_t pos,
  347. const void* buffer, rt_size_t size)
  348. {
  349. struct codec_device* device;
  350. struct codec_data_node* node;
  351. rt_uint32_t level;
  352. rt_uint16_t next_index;
  353. device = (struct codec_device*) dev;
  354. RT_ASSERT(device != RT_NULL);
  355. next_index = device->put_index + 1;
  356. if (next_index >= DATA_NODE_MAX)
  357. next_index = 0;
  358. /* check data_list full */
  359. if (next_index == device->read_index)
  360. {
  361. rt_set_errno(-RT_EFULL);
  362. return 0;
  363. }
  364. level = rt_hw_interrupt_disable();
  365. node = &device->data_list[device->put_index];
  366. device->put_index = next_index;
  367. // rt_kprintf("+\n");
  368. /* set node attribute */
  369. node->data_ptr = (rt_uint16_t*) buffer;
  370. node->data_size = size >> 1; /* size is byte unit, convert to half word unit */
  371. next_index = device->read_index + 1;
  372. if (next_index >= DATA_NODE_MAX)
  373. next_index = 0;
  374. /* check data list whether is empty */
  375. if (next_index == device->put_index)
  376. {
  377. if (dev->flag & RT_DEVICE_FLAG_INT_TX)
  378. {
  379. device->offset = 0;
  380. /* enable I2S interrupt */
  381. SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);
  382. }
  383. else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
  384. {
  385. DMA_Configuration((rt_uint32_t) node->data_ptr, node->data_size);
  386. }
  387. }
  388. rt_hw_interrupt_enable(level);
  389. return size;
  390. }
  391. rt_err_t codec_hw_init(void)
  392. {
  393. rt_device_t dev;
  394. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
  395. RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  396. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  397. NVIC_Configuration();
  398. GPIO_Configuration();
  399. I2S_Configuration();
  400. dev = (rt_device_t) &codec;
  401. dev->type = RT_Device_Class_Sound;
  402. dev->rx_indicate = RT_NULL;
  403. dev->tx_complete = RT_NULL;
  404. dev->init = codec_init;
  405. dev->open = codec_open;
  406. dev->close = codec_close;
  407. dev->read = RT_NULL;
  408. dev->write = codec_write;
  409. dev->control = codec_control;
  410. dev->private = RT_NULL;
  411. /* set read_index and put index to 0 */
  412. codec.read_index = 0;
  413. codec.put_index = 0;
  414. /* unselect */
  415. codec_set_csb();
  416. /* register the device */
  417. return rt_device_register(&codec.parent, "snd", RT_DEVICE_FLAG_WRONLY | RT_DEVICE_FLAG_DMA_TX);
  418. }
  419. void codec_isr()
  420. {
  421. struct codec_data_node* node;
  422. node = &codec.data_list[codec.read_index]; /* get current data node */
  423. if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_TXE) == SET)
  424. {
  425. SPI_I2S_SendData(SPI2, node->data_ptr[codec.offset++]);
  426. }
  427. if (codec.offset == node->data_size)
  428. {
  429. /* move to next node */
  430. rt_uint16_t next_index;
  431. next_index = codec.read_index + 1;
  432. if (next_index >= DATA_NODE_MAX)
  433. next_index = 0;
  434. /* notify transmitted complete. */
  435. if (codec.parent.tx_complete != RT_NULL)
  436. {
  437. codec.parent.tx_complete(&codec.parent,
  438. codec.data_list[codec.read_index].data_ptr);
  439. rt_kprintf("-\n");
  440. }
  441. codec.offset = 0;
  442. codec.read_index = next_index;
  443. if (next_index == codec.put_index)
  444. {
  445. /* no data on the list, disable I2S interrupt */
  446. SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
  447. rt_kprintf("*\n");
  448. }
  449. }
  450. }
  451. void codec_dma_isr()
  452. {
  453. /* switch to next buffer */
  454. rt_uint16_t next_index;
  455. void* data_ptr;
  456. next_index = codec.read_index + 1;
  457. if (next_index >= DATA_NODE_MAX)
  458. next_index = 0;
  459. /* save current data pointer */
  460. data_ptr = codec.data_list[codec.read_index].data_ptr;
  461. codec.read_index = next_index;
  462. if (next_index != codec.put_index)
  463. {
  464. /* enable next dma request */
  465. DMA_Configuration((rt_uint32_t) codec.data_list[codec.read_index].data_ptr, codec.data_list[codec.read_index].data_size);
  466. }
  467. else
  468. {
  469. #if CODEC_MASTER_MODE
  470. DMA_ZeroFill_I2S();
  471. #endif
  472. rt_kprintf("*\n");
  473. }
  474. /* notify transmitted complete. */
  475. if (codec.parent.tx_complete != RT_NULL)
  476. {
  477. codec.parent.tx_complete(&codec.parent, data_ptr);
  478. // rt_kprintf("-\n");
  479. }
  480. }