codec.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. #include <rthw.h>
  2. #include <rtthread.h>
  3. #include "stm32f10x.h"
  4. /*
  5. SCLK PA5 SPI1_SCK
  6. SDIN PA7 SPI1_MOSI
  7. CSB PC5
  8. */
  9. #define wm_csb_0 GPIO_ResetBits(GPIOC,GPIO_Pin_5)
  10. #define wm_csb_1 GPIO_SetBits(GPIOC,GPIO_Pin_5)
  11. #define DATA_NODE_MAX 5
  12. /* data node for Tx Mode */
  13. struct wm8753_data_node
  14. {
  15. rt_uint16_t *data_ptr;
  16. rt_size_t data_size;
  17. };
  18. struct wm8753_device
  19. {
  20. /* inherit from rt_device */
  21. struct rt_device parent;
  22. /* pcm data list */
  23. struct wm8753_data_node data_list[DATA_NODE_MAX];
  24. rt_uint16_t read_index, put_index;
  25. /* transmitted offset of current data node */
  26. rt_size_t offset;
  27. };
  28. struct wm8753_device wm8753;
  29. static void NVIC_Configuration(void)
  30. {
  31. NVIC_InitTypeDef NVIC_InitStructure;
  32. /* SPI2 IRQ Channel configuration */
  33. NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
  34. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  35. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  36. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  37. NVIC_Init(&NVIC_InitStructure);
  38. /* DMA1 IRQ Channel configuration */
  39. NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
  40. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  41. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  42. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  43. NVIC_Init(&NVIC_InitStructure);
  44. }
  45. static void GPIO_Configuration(void)
  46. {
  47. GPIO_InitTypeDef GPIO_InitStructure;
  48. /* Disable the JTAG interface and enable the SWJ interface */
  49. GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
  50. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
  51. /* PC5 CODEC CS */
  52. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  53. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  54. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  55. GPIO_Init(GPIOC,&GPIO_InitStructure);
  56. /* Configure SPI2 pins: CK, WS and SD */
  57. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15;
  58. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  59. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  60. GPIO_Init(GPIOB, &GPIO_InitStructure);
  61. #if 0
  62. /* MCO configure */
  63. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  64. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  65. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  66. GPIO_Init(GPIOA,&GPIO_InitStructure);
  67. RCC_MCOConfig(RCC_MCO_HSE);
  68. #endif
  69. }
  70. #define SPI2_DR_Address 0x4000380C
  71. static void DMA_Configuration(rt_uint32_t addr, rt_size_t size)
  72. {
  73. DMA_InitTypeDef DMA_InitStructure;
  74. /* DMA1 Channel2 configuration ----------------------------------------------*/
  75. DMA_Cmd(DMA1_Channel5, DISABLE);
  76. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SPI2_DR_Address;
  77. DMA_InitStructure.DMA_MemoryBaseAddr = (u32)addr;
  78. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  79. DMA_InitStructure.DMA_BufferSize = size;
  80. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  81. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  82. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  83. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  84. DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
  85. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  86. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  87. DMA_Init(DMA1_Channel5, &DMA_InitStructure);
  88. /* Enable SPI2 DMA Tx request */
  89. SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
  90. DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
  91. DMA_Cmd(DMA1_Channel5, ENABLE);
  92. }
  93. static void I2S_Configuration(void)
  94. {
  95. I2S_InitTypeDef I2S_InitStructure;
  96. /* I2S peripheral configuration */
  97. I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
  98. I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
  99. I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
  100. I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_44k;
  101. I2S_InitStructure.I2S_CPOL = I2S_CPOL_High;// I2S_CPOL_Low
  102. /* I2S2 Master Transmitter to I2S3 Slave Receiver communication -----------*/
  103. /* I2S2 configuration */
  104. I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;//I2S_Mode_MasterTx I2S_Mode_SlaveTx
  105. I2S_Init(SPI2, &I2S_InitStructure);
  106. }
  107. unsigned char SPI_WriteByte(unsigned char data)
  108. {
  109. unsigned char Data = 0;
  110. //Wait until the transmit buffer is empty
  111. while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
  112. // Send the byte
  113. SPI_I2S_SendData(SPI1,data);
  114. //Wait until a data is received
  115. while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET);
  116. // Get the received data
  117. Data = SPI_I2S_ReceiveData(SPI1);
  118. // Return the shifted data
  119. return Data;
  120. }
  121. void wm8753_send(rt_uint16_t s_data)
  122. {
  123. wm_csb_0;
  124. SPI_WriteByte( (s_data>>8)&0xFF );
  125. SPI_WriteByte( s_data&0xFF );
  126. wm_csb_1;
  127. }
  128. static rt_err_t wm8753_init (rt_device_t dev)
  129. {
  130. wm8753_send(0<<9 | 0xFF); // reset
  131. /* POWER manager */
  132. wm8753_send(1<<9 | (1<<8) | (0<<7) | (0<<6) | (0<<5) | (1<<4) | (1<<3) | (1<<2) | 2 );//电源设置
  133. wm8753_send(2<<9 | (1<<8) | (1<<7) | (1<<5) | (1<<4) | (1<<3) | (1<<2) ); // 打开电源 耳机输出
  134. wm8753_send(3<<9 | (0<<8) | (0<<7) | (1<<6) | (1<<5) | (1<<3) | (1<<2) | (1<<1) | 1 ); // 喇叭输出和DAC
  135. /* IIS DAC test */
  136. wm8753_send(4<<9 | (0<<7) | (2<<3) );//IIS 16BIT
  137. // 12.288/3/8=512K
  138. wm8753_send(6<<9 | (0<<5) | (3<<2)| 0);//0: slave 1: master | (3<<5) | (3<<2)
  139. wm8753_send(43<<9 | (1<<4) );//INVROUT2
  140. /* 设置初始化音量 */
  141. wm8753_send(52<<9 | (1<<8) | (1<<7) | 35 ); // LOUT1 0-57-63
  142. wm8753_send(53<<9 | (1<<8) | (1<<7) | 35 ); // ROUT1 0-57-63
  143. wm8753_send(54<<9 | (1<<8) | (1<<7) | 35 ); // LOUT2 0-57-63
  144. wm8753_send(55<<9 | (1<<8) | (1<<7) | 35 ); // ROUT2 0-57-63
  145. #if 1
  146. /* LINE IN test */
  147. wm8753_send(47<<9 | (1<<8) | (1<<4) ); //L LINE_IN VOL (6:4)输入增益: 0-关 1-12DB 2-9DB 5-0db 7+6DB
  148. wm8753_send(48<<9 | (1<<8) | (1<<4) ); //R LINE_IN VOL (6:4)输入增益: 0-关 1-12DB 2-9DB 5-0db 7+6DB
  149. wm8753_send(50<<9 | (5<<2) | (1<<1) | (1<<0) );//打开左监听 (4:2)增益 0-关 1-12DB 2-9DB 5-0db 7+6DB
  150. wm8753_send(51<<9 | (5<<2) | (1<<1) | (1<<0) );//打开右监听 (4:2)增益 0-关 1-12DB 2-9DB 5-0db 7+6DB
  151. /* MIC test */
  152. wm8753_send(44<<9 | (1<<8) | (1<<5) | (1<<4) | (0<<2) | (1<<1) | (1<<0) );//MIC输入选择
  153. wm8753_send(45<<9 | 50);//16-0 63-35
  154. wm8753_send(46<<9 | 50);//16-0 63-35
  155. #endif
  156. return RT_EOK;
  157. }
  158. #include <finsh.h>
  159. //0~57~63
  160. void vol(int v)
  161. {
  162. wm8753_send(52<<9 | (0<<8) | (1<<7) | v ); // LOUT1 0-57-63
  163. wm8753_send(53<<9 | (1<<8) | (1<<7) | v ); // ROUT1 0-57-63
  164. wm8753_send(54<<9 | (0<<8) | (1<<7) | v ); // LOUT2 0-57-63
  165. wm8753_send(55<<9 | (1<<8) | (1<<7) | v ); // ROUT2 0-57-63
  166. }
  167. FINSH_FUNCTION_EXPORT(vol, set volume)
  168. static rt_err_t wm8753_open(rt_device_t dev, rt_uint16_t oflag)
  169. {
  170. /* enable I2S */
  171. I2S_Cmd(SPI2, ENABLE);
  172. return RT_EOK;
  173. }
  174. static rt_err_t wm8753_close(rt_device_t dev)
  175. {
  176. /* interrupt mode */
  177. if (dev->flag & RT_DEVICE_FLAG_INT_TX)
  178. {
  179. /* Disable the I2S2 */
  180. I2S_Cmd(SPI2, DISABLE);
  181. }
  182. /* remove all data node */
  183. return RT_EOK;
  184. }
  185. static rt_err_t wm8753_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  186. {
  187. /* rate control */
  188. return RT_EOK;
  189. }
  190. static rt_size_t wm8753_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  191. {
  192. struct wm8753_device* device;
  193. struct wm8753_data_node* node;
  194. rt_uint32_t level;
  195. rt_uint16_t next_index;
  196. device = (struct wm8753_device*)dev;
  197. RT_ASSERT(device != RT_NULL);
  198. next_index = device->put_index + 1;
  199. if (next_index >= DATA_NODE_MAX) next_index = 0;
  200. /* check data_list full */
  201. if (next_index == device->read_index)
  202. {
  203. rt_set_errno(-RT_EFULL);
  204. return 0;
  205. }
  206. level = rt_hw_interrupt_disable();
  207. node = &device->data_list[device->put_index];
  208. device->put_index = next_index;
  209. // rt_kprintf("+\n");
  210. /* set node attribute */
  211. node->data_ptr = (rt_uint16_t*)buffer;
  212. node->data_size = size >> 1; /* size is byte unit, convert to half word unit */
  213. next_index = device->read_index + 1;
  214. if (next_index >= DATA_NODE_MAX) next_index = 0;
  215. /* check data list whether is empty */
  216. if (next_index == device->put_index)
  217. {
  218. if (dev->flag & RT_DEVICE_FLAG_INT_TX)
  219. {
  220. device->offset = 0;
  221. /* enable I2S interrupt */
  222. SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);
  223. }
  224. else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
  225. {
  226. DMA_Configuration((rt_uint32_t)node->data_ptr, node->data_size);
  227. }
  228. }
  229. rt_hw_interrupt_enable(level);
  230. return size;
  231. }
  232. rt_err_t wm8753_hw_init(void)
  233. {
  234. rt_device_t dev;
  235. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
  236. RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  237. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  238. NVIC_Configuration();
  239. GPIO_Configuration();
  240. I2S_Configuration();
  241. dev = (rt_device_t)&wm8753;
  242. dev->type = RT_Device_Class_Unknown;
  243. dev->rx_indicate = RT_NULL;
  244. dev->tx_complete = RT_NULL;
  245. dev->init = wm8753_init;
  246. dev->open = wm8753_open;
  247. dev->close = wm8753_close;
  248. dev->read = RT_NULL;
  249. dev->write = wm8753_write;
  250. dev->control = wm8753_control;
  251. dev->private = RT_NULL;
  252. /* set read_index and put index to 0 */
  253. wm8753.read_index = 0;
  254. wm8753.put_index = 0;
  255. /* unselect */
  256. wm_csb_1;
  257. /* register the device */
  258. return rt_device_register(&wm8753.parent, "snd",
  259. RT_DEVICE_FLAG_WRONLY | RT_DEVICE_FLAG_DMA_TX);
  260. }
  261. void wm8753_isr()
  262. {
  263. struct wm8753_data_node* node;
  264. node = &wm8753.data_list[wm8753.read_index]; /* get current data node */
  265. if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_TXE) == SET)
  266. {
  267. SPI_I2S_SendData(SPI2, node->data_ptr[wm8753.offset++]);
  268. }
  269. if (wm8753.offset == node->data_size)
  270. {
  271. /* move to next node */
  272. rt_uint16_t next_index;
  273. next_index = wm8753.read_index + 1;
  274. if (next_index >= DATA_NODE_MAX) next_index = 0;
  275. /* notify transmitted complete. */
  276. if (wm8753.parent.tx_complete != RT_NULL)
  277. {
  278. wm8753.parent.tx_complete (&wm8753.parent, wm8753.data_list[wm8753.read_index].data_ptr);
  279. rt_kprintf("-\n");
  280. }
  281. wm8753.offset = 0;
  282. wm8753.read_index = next_index;
  283. if (next_index == wm8753.put_index)
  284. {
  285. /* no data on the list, disable I2S interrupt */
  286. SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
  287. rt_kprintf("*\n");
  288. }
  289. }
  290. }
  291. void wm8753_dma_isr()
  292. {
  293. /* switch to next buffer */
  294. rt_uint16_t next_index;
  295. void* data_ptr;
  296. next_index = wm8753.read_index + 1;
  297. if (next_index >= DATA_NODE_MAX) next_index = 0;
  298. /* save current data pointer */
  299. data_ptr = wm8753.data_list[wm8753.read_index].data_ptr;
  300. wm8753.read_index = next_index;
  301. if (next_index != wm8753.put_index)
  302. {
  303. /* enable next dma request */
  304. DMA_Configuration((rt_uint32_t)wm8753.data_list[wm8753.read_index].data_ptr,
  305. wm8753.data_list[wm8753.read_index].data_size);
  306. }
  307. else
  308. {
  309. rt_kprintf("*\n");
  310. }
  311. /* notify transmitted complete. */
  312. if (wm8753.parent.tx_complete != RT_NULL)
  313. {
  314. wm8753.parent.tx_complete (&wm8753.parent, data_ptr);
  315. // rt_kprintf("-\n");
  316. }
  317. }