bflb_Microphone.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include "bflb_adc.h"
  2. #include "bflb_dma.h"
  3. #include "bflb_gpio.h"
  4. #include "lvgl.h"
  5. #include "bflb_Microphone.h"
  6. #include "bflb_common.h"
  7. #define TEST_ADC_CHANNELS 2
  8. #define TEST_COUNT 80
  9. extern PikaEventListener* g_pika_bflb_event_listener;
  10. extern uint8_t g_mic_callback_task_flag;
  11. extern volatile uint8_t g_callback_thread_inited;
  12. static lv_obj_t* chart_mic = NULL;
  13. static lv_coord_t ecg_sample[160];
  14. int16_t g_mic_frame[TEST_COUNT];
  15. static struct bflb_device_s* adc;
  16. static uint32_t adc_raw_data[2][TEST_ADC_CHANNELS * TEST_COUNT];
  17. static lv_obj_t* chart_mic_create(lv_obj_t* parent);
  18. static void adc_init(void);
  19. static void dma0_ch0_isr(void* arg);
  20. static uint8_t g_mic_inited = 0;
  21. static uint8_t g_mic_callback_inited = 0;
  22. static void microphone_init(void) {
  23. adc_init();
  24. }
  25. void microphone_demo(void) {
  26. chart_mic = chart_mic_create(lv_scr_act());
  27. bflb_adc_start_conversion(adc);
  28. }
  29. static void adc_init(void) {
  30. /* ADC_CH0 */
  31. struct bflb_device_s* gpio = bflb_device_get_by_name("gpio");
  32. bflb_gpio_init(gpio, GPIO_PIN_20, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0);
  33. /* ADC_CH3 */
  34. bflb_gpio_init(gpio, GPIO_PIN_3, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0);
  35. struct bflb_adc_channel_s chan[] = {
  36. { .pos_chan = ADC_CHANNEL_0,
  37. .neg_chan = ADC_CHANNEL_GND },
  38. { .pos_chan = ADC_CHANNEL_3,
  39. .neg_chan = ADC_CHANNEL_GND },
  40. };
  41. adc = bflb_device_get_by_name("adc");
  42. /**
  43. * adc clock = XCLK / 2 / 20 / 64(14B) = 15.625K
  44. */
  45. struct bflb_adc_config_s cfg;
  46. cfg.clk_div = ADC_CLK_DIV_20;
  47. cfg.scan_conv_mode = true;
  48. cfg.continuous_conv_mode = true;
  49. cfg.differential_mode = false;
  50. cfg.resolution = ADC_RESOLUTION_14B;
  51. cfg.vref = ADC_VREF_2P0V;
  52. bflb_adc_init(adc, &cfg);
  53. bflb_adc_channel_config(adc, chan, sizeof(chan) / sizeof(chan[0]));
  54. bflb_adc_link_rxdma(adc, true);
  55. struct bflb_device_s *dma0_ch0;
  56. dma0_ch0 = bflb_device_get_by_name("dma0_ch0");
  57. struct bflb_dma_channel_config_s config;
  58. config.direction = DMA_PERIPH_TO_MEMORY;
  59. config.src_req = DMA_REQUEST_ADC;
  60. config.dst_req = DMA_REQUEST_NONE;
  61. config.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
  62. config.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
  63. config.src_burst_count = DMA_BURST_INCR1;
  64. config.dst_burst_count = DMA_BURST_INCR1;
  65. config.src_width = DMA_DATA_WIDTH_32BIT;
  66. config.dst_width = DMA_DATA_WIDTH_32BIT;
  67. bflb_dma_channel_init(dma0_ch0, &config);
  68. bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL);
  69. static struct bflb_dma_channel_lli_pool_s lli[20]; /* max trasnfer size 4064 * 20 */
  70. static struct bflb_dma_channel_lli_transfer_s transfers[2];
  71. transfers[0].src_addr = (uint32_t)DMA_ADDR_ADC_RDR;
  72. transfers[0].dst_addr = (uint32_t)adc_raw_data[0];
  73. transfers[0].nbytes = sizeof(adc_raw_data[0]);
  74. transfers[1].src_addr = (uint32_t)DMA_ADDR_ADC_RDR;
  75. transfers[1].dst_addr = (uint32_t)adc_raw_data[1];
  76. transfers[1].nbytes = sizeof(adc_raw_data[1]);
  77. int used_count = bflb_dma_channel_lli_reload(dma0_ch0, lli, 20, transfers, 2);
  78. bflb_dma_channel_lli_link_head(dma0_ch0, lli, used_count);
  79. bflb_dma_channel_start(dma0_ch0);
  80. // bflb_adc_start_conversion(adc);
  81. bflb_adc_stop_conversion(adc);
  82. _callback_thread_init();
  83. }
  84. void mic_demo_update(int16_t *data, uint16_t len)
  85. {
  86. uint32_t pcnt = sizeof(ecg_sample) / sizeof(ecg_sample[0]);
  87. if (!chart_mic || !data || !len) {
  88. pika_debug("mic_demo_update skiped");
  89. return;
  90. }
  91. if (len > pcnt)
  92. len = pcnt;
  93. lv_obj_t *chart = chart_mic;
  94. lv_chart_set_point_count(chart, 0);
  95. memcpy(ecg_sample, ecg_sample + len, (pcnt - len) * sizeof(lv_coord_t));
  96. memcpy(ecg_sample + pcnt - len, data, len * sizeof(lv_coord_t));
  97. lv_chart_set_point_count(chart, pcnt);
  98. // pika_debug("mic_demo_update len:%d", len);
  99. }
  100. static void dma0_ch0_isr(void* arg) {
  101. // pika_debug("dma0_ch0_isr");
  102. static uint32_t dma_tc_flag0 = 0;
  103. dma_tc_flag0++;
  104. // printf("[%d]tc done\r\n", dma_tc_flag0);
  105. struct bflb_adc_result_s result[TEST_ADC_CHANNELS * TEST_COUNT];
  106. bflb_adc_parse_result(adc, adc_raw_data[!(dma_tc_flag0 & 0x1)], result,
  107. TEST_ADC_CHANNELS * TEST_COUNT);
  108. uint32_t btn_adc_val_avg = 0;
  109. for (size_t j = 0, k = 0; j < TEST_ADC_CHANNELS * TEST_COUNT; j++) {
  110. // printf("raw data:%08x\r\n", adc_raw_data[!(dma_tc_flag0 & 0x1)][j]);
  111. // ADC_CHANNEL_0 min:923mv nor:952mv max:980mv
  112. // printf("pos chan %d,%d mv \r\n", result[j].pos_chan,
  113. // result[j].millivolt);
  114. if (ADC_CHANNEL_3 == result[j].pos_chan) {
  115. btn_adc_val_avg += result[j].millivolt;
  116. } else if (ADC_CHANNEL_0 == result[j].pos_chan) {
  117. g_mic_frame[k++] = result[j].millivolt; // - 952;
  118. }
  119. }
  120. btn_adc_val_avg /= TEST_COUNT;
  121. g_mic_callback_task_flag = 1;
  122. mic_demo_update(g_mic_frame, TEST_COUNT);
  123. // label_adc_btn_update(btn_adc_val_avg);
  124. }
  125. static lv_obj_t* chart_mic_create(lv_obj_t* parent) {
  126. /* Create a chart */
  127. lv_obj_t* chart;
  128. chart = lv_chart_create(parent);
  129. pika_debug("create chart: %p", chart);
  130. lv_obj_set_size(chart, 320, 240);
  131. // lv_obj_align(chart, LV_ALIGN_CENTER, 0, 0);
  132. lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 2000);
  133. /*Do not display points on the data*/
  134. lv_obj_set_style_size(chart, 0, LV_PART_INDICATOR);
  135. pika_debug("LV_PART_INDICATOR: %d", LV_PART_INDICATOR);
  136. lv_chart_series_t* ser = lv_chart_add_series(
  137. chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
  138. pika_debug("LV_CHART_AXIS_PRIMARY_Y: %d", LV_CHART_AXIS_PRIMARY_Y);
  139. uint32_t pcnt = sizeof(ecg_sample) / sizeof(ecg_sample[0]);
  140. lv_chart_set_point_count(chart, pcnt);
  141. lv_chart_set_ext_y_array(chart, ser, (lv_coord_t*)ecg_sample);
  142. lv_chart_set_zoom_x(chart, LV_IMG_ZOOM_NONE);
  143. lv_chart_set_zoom_y(chart, LV_IMG_ZOOM_NONE);
  144. pika_debug("create chart OK");
  145. return chart;
  146. }
  147. void bflb_Microphone___init__(PikaObj *self){
  148. if (g_mic_inited){
  149. return;
  150. }
  151. pika_debug("microphone init");
  152. microphone_init();
  153. g_mic_inited = 1;
  154. }
  155. void bflb_Microphone_demo(PikaObj *self){
  156. pika_debug("microphone demo");
  157. microphone_demo();
  158. }
  159. void bflb_Microphone_set_callback(PikaObj *self, Arg* callback){
  160. obj_setArg(self, "eventCallBack", callback);
  161. /* init event_listener for the first time */
  162. if (NULL == g_pika_bflb_event_listener) {
  163. pks_eventListener_init(&g_pika_bflb_event_listener);
  164. }
  165. uint32_t eventId = (uintptr_t)adc;
  166. pks_eventListener_registEvent(g_pika_bflb_event_listener, eventId, self);
  167. g_mic_callback_inited = 1;
  168. pika_debug("bflb_Microphone_set_callback: %p\r\n", eventId);
  169. }
  170. void bflb_Microphone_start(PikaObj *self){
  171. bflb_adc_start_conversion(adc);
  172. }
  173. void bflb_Microphone_stop(PikaObj *self){
  174. bflb_adc_stop_conversion(adc);
  175. }
  176. void mic_py_callback(void) {
  177. if (!g_mic_callback_inited) {
  178. return;
  179. }
  180. pika_debug("mic_py_callback\r\n");
  181. pks_eventListener_sendSignal(g_pika_bflb_event_listener, (uintptr_t)adc, 0);
  182. }
  183. PikaObj* bflb_Microphone_get_frame_info(PikaObj *self){
  184. return obj_newTuple(arg_newInt((uintptr_t)g_mic_frame), arg_newInt(sizeof(g_mic_frame) / sizeof(g_mic_frame[0])));
  185. }