123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /*
- * Copyright (c) 2022 Actions Technology Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <soc.h>
- #include <board.h>
- #include <device.h>
- #include <drivers/uart.h>
- #include <drivers/uart_dma.h>
- #include <logging/log.h>
- #include <gps/gps.h>
- #ifndef TRUE
- #define TRUE 1
- #endif
- #ifndef FALSE
- #define FALSE 0
- #endif
- LOG_MODULE_REGISTER(gps_3352, LOG_LEVEL_INF);
- #define CONFIG_GPS_DEV_NAME "gps"
- #define GPS_UERT_DEV_NAME CONFIG_UART_2_NAME
- #ifdef CONFIG_SENSOR_GPS_UART_DMA
- #define GPS_DATA_BUFFER_SIZE 100
- #else
- #define UART_FIFO_MAX 16
- #define GPS_DATA_BUFFER_SIZE 100
- #endif // CONFIG_SENSOR_GPS_UART_DMA
- struct ag3352_data {
- const struct device *uart_gpio_dev;
- #ifdef CONFIG_SENSOR_GPS_UART_DMA
- uint8_t temp_buff[GPS_DATA_BUFFER_SIZE];
- #else
- uint8_t gps_data[2][GPS_DATA_BUFFER_SIZE];
- uint8_t gpa_data_cur;
- uint8_t gpa_data_prev;
- #endif // CONFIG_SENSOR_GPS_UART_DMA
- gps_notify_t notify;
- struct k_work gps_work;
- };
- static struct ag3352_data ag3352_data;
- #ifdef CONFIG_SENSOR_GPS_UART_DMA
- void uart_ctrl_rx_dma_start(struct device *dev)
- {
- uart_dma_receive(dev, ag3352_data.temp_buff, GPS_DATA_BUFFER_SIZE);
- /* timeout���������Ƿ�����
- */
- // hrtimer_start(&g_tool_data.timer, UART_CTRL_RX_DMA_TIMEOUT_US, 0);
- }
- static void uart_ctrl_rx_dma_handler(const struct device *dma_dev, void *user_data,
- uint32_t channel, int status)
- {
- LOG_INF("%s", ag3352_data.temp_buff);
- // hrtimer_stop(&g_tool_data.timer);
- // ring_buf_put(&g_tool_data.rx_ringbuf, g_tool_data.temp_buff, UART_CTRL_RX_TEMP_BUF_SIZE);
- uart_ctrl_rx_dma_start((struct device *)ag3352_data.uart_gpio_dev);
- }
- #else
- static void uart_fifo_callback(const struct device *dev, void *user_data)
- {
- uint8_t rx_buff[UART_FIFO_MAX];
- int read_size;
- static uint8_t cnt;
- uart_irq_update(dev);
- if (uart_irq_rx_ready(dev)) {
- read_size = uart_fifo_read(dev, rx_buff, UART_FIFO_MAX);
- if (read_size == UART_FIFO_MAX)
- LOG_ERR("uart fifo buffer overflow");
- for (int i = 0; i < read_size; i++) {
- switch (rx_buff[i]) {
- case '$':
- if (ag3352_data.gpa_data_cur)
- ag3352_data.gpa_data_cur = 0;
- else
- ag3352_data.gpa_data_cur = 1;
- memset(ag3352_data.gps_data[ag3352_data.gpa_data_cur], 0,
- sizeof(ag3352_data.gps_data[ag3352_data.gpa_data_cur]));
- cnt = 0;
- ag3352_data.gps_data[ag3352_data.gpa_data_cur][cnt] = rx_buff[i];
- break;
- case '\n':
- cnt++;
- ag3352_data.gps_data[ag3352_data.gpa_data_cur][cnt] = rx_buff[i];
- ag3352_data.gpa_data_prev = ag3352_data.gpa_data_cur;
- k_work_submit(&ag3352_data.gps_work);
- break;
- default:
- cnt++;
- ag3352_data.gps_data[ag3352_data.gpa_data_cur][cnt] = rx_buff[i];
- /* protection data cannot exceed boundary */
- if (cnt >= GPS_DATA_BUFFER_SIZE)
- cnt--;
- break;
- }
- }
- }
- }
- #endif // CONFIG_SENSOR_GPS_UART_DMA
- static void ag3352_enable(const struct device *dev)
- {
- struct ag3352_data *data = (struct ag3352_data *)dev->data;
- sys_write32(0x3, HGLFCLK_CTL);
- sys_write32((sys_read32(CMU_DEVCLKEN1) | (1 << 31)), CMU_DEVCLKEN1);
- sys_write32(0x101e, 0x400680F4); //GPIO61 set 0x1E: LOSCOUT
- gps_reset_pin_ctl();
- gps_wake_up_pin_ctl(true);
- #ifdef CONFIG_SENSOR_GPS_UART_DMA
- uart_ctrl_rx_dma_start((struct device *)data->uart_gpio_dev);
- #else
- uart_irq_rx_enable(data->uart_gpio_dev);
- #endif // CONFIG_SENSOR_GPS_UART_DMA
- }
- static void ag3352_disable(const struct device *dev)
- {
- struct ag3352_data *data = (struct ag3352_data *)dev->data;
- // gps_wake_up_pin_ctl(false);
- #ifdef CONFIG_SENSOR_GPS_UART_DMA
- uart_dma_receive_stop((struct device *)data->uart_gpio_dev);
- #else
- uart_irq_rx_disable(data->uart_gpio_dev);
- #endif // CONFIG_SENSOR_GPS_UART_DMA
- }
- static void ag3352_register_notify(const struct device *dev, gps_notify_t notify)
- {
- LOG_INF("ag3352_init");
- struct ag3352_data *data = (struct ag3352_data *)dev->data;
- data->notify = notify;
- }
- static void ag3352_unregister_notify(const struct device *dev, gps_notify_t notify)
- {
- struct ag3352_data *data = (struct ag3352_data *)dev->data;
- data->notify = NULL;
- }
- static const struct gps_dev_driver_api ag3352_api = {
- .enable = ag3352_enable,
- .disable = ag3352_disable,
- .inquiry = NULL,
- .register_notify = ag3352_register_notify,
- .unregister_notify = ag3352_unregister_notify,
- };
- static void _gps_work_handler(struct k_work *work)
- {
- struct gps_value val = { 0 };
- //LOG_INF("gps nmea: %s\r\n", ag3352_data.gps_data[ag3352_data.gpa_data_prev]);
- if (ag3352_data.notify) {
- #ifdef CONFIG_SENSOR_GPS_UART_DMA
- #else
- val.gps_nmea_data = ag3352_data.gps_data[ag3352_data.gpa_data_prev];
- #endif // CONFIG_SENSOR_GPS_UART_DMA
- ag3352_data.notify(NULL, &val);
- }
- }
- static int ag3352_init(const struct device *dev)
- {
- struct ag3352_data *data = (struct ag3352_data *)dev->data;
- LOG_INF("ag3352_init");
- gps_power_pin_ctl(true);
- gps_power095_pin_ctl(true);
- gps_reset_pin_ctl();
- data->uart_gpio_dev = device_get_binding(GPS_UERT_DEV_NAME);
- if (data->uart_gpio_dev == NULL) {
- LOG_ERR("Couldn't find gps uart");
- return -ENODEV;
- }
- k_work_init(&data->gps_work, _gps_work_handler);
- #ifdef CONFIG_SENSOR_GPS_UART_DMA
- uart_dma_receive_init((struct device *)data->uart_gpio_dev, uart_ctrl_rx_dma_handler, NULL);
- uart_rx_dma_switch((struct device *)data->uart_gpio_dev, TRUE, NULL, NULL);
- #else
- uart_irq_callback_set(data->uart_gpio_dev, uart_fifo_callback);
- data->gpa_data_cur = 0;
- #endif // CONFIG_SENSOR_GPS_UART_DMA
- return 0;
- }
- #if IS_ENABLED(CONFIG_GPS)
- DEVICE_DEFINE(ag3352, CONFIG_GPS_DEV_NAME, &ag3352_init, NULL, &ag3352_data, NULL, POST_KERNEL, 60,
- &ag3352_api);
- #endif
|