gps_ag3352b.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright (c) 2022 Actions Technology Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <soc.h>
  7. #include <board.h>
  8. #include <device.h>
  9. #include <drivers/uart.h>
  10. #include <drivers/uart_dma.h>
  11. #include <logging/log.h>
  12. #include <gps/gps.h>
  13. #ifndef TRUE
  14. #define TRUE 1
  15. #endif
  16. #ifndef FALSE
  17. #define FALSE 0
  18. #endif
  19. LOG_MODULE_REGISTER(gps_3352, LOG_LEVEL_INF);
  20. #define CONFIG_GPS_DEV_NAME "gps"
  21. #define GPS_UERT_DEV_NAME CONFIG_UART_2_NAME
  22. #ifdef CONFIG_SENSOR_GPS_UART_DMA
  23. #define GPS_DATA_BUFFER_SIZE 100
  24. #else
  25. #define UART_FIFO_MAX 16
  26. #define GPS_DATA_BUFFER_SIZE 100
  27. #endif // CONFIG_SENSOR_GPS_UART_DMA
  28. struct ag3352_data {
  29. const struct device *uart_gpio_dev;
  30. #ifdef CONFIG_SENSOR_GPS_UART_DMA
  31. uint8_t temp_buff[GPS_DATA_BUFFER_SIZE];
  32. #else
  33. uint8_t gps_data[2][GPS_DATA_BUFFER_SIZE];
  34. uint8_t gpa_data_cur;
  35. uint8_t gpa_data_prev;
  36. #endif // CONFIG_SENSOR_GPS_UART_DMA
  37. gps_notify_t notify;
  38. struct k_work gps_work;
  39. };
  40. static struct ag3352_data ag3352_data;
  41. #ifdef CONFIG_SENSOR_GPS_UART_DMA
  42. void uart_ctrl_rx_dma_start(struct device *dev)
  43. {
  44. uart_dma_receive(dev, ag3352_data.temp_buff, GPS_DATA_BUFFER_SIZE);
  45. /* timeout���������Ƿ�����
  46. */
  47. // hrtimer_start(&g_tool_data.timer, UART_CTRL_RX_DMA_TIMEOUT_US, 0);
  48. }
  49. static void uart_ctrl_rx_dma_handler(const struct device *dma_dev, void *user_data,
  50. uint32_t channel, int status)
  51. {
  52. LOG_INF("%s", ag3352_data.temp_buff);
  53. // hrtimer_stop(&g_tool_data.timer);
  54. // ring_buf_put(&g_tool_data.rx_ringbuf, g_tool_data.temp_buff, UART_CTRL_RX_TEMP_BUF_SIZE);
  55. uart_ctrl_rx_dma_start((struct device *)ag3352_data.uart_gpio_dev);
  56. }
  57. #else
  58. static void uart_fifo_callback(const struct device *dev, void *user_data)
  59. {
  60. uint8_t rx_buff[UART_FIFO_MAX];
  61. int read_size;
  62. static uint8_t cnt;
  63. uart_irq_update(dev);
  64. if (uart_irq_rx_ready(dev)) {
  65. read_size = uart_fifo_read(dev, rx_buff, UART_FIFO_MAX);
  66. if (read_size == UART_FIFO_MAX)
  67. LOG_ERR("uart fifo buffer overflow");
  68. for (int i = 0; i < read_size; i++) {
  69. switch (rx_buff[i]) {
  70. case '$':
  71. if (ag3352_data.gpa_data_cur)
  72. ag3352_data.gpa_data_cur = 0;
  73. else
  74. ag3352_data.gpa_data_cur = 1;
  75. memset(ag3352_data.gps_data[ag3352_data.gpa_data_cur], 0,
  76. sizeof(ag3352_data.gps_data[ag3352_data.gpa_data_cur]));
  77. cnt = 0;
  78. ag3352_data.gps_data[ag3352_data.gpa_data_cur][cnt] = rx_buff[i];
  79. break;
  80. case '\n':
  81. cnt++;
  82. ag3352_data.gps_data[ag3352_data.gpa_data_cur][cnt] = rx_buff[i];
  83. ag3352_data.gpa_data_prev = ag3352_data.gpa_data_cur;
  84. k_work_submit(&ag3352_data.gps_work);
  85. break;
  86. default:
  87. cnt++;
  88. ag3352_data.gps_data[ag3352_data.gpa_data_cur][cnt] = rx_buff[i];
  89. /* protection data cannot exceed boundary */
  90. if (cnt >= GPS_DATA_BUFFER_SIZE)
  91. cnt--;
  92. break;
  93. }
  94. }
  95. }
  96. }
  97. #endif // CONFIG_SENSOR_GPS_UART_DMA
  98. static void ag3352_enable(const struct device *dev)
  99. {
  100. struct ag3352_data *data = (struct ag3352_data *)dev->data;
  101. sys_write32(0x3, HGLFCLK_CTL);
  102. sys_write32((sys_read32(CMU_DEVCLKEN1) | (1 << 31)), CMU_DEVCLKEN1);
  103. sys_write32(0x101e, 0x400680F4); //GPIO61 set 0x1E: LOSCOUT
  104. gps_reset_pin_ctl();
  105. gps_wake_up_pin_ctl(true);
  106. #ifdef CONFIG_SENSOR_GPS_UART_DMA
  107. uart_ctrl_rx_dma_start((struct device *)data->uart_gpio_dev);
  108. #else
  109. uart_irq_rx_enable(data->uart_gpio_dev);
  110. #endif // CONFIG_SENSOR_GPS_UART_DMA
  111. }
  112. static void ag3352_disable(const struct device *dev)
  113. {
  114. struct ag3352_data *data = (struct ag3352_data *)dev->data;
  115. // gps_wake_up_pin_ctl(false);
  116. #ifdef CONFIG_SENSOR_GPS_UART_DMA
  117. uart_dma_receive_stop((struct device *)data->uart_gpio_dev);
  118. #else
  119. uart_irq_rx_disable(data->uart_gpio_dev);
  120. #endif // CONFIG_SENSOR_GPS_UART_DMA
  121. }
  122. static void ag3352_register_notify(const struct device *dev, gps_notify_t notify)
  123. {
  124. LOG_INF("ag3352_init");
  125. struct ag3352_data *data = (struct ag3352_data *)dev->data;
  126. data->notify = notify;
  127. }
  128. static void ag3352_unregister_notify(const struct device *dev, gps_notify_t notify)
  129. {
  130. struct ag3352_data *data = (struct ag3352_data *)dev->data;
  131. data->notify = NULL;
  132. }
  133. static const struct gps_dev_driver_api ag3352_api = {
  134. .enable = ag3352_enable,
  135. .disable = ag3352_disable,
  136. .inquiry = NULL,
  137. .register_notify = ag3352_register_notify,
  138. .unregister_notify = ag3352_unregister_notify,
  139. };
  140. static void _gps_work_handler(struct k_work *work)
  141. {
  142. struct gps_value val = { 0 };
  143. //LOG_INF("gps nmea: %s\r\n", ag3352_data.gps_data[ag3352_data.gpa_data_prev]);
  144. if (ag3352_data.notify) {
  145. #ifdef CONFIG_SENSOR_GPS_UART_DMA
  146. #else
  147. val.gps_nmea_data = ag3352_data.gps_data[ag3352_data.gpa_data_prev];
  148. #endif // CONFIG_SENSOR_GPS_UART_DMA
  149. ag3352_data.notify(NULL, &val);
  150. }
  151. }
  152. static int ag3352_init(const struct device *dev)
  153. {
  154. struct ag3352_data *data = (struct ag3352_data *)dev->data;
  155. LOG_INF("ag3352_init");
  156. gps_power_pin_ctl(true);
  157. gps_power095_pin_ctl(true);
  158. gps_reset_pin_ctl();
  159. data->uart_gpio_dev = device_get_binding(GPS_UERT_DEV_NAME);
  160. if (data->uart_gpio_dev == NULL) {
  161. LOG_ERR("Couldn't find gps uart");
  162. return -ENODEV;
  163. }
  164. k_work_init(&data->gps_work, _gps_work_handler);
  165. #ifdef CONFIG_SENSOR_GPS_UART_DMA
  166. uart_dma_receive_init((struct device *)data->uart_gpio_dev, uart_ctrl_rx_dma_handler, NULL);
  167. uart_rx_dma_switch((struct device *)data->uart_gpio_dev, TRUE, NULL, NULL);
  168. #else
  169. uart_irq_callback_set(data->uart_gpio_dev, uart_fifo_callback);
  170. data->gpa_data_cur = 0;
  171. #endif // CONFIG_SENSOR_GPS_UART_DMA
  172. return 0;
  173. }
  174. #if IS_ENABLED(CONFIG_GPS)
  175. DEVICE_DEFINE(ag3352, CONFIG_GPS_DEV_NAME, &ag3352_init, NULL, &ag3352_data, NULL, POST_KERNEL, 60,
  176. &ag3352_api);
  177. #endif