tc_audio_main.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*
  2. * Copyright (c) 2006-2025 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2025-05-01 wumingzi first version
  9. */
  10. /* The file can test the rt-thread audio driver framework including following api via memory
  11. * simulation.
  12. *
  13. * rt_audio_register
  14. * rt_audio_rx_done
  15. * rt_audio_tx_complete
  16. *
  17. * When audio devices generate or receive new data, the corresponding buffer in device will
  18. * receive date from kernel or surroundings. The same phenomenon will also happen at the
  19. * application level. Thus we can fill memory to simulate the generation of data then track
  20. * and check memory to ensure kernel processing audio data correctly. And this depends on
  21. * implementations of audio drivers.
  22. *
  23. * Therefore, if the player_test testcase failed, it could mean rt_audio_register or
  24. * rt_audio_tx_complete existing bugs. Similarly, if mic_test testcase failed, it could mean
  25. * rt_audio_register or rt_audio_rx_done existing bugs.
  26. */
  27. #include "tc_audio_common.h"
  28. rt_uint8_t audio_fsm_step = 0;
  29. /* Allocate and initialize memory filled by fill_byte */
  30. static void *alloc_filled_mem(rt_uint8_t fill_byte, rt_size_t size)
  31. {
  32. void *ptr = rt_malloc(size);
  33. if (ptr != NULL)
  34. {
  35. rt_memset(ptr, fill_byte, size);
  36. }
  37. return ptr;
  38. }
  39. /* Check if the memory is filled with fill_byte */
  40. static rt_err_t check_filled_mem(rt_uint8_t fill_byte, rt_uint8_t *mem, size_t size)
  41. {
  42. rt_uint8_t *p = mem;
  43. for (size_t i = 0; i < size; ++i)
  44. {
  45. if (*(p+i) != fill_byte)
  46. {
  47. return -RT_ERROR;
  48. }
  49. }
  50. return RT_EOK;
  51. }
  52. static void player_test(void)
  53. {
  54. int res = 0;
  55. void* player_buffer = RT_NULL;
  56. rt_device_t dev_obj;
  57. dev_obj = rt_device_find(SOUND_PLAYER_DEVICE_NAME);
  58. if (dev_obj == RT_NULL)
  59. {
  60. uassert_not_null(dev_obj);
  61. goto __exit;
  62. }
  63. if (dev_obj->type != RT_Device_Class_Sound)
  64. {
  65. LOG_E("Not an audio player device\n");
  66. goto __exit;
  67. }
  68. res = rt_device_open(dev_obj, RT_DEVICE_OFLAG_WRONLY);
  69. if (res != RT_EOK)
  70. {
  71. LOG_E("Audio player device failed\n");
  72. uassert_true(0);
  73. goto __exit;
  74. }
  75. /* The sampling rate is set by the driver default, so there isn't configuration step */
  76. struct rt_audio_device *audio_dev = rt_container_of(dev_obj, struct rt_audio_device, parent);
  77. struct rt_audio_buf_info buf_info = audio_dev->replay->buf_info;
  78. struct sound_device *snd_dev = rt_container_of(audio_dev, struct sound_device, audio);
  79. player_buffer = alloc_filled_mem(0xAA, TX_DMA_BLOCK_SIZE);
  80. if (player_buffer == RT_NULL)
  81. {
  82. rt_kprintf("Allocate test memory failed\n");
  83. uassert_true(0);
  84. goto __exit;
  85. }
  86. if(snd_dev->tx_fifo == RT_NULL)
  87. {
  88. rt_kprintf("snd_dev->tx_fifo == RT_NULL ");
  89. uassert_true(0);
  90. goto __exit;
  91. }
  92. res = rt_device_write(dev_obj, 0, player_buffer, TX_DMA_BLOCK_SIZE);
  93. if (res != RT_EOK && res != TX_DMA_BLOCK_SIZE)
  94. {
  95. rt_kprintf("Failed to write data to the player device, res = %d\n",res);
  96. uassert_true(0);
  97. goto __exit;
  98. }
  99. audio_fsm_step = 1;
  100. while (1)
  101. {
  102. if(audio_fsm_step == 2)
  103. {
  104. break;
  105. }
  106. rt_thread_mdelay(10);
  107. }
  108. res = check_filled_mem(0xAA, &buf_info.buffer[0], TX_DMA_BLOCK_SIZE);
  109. if (res != RT_EOK)
  110. {
  111. rt_kprintf("The first memory check failed! Buffer dump\n");
  112. for (rt_size_t i = 0; i < TX_DMA_FIFO_SIZE; i++)
  113. {
  114. rt_kprintf("%02X ", buf_info.buffer[i]);
  115. if (i % 16 == 15) rt_kprintf("\n");
  116. }
  117. rt_kprintf("\n");
  118. uassert_true(0);
  119. goto __exit;
  120. }
  121. rt_free(player_buffer);
  122. player_buffer = RT_NULL;
  123. player_buffer = alloc_filled_mem(0x55, TX_DMA_BLOCK_SIZE);
  124. if (player_buffer == RT_NULL)
  125. {
  126. rt_kprintf("Allocate test memory failed\n");
  127. uassert_true(0);
  128. goto __exit;
  129. }
  130. res = rt_device_write(dev_obj, TX_DMA_BLOCK_SIZE, player_buffer, TX_DMA_BLOCK_SIZE);
  131. if (res != RT_EOK && res != TX_DMA_BLOCK_SIZE)
  132. {
  133. rt_kprintf("Failed to write data to the player device, res = %d\n",res);
  134. uassert_true(0);
  135. goto __exit;
  136. }
  137. audio_fsm_step = 2;
  138. while (res != RT_EOK)
  139. {
  140. if(audio_fsm_step == 3)
  141. {
  142. break;
  143. }
  144. rt_thread_mdelay(10);
  145. }
  146. res = check_filled_mem(0x55,&buf_info.buffer[TX_DMA_BLOCK_SIZE], TX_DMA_BLOCK_SIZE);
  147. if (res != RT_EOK)
  148. {
  149. rt_kprintf("The second memory check failed! Buffer dump\n");
  150. for (rt_size_t i = 0; i < TX_DMA_FIFO_SIZE; i++)
  151. {
  152. rt_kprintf("%02X ", buf_info.buffer[i]);
  153. if (i % 16 == 15) rt_kprintf("\n");
  154. }
  155. rt_kprintf("\n");
  156. uassert_true(0);
  157. goto __exit;
  158. }
  159. __exit:
  160. if (player_buffer)
  161. {
  162. rt_free(player_buffer);
  163. player_buffer = RT_NULL;
  164. }
  165. if (dev_obj != RT_NULL)
  166. {
  167. audio_fsm_step = 4;
  168. rt_device_close(dev_obj);
  169. }
  170. }
  171. static void mic_test(void)
  172. {
  173. rt_device_t dev_obj;
  174. rt_uint8_t *mic_buffer = RT_NULL;
  175. rt_ssize_t res = 0;
  176. rt_ssize_t length = 0;
  177. mic_buffer = (rt_uint8_t *)rt_malloc(RX_DMA_BLOCK_SIZE);
  178. if (mic_buffer == RT_NULL)
  179. {
  180. rt_kprintf("The mic_buffer memory allocate failed\n");
  181. uassert_true(0);
  182. goto __exit;
  183. }
  184. dev_obj = rt_device_find(SOUND_MIC_DEVICE_NAME);
  185. if (dev_obj == RT_NULL)
  186. {
  187. LOG_E("Not a mic device\n");
  188. uassert_true(0);
  189. goto __exit;
  190. }
  191. res = rt_device_open(dev_obj, RT_DEVICE_OFLAG_RDONLY);
  192. if (res != RT_EOK)
  193. {
  194. LOG_E("Audio player device failed\n");
  195. uassert_true(0);
  196. goto __exit;
  197. }
  198. length = rt_device_read(dev_obj, 0, mic_buffer,RX_DMA_BLOCK_SIZE);
  199. if(length < 0)
  200. {
  201. LOG_E("Mic device read err\n");
  202. }
  203. if(audio_fsm_step == 1)
  204. {
  205. res = check_filled_mem(0xAA, (rt_uint8_t*)(mic_buffer), length);
  206. }
  207. if (res != RT_EOK)
  208. {
  209. LOG_E("The first memory check failed! Buffer dump\n");
  210. for (rt_size_t i = 0; i < RX_DMA_FIFO_SIZE; i++)
  211. {
  212. rt_kprintf("%02X ",mic_buffer[i]);
  213. if (i % 16 == 15) rt_kprintf("\n");
  214. }
  215. rt_kprintf("\n");
  216. uassert_true(0);
  217. goto __exit;
  218. }
  219. audio_fsm_step = 2;
  220. while (1)
  221. {
  222. if(audio_fsm_step == 3)
  223. {
  224. length = rt_device_read(dev_obj, 0, mic_buffer, RX_DMA_FIFO_SIZE);
  225. if(length < 0)
  226. {
  227. LOG_E("Mic device read err\n");
  228. }
  229. res = check_filled_mem(0x55, (rt_uint8_t*)(&mic_buffer[0]), length);
  230. if(res != RT_EOK)
  231. {
  232. LOG_E("The second memory check failed! Buffer dump\n");
  233. for (rt_size_t i = 0; i < RX_DMA_FIFO_SIZE; i++)
  234. {
  235. rt_kprintf("%02X ",mic_buffer[i]);
  236. if (i % 16 == 15) rt_kprintf("\n");
  237. }
  238. rt_kprintf("\n");
  239. uassert_true(0);
  240. goto __exit;
  241. }
  242. break;
  243. }
  244. rt_thread_mdelay(100);
  245. }
  246. __exit:
  247. if (mic_buffer)
  248. {
  249. rt_free(mic_buffer);
  250. }
  251. if (dev_obj != RT_NULL)
  252. {
  253. audio_fsm_step = 4;
  254. rt_device_close(dev_obj);
  255. }
  256. }
  257. static void testcase(void)
  258. {
  259. UTEST_UNIT_RUN(player_test);
  260. UTEST_UNIT_RUN(mic_test);
  261. }
  262. static rt_err_t utest_tc_init(void)
  263. {
  264. return RT_EOK;
  265. }
  266. static rt_err_t utest_tc_cleanup(void)
  267. {
  268. return RT_EOK;
  269. }
  270. UTEST_TC_EXPORT(testcase, "components.drivers.audio.tc_audio_main", utest_tc_init, utest_tc_cleanup, 10);