From ab4ea8c8f5335209901b835e1dfdd25aef1e4fb2 Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Thu, 2 Apr 2026 21:34:31 -0400 Subject: [PATCH 01/11] init --- drivers/sensors/ubm10.c | 25 +++++++++++++++++++++++++ include/nuttx/sensors/ubm10.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 drivers/sensors/ubm10.c create mode 100644 include/nuttx/sensors/ubm10.h diff --git a/drivers/sensors/ubm10.c b/drivers/sensors/ubm10.c new file mode 100644 index 0000000000000..7605828b1ffbf --- /dev/null +++ b/drivers/sensors/ubm10.c @@ -0,0 +1,25 @@ +/**************************************************************************** + * drivers/sensors/ubm10.c + * + * NOTE: EXPERIMENTAL DRIVER for the U-Blox M10 GNSS Chip + * + * Contributed by Carleton University InSpace + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ diff --git a/include/nuttx/sensors/ubm10.h b/include/nuttx/sensors/ubm10.h new file mode 100644 index 0000000000000..224e9eadd3d2e --- /dev/null +++ b/include/nuttx/sensors/ubm10.h @@ -0,0 +1,28 @@ +/**************************************************************************** + * drivers/sensors/ubm10.h + * + * NOTE: EXPERIMENTAL DRIVER for the U-Blox M10 GNSS Chip + * + * Contributed by Carleton University InSpace + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + + + #define UBM10_BAUD_RATE 19200 \ No newline at end of file From a73173360ae3b3e41277eb8531b11cb653c6aa5d Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Fri, 3 Apr 2026 19:20:54 -0400 Subject: [PATCH 02/11] Fix baud rate --- include/nuttx/sensors/ubm10.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/nuttx/sensors/ubm10.h b/include/nuttx/sensors/ubm10.h index 224e9eadd3d2e..6bddab286ca75 100644 --- a/include/nuttx/sensors/ubm10.h +++ b/include/nuttx/sensors/ubm10.h @@ -25,4 +25,8 @@ ****************************************************************************/ - #define UBM10_BAUD_RATE 19200 \ No newline at end of file + #define UBM10_BAUD_RATE 38400 + + /* Depending on the start byte we decide which protocol we should be parsing. */ + #define UBLOX_PROTOCOL_START_BYTE 0xB5 + #define NMEA_PROTOCOL_START_BYTE 0x24 /* '$' in Hex */ \ No newline at end of file From b6b2bd10f0f92b3f11b672b37469c20edfeb0ebd Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Tue, 7 Apr 2026 16:54:12 -0400 Subject: [PATCH 03/11] Start configuring drivers --- include/nuttx/sensors/ubm10.h | 43 +++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/include/nuttx/sensors/ubm10.h b/include/nuttx/sensors/ubm10.h index 6bddab286ca75..671e4fa45d6cc 100644 --- a/include/nuttx/sensors/ubm10.h +++ b/include/nuttx/sensors/ubm10.h @@ -24,9 +24,44 @@ * ****************************************************************************/ +#ifndef __DRIVERS_GPS_UBX_M10_H +#define __DRIVERS_GPS_UBX_M10_H - #define UBM10_BAUD_RATE 38400 +#include +#include - /* Depending on the start byte we decide which protocol we should be parsing. */ - #define UBLOX_PROTOCOL_START_BYTE 0xB5 - #define NMEA_PROTOCOL_START_BYTE 0x24 /* '$' in Hex */ \ No newline at end of file +#define UBM10_BAUD_RATE 38400 +#define UBM10_THREAD_STACK_SIZE 10000 + +/* Depending on the start byte we decide which protocol we should be parsing. */ +#define UBX_PROTOCOL_SYNC_BYTE_1 0xB5 +#define UBX_PROTOCOL_SYNC_BYTE_2 0x62 +#define NMEA_PROTOCOL_START_BYTE 0x24 /* '$' in Hex */ + +#define UBX_PROTOCOL_ACK_RETRY_COUNT 5 +#define MINMEA_MAX_LENGTH 256 + + +typedef struct { + uint8_t cls; + uint8_t id; +} ubx_msg_id; + +/* UBX Acknowledge Messages, outputs */ +static const ubx_msg_id UBX_ACK_ACK = { 0x5, 0x01 }; +static const ubx_msg_id UBX_ACK_NAK = { 0x5, 0x00 }; + +/* UBX Configuration Messages*/ + + +/* Need to figure out how to send to uorb */ + +/* Private functions or something like that */ +/* Init module */ +/* Send command */ +/* Parse response */ + +/* Public functions */ +/* Register module */ + +#endif \ No newline at end of file From f5db5ffc1ea65852bc083070b7425bab48c53e21 Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Tue, 7 Apr 2026 16:54:43 -0400 Subject: [PATCH 04/11] Rename to uorb - following uorb guide in docs --- drivers/sensors/{ubm10.c => ubm10_uorb.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename drivers/sensors/{ubm10.c => ubm10_uorb.c} (100%) diff --git a/drivers/sensors/ubm10.c b/drivers/sensors/ubm10_uorb.c similarity index 100% rename from drivers/sensors/ubm10.c rename to drivers/sensors/ubm10_uorb.c From 8ccf41b7f894ab8d51e7a80bb1971e79329caabf Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:42:20 -0400 Subject: [PATCH 05/11] Start working on uorb integration and payloads --- drivers/sensors/ubm10_uorb.c | 25 ------ drivers/sensors/ubxm10_uorb.c | 89 +++++++++++++++++++++ include/nuttx/sensors/ioctl.h | 3 +- include/nuttx/sensors/{ubm10.h => ubxm10.h} | 53 ++++++++++-- 4 files changed, 137 insertions(+), 33 deletions(-) delete mode 100644 drivers/sensors/ubm10_uorb.c create mode 100644 drivers/sensors/ubxm10_uorb.c rename include/nuttx/sensors/{ubm10.h => ubxm10.h} (54%) diff --git a/drivers/sensors/ubm10_uorb.c b/drivers/sensors/ubm10_uorb.c deleted file mode 100644 index 7605828b1ffbf..0000000000000 --- a/drivers/sensors/ubm10_uorb.c +++ /dev/null @@ -1,25 +0,0 @@ -/**************************************************************************** - * drivers/sensors/ubm10.c - * - * NOTE: EXPERIMENTAL DRIVER for the U-Blox M10 GNSS Chip - * - * Contributed by Carleton University InSpace - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ diff --git a/drivers/sensors/ubxm10_uorb.c b/drivers/sensors/ubxm10_uorb.c new file mode 100644 index 0000000000000..714d54f54b329 --- /dev/null +++ b/drivers/sensors/ubxm10_uorb.c @@ -0,0 +1,89 @@ +/**************************************************************************** + * drivers/sensors/ubxm10_uorb.c + * + * NOTE: EXPERIMENTAL DRIVER for the U-Blox M10 GNSS Chip + * + * Contributed by Carleton University InSpace + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#include +#include + +static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, int cmd, unsigned long arg) { + + + FAR ubxm10_dev_s *dev = container_of(lower, FAR ubxm10_dev_s, lower); + const ubx_cmd_id_t *ubx_cmd_id; + + /* TEMPORARY UNTIL IMPL THE INTERVAL AND BAUD RATE COMMANDS. THOSE USE UBX_CFG_VALSET */ + uint8_t ubx_payload[4]; /* Init 4 byte payload. The only msg we are sending is UBX_CFG_RST for the power as of now and that takes only 4 bytes. */ + + switch(cmd) { + + case SNIOC_HOT_START: + ubx_cmd_id = &UBX_CFG_RST; + + /* Hot start payload - clear nothing */ + ubx_payload[0] = 0x00; /* navBbrMask low byte */ + ubx_payload[1] = 0x00; /* navBbrMask high byte */ + ubx_payload[2] = 0x00; /* resetMode */ + ubx_payload[3] = 0x00; /* reserved */ + + break; + + case SNIOC_WARM_START: + ubx_cmd_id = &UBX_CFG_RST; + + /* Warm start payload - clear ephemeris only */ + /* NOTE: Payload is in little-endian byte order, meaning low bytes are fed first then the high byte. + For example the navBbrMask here actually comes out to 0x0001 but the low 0x01 is fed before the high 0x00. */ + ubx_payload[0] = 0x01; /* navBbrMask low byte */ + ubx_payload[1] = 0x00; /* navBbrMask high byte */ + ubx_payload[2] = 0x00; /* resetMode */ + ubx_payload[3] = 0x00; /* reserved */ + + break; + + case SNIOC_COLD_START: + ubx_cmd_id = &UBX_CFG_RST; + + /* Cold start payload - clear everything */ + ubx_payload[0] = 0xFF; /* navBbrMask low byte */ + ubx_payload[1] = 0xFF; /* navBbrMask high byte */ + ubx_payload[2] = 0x00; /* resetMode */ + ubx_payload[3] = 0x00; /* reserved */ + + break; + + // case SNIOC_SET_INTERVAL: + + // case SNIOC_SET_BAUD: + + } + + + /* With the UBX_CFG_RST commands, no ack is guaranteed so we just send it off and hope for the best */ + + /* Note that we need to add the sync words, length, payload, checksum into one frame. */ + + + return 0; +} \ No newline at end of file diff --git a/include/nuttx/sensors/ioctl.h b/include/nuttx/sensors/ioctl.h index ff2e6b7d0ab51..886579708dd1d 100644 --- a/include/nuttx/sensors/ioctl.h +++ b/include/nuttx/sensors/ioctl.h @@ -504,13 +504,14 @@ #define SNIOC_SET_BAUD _SNIOC(0x00A4) -/* IOCTL commands unique to the L86XXX and other GNSS modules */ +/* IOCTL commands unique to the L86XXX, UBX M10, and other GNSS modules */ #define SNIOC_HOT_START _SNIOC(0X00A5) #define SNIOC_WARM_START _SNIOC(0X00A6) #define SNIOC_COLD_START _SNIOC(0X00A7) #define SNIOC_FULL_COLD_START _SNIOC(0X00A8) + /**************************************************************************** * Public types ****************************************************************************/ diff --git a/include/nuttx/sensors/ubm10.h b/include/nuttx/sensors/ubxm10.h similarity index 54% rename from include/nuttx/sensors/ubm10.h rename to include/nuttx/sensors/ubxm10.h index 671e4fa45d6cc..eaee3a4b166c9 100644 --- a/include/nuttx/sensors/ubm10.h +++ b/include/nuttx/sensors/ubxm10.h @@ -1,5 +1,5 @@ /**************************************************************************** - * drivers/sensors/ubm10.h + * drivers/sensors/ubxm10.h * * NOTE: EXPERIMENTAL DRIVER for the U-Blox M10 GNSS Chip * @@ -30,8 +30,8 @@ #include #include -#define UBM10_BAUD_RATE 38400 -#define UBM10_THREAD_STACK_SIZE 10000 +#define UBXM10_BAUD_RATE 38400 +#define UBXM10_THREAD_STACK_SIZE 10000 /* Depending on the start byte we decide which protocol we should be parsing. */ #define UBX_PROTOCOL_SYNC_BYTE_1 0xB5 @@ -39,19 +39,58 @@ #define NMEA_PROTOCOL_START_BYTE 0x24 /* '$' in Hex */ #define UBX_PROTOCOL_ACK_RETRY_COUNT 5 -#define MINMEA_MAX_LENGTH 256 +#define UBX_PROTOCOL_BUFFER_MAX_LENGTH 256 +static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, + FAR struct file *filep, int cmd, + unsigned long arg); +static int ubxm10_activate(FAR struct gnss_lowerhalf_s *lower, + FAR struct file *filep, bool enable); +static int ubxm10_set_interval(FAR struct gnss_lowerhalf_s *lower, + FAR struct file *filep, + FAR uint32_t *period_us); + + + + +typedef struct +{ + FAR struct file uart; /* UART interface to get data */ + struct gnss_lowerhalf_s lower; /* GNSS lower-half */ + bool enabled; /* Enabled state */ + char buffer[UBX_PROTOCOL_BUFFER_MAX_LENGTH]; /* UART read buffer */ + mutex_t lock; /* Device lock */ + sem_t run; /* Start/stop kthread */ +} ubxm10_dev_s; typedef struct { uint8_t cls; uint8_t id; -} ubx_msg_id; +} ubx_cmd_id_t; + +static const struct gnss_ops_s g_gnss_ops = +{ + .control = ubxm10_control, + .activate = ubxm10_activate, + .set_interval = ubxm10_set_interval, +}; + + + + +// static int send_command(ubxm10_dev_s *dev, +// ubx_cmd_id_t cmd, unsigned long arg); +// static int read_line(ubxm10_dev_s *dev); + + + /* UBX Acknowledge Messages, outputs */ -static const ubx_msg_id UBX_ACK_ACK = { 0x5, 0x01 }; -static const ubx_msg_id UBX_ACK_NAK = { 0x5, 0x00 }; +static const ubx_cmd_id_t UBX_ACK_ACK = { 0x5, 0x01 }; +static const ubx_cmd_id_t UBX_ACK_NAK = { 0x5, 0x00 }; /* UBX Configuration Messages*/ +static const ubx_cmd_id_t UBX_CFG_RST = { 0x06, 0x04 }; /* Reset and power config */ /* Need to figure out how to send to uorb */ From ba660241ac07ce75098454cbb889c57406051ac4 Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Fri, 10 Apr 2026 00:42:31 -0400 Subject: [PATCH 06/11] Write and create frame function --- drivers/sensors/ubxm10_uorb.c | 112 +++++++++++++++++++++------------ include/nuttx/sensors/ubxm10.h | 2 +- 2 files changed, 72 insertions(+), 42 deletions(-) diff --git a/drivers/sensors/ubxm10_uorb.c b/drivers/sensors/ubxm10_uorb.c index 714d54f54b329..df463f8d43c92 100644 --- a/drivers/sensors/ubxm10_uorb.c +++ b/drivers/sensors/ubxm10_uorb.c @@ -27,63 +27,93 @@ #include #include -static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, int cmd, unsigned long arg) { +/* Builds the UBX payload frame into out_frame and the total frame size. + * out_frame must be at least (payload_len + 8) bytes. + * Frame format: [sync1][sync2][class][id][len_lo][len_hi][payload...][ck_a][ck_b] + */ +int ubxm10_create_frame(const ubx_cmd_id_t *ubx_cmd_id, const uint8_t *payload, uint16_t payload_len, uint8_t *out_frame) { + int i; + uint8_t ck_a = 0; + uint8_t ck_b = 0; + int frame_size = 6 + payload_len + 2; + + /* Sync bytes */ + out_frame[0] = UBX_PROTOCOL_SYNC_BYTE_1; + out_frame[1] = UBX_PROTOCOL_SYNC_BYTE_2; + + /* Class and ID */ + out_frame[2] = ubx_cmd_id->cls; + out_frame[3] = ubx_cmd_id->id; + + /* Payload length (little-endian) */ + out_frame[4] = (uint8_t)(payload_len & 0xFF); + out_frame[5] = (uint8_t)((payload_len >> 8) & 0xFF); + + /* Copy payload */ + for (i = 0; i < payload_len; i++) + { + out_frame[6 + i] = payload[i]; + } + + /* 8-bit Fletcher checksum over class, id, length, and payload. Start at i=2 since sync bytes shouldnt be included in checksum. */ + for (i = 2; i < 6 + payload_len; i++) + { + ck_a += out_frame[i]; + ck_b += ck_a; + } + + out_frame[6 + payload_len] = ck_a; + out_frame[7 + payload_len] = ck_b; + return frame_size; +} + +static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, int cmd, unsigned long arg) { FAR ubxm10_dev_s *dev = container_of(lower, FAR ubxm10_dev_s, lower); - const ubx_cmd_id_t *ubx_cmd_id; + uint8_t frame[UBX_PROTOCOL_BUFFER_MAX_LENGTH]; + int frame_len; - /* TEMPORARY UNTIL IMPL THE INTERVAL AND BAUD RATE COMMANDS. THOSE USE UBX_CFG_VALSET */ - uint8_t ubx_payload[4]; /* Init 4 byte payload. The only msg we are sending is UBX_CFG_RST for the power as of now and that takes only 4 bytes. */ - switch(cmd) { case SNIOC_HOT_START: - ubx_cmd_id = &UBX_CFG_RST; - + { /* Hot start payload - clear nothing */ - ubx_payload[0] = 0x00; /* navBbrMask low byte */ - ubx_payload[1] = 0x00; /* navBbrMask high byte */ - ubx_payload[2] = 0x00; /* resetMode */ - ubx_payload[3] = 0x00; /* reserved */ + uint8_t payload[4] = { 0x00, 0x00, 0x00, 0x00}; + + frame_len = ubxm10_create_frame(&UBX_CFG_RST, payload, 4, frame); - break; + /* UBX-CFG-RST does not guarantee an ACK, so just send it */ + return file_write(&dev->uart, frame, frame_len); + } case SNIOC_WARM_START: - ubx_cmd_id = &UBX_CFG_RST; - - /* Warm start payload - clear ephemeris only */ - /* NOTE: Payload is in little-endian byte order, meaning low bytes are fed first then the high byte. - For example the navBbrMask here actually comes out to 0x0001 but the low 0x01 is fed before the high 0x00. */ - ubx_payload[0] = 0x01; /* navBbrMask low byte */ - ubx_payload[1] = 0x00; /* navBbrMask high byte */ - ubx_payload[2] = 0x00; /* resetMode */ - ubx_payload[3] = 0x00; /* reserved */ - - break; + { + /* Warm start payload - clear ephemeris only (navBbrMask = 0x0001 little-endian) */ + uint8_t payload[4] = { 0x01, 0x00, 0x00, 0x00 }; + frame_len = ubxm10_create_frame(&UBX_CFG_RST, payload, 4, frame); - case SNIOC_COLD_START: - ubx_cmd_id = &UBX_CFG_RST; - - /* Cold start payload - clear everything */ - ubx_payload[0] = 0xFF; /* navBbrMask low byte */ - ubx_payload[1] = 0xFF; /* navBbrMask high byte */ - ubx_payload[2] = 0x00; /* resetMode */ - ubx_payload[3] = 0x00; /* reserved */ - - break; - - // case SNIOC_SET_INTERVAL: - - // case SNIOC_SET_BAUD: + /* UBX-CFG-RST does not guarantee an ACK, so just send it */ + return file_write(&dev->uart, frame, frame_len); + } - } + case SNIOC_COLD_START: + { + /* Cold start payload - clear everything (navBbrMask = 0xFFFF little-endian) */ + uint8_t payload[4] = { 0xFF, 0xFF, 0x00, 0x00} ; + frame_len = ubxm10_create_frame(&UBX_CFG_RST, payload, 4, frame); - /* With the UBX_CFG_RST commands, no ack is guaranteed so we just send it off and hope for the best */ + /* UBX-CFG-RST does not guarantee an ACK, so just send it */ + return file_write(&dev->uart, frame, frame_len); + } - /* Note that we need to add the sync words, length, payload, checksum into one frame. */ + // case SNIOC_SET_INTERVAL: + // case SNIOC_SET_BAUD: + default: + return -ENOTTY; + } - return 0; + } \ No newline at end of file diff --git a/include/nuttx/sensors/ubxm10.h b/include/nuttx/sensors/ubxm10.h index eaee3a4b166c9..bd67781da0c41 100644 --- a/include/nuttx/sensors/ubxm10.h +++ b/include/nuttx/sensors/ubxm10.h @@ -50,7 +50,7 @@ static int ubxm10_set_interval(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, FAR uint32_t *period_us); - +int ubxm10_create_frame(const ubx_cmd_id_t *ubx_cmd_id, const uint8_t *payload, uint16_t payload_len, uint8_t *out_frame); typedef struct From 703bd19b7c1767b6b3a1f4fa0c668908c3605181 Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Fri, 10 Apr 2026 01:53:06 -0400 Subject: [PATCH 07/11] Set interval function --- drivers/sensors/ubxm10_uorb.c | 153 ++++++++++++++++++++++++++++++++- include/nuttx/sensors/ubxm10.h | 1 + 2 files changed, 150 insertions(+), 4 deletions(-) diff --git a/drivers/sensors/ubxm10_uorb.c b/drivers/sensors/ubxm10_uorb.c index df463f8d43c92..82dd4a898e7d3 100644 --- a/drivers/sensors/ubxm10_uorb.c +++ b/drivers/sensors/ubxm10_uorb.c @@ -27,6 +27,107 @@ #include #include +/**************************************************************************** + * Name: ubxm10_wait_ack + * + * Description: + * Reads from UART looking for a UBX-ACK-ACK or UBX-ACK-NAK response + * matching the class/id of the command that was sent. + * + * Returns: + * 0 - ACK received + * -EIO - NAK received + * -ETIMEDOUT - No ACK/NAK after retries + ****************************************************************************/ + +static int ubxm10_wait_ack(ubxm10_dev_s *dev, const ubx_cmd_id_t *sent_cmd) +{ + uint8_t byte; + int retries; + int index; + uint8_t header[6]; + uint8_t ack_payload[2]; + uint8_t ck[2]; + int err; + + for (retries = 0; retries < UBX_PROTOCOL_ACK_RETRY_COUNT; retries++) + { + index = 0; + + /* Parse through bytes looking for a full UBX header */ + while (index < 6){ + err = file_read(&dev->uart, &byte, 1); + if (err <= 0) { + break; + } + + switch (index) { + case 0: + if (byte == UBX_PROTOCOL_SYNC_BYTE_1) { + header[0] = byte; + index = 1; + } + + break; + + case 1: + if (byte == UBX_PROTOCOL_SYNC_BYTE_2) { + header[1] = byte; + index = 2; + } else { + index = 0; + } + + break; + + default: + header[index] = byte; + index++; + break; + } + } + + if (index < 6) { + continue; + } + + /* Check if this is an ACK class */ + if (header[2] != UBX_ACK_ACK.cls) { + continue; + } + + /* Read the 2-byte payload (class and id being acknowledged) */ + err = file_read(&dev->uart, ack_payload, 2); + + if (err < 2) { + continue; + } + + /* Read and discard the 2 checksum bytes */ + file_read(&dev->uart, ck, 2); + + /* Check if this ACK/NAK is for the command we sent */ + if (ack_payload[0] != sent_cmd->cls || + ack_payload[1] != sent_cmd->id) { + continue; + } + + /* Match found - check if ACK or NAK */ + if (header[3] == UBX_ACK_ACK.id) { + sninfo("UBX ACK received\n"); + + return 0; + } else if (header[3] == UBX_ACK_NAK.id) { + snerr("UBX NAK received\n"); + + return -EIO; + } + } + + snerr("Timed out waiting for UBX ACK\n"); + return -ETIMEDOUT; +} + /* Builds the UBX payload frame into out_frame and the total frame size. * out_frame must be at least (payload_len + 8) bytes. * Frame format: [sync1][sync2][class][id][len_lo][len_hi][payload...][ck_a][ck_b] @@ -73,6 +174,7 @@ static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *f FAR ubxm10_dev_s *dev = container_of(lower, FAR ubxm10_dev_s, lower); uint8_t frame[UBX_PROTOCOL_BUFFER_MAX_LENGTH]; int frame_len; + int write_ret; switch(cmd) { @@ -83,8 +185,10 @@ static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *f frame_len = ubxm10_create_frame(&UBX_CFG_RST, payload, 4, frame); + nxmutex_lock(&dev->lock); /* UBX-CFG-RST does not guarantee an ACK, so just send it */ - return file_write(&dev->uart, frame, frame_len); + write_ret = file_write(&dev->uart, frame, frame_len); + nxmutex_unlock(&dev->lock); } case SNIOC_WARM_START: @@ -93,8 +197,10 @@ static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *f uint8_t payload[4] = { 0x01, 0x00, 0x00, 0x00 }; frame_len = ubxm10_create_frame(&UBX_CFG_RST, payload, 4, frame); + nxmutex_lock(&dev->lock); /* UBX-CFG-RST does not guarantee an ACK, so just send it */ - return file_write(&dev->uart, frame, frame_len); + write_ret = file_write(&dev->uart, frame, frame_len); + nxmutex_unlock(&dev->lock); } case SNIOC_COLD_START: @@ -104,16 +210,55 @@ static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *f uint8_t payload[4] = { 0xFF, 0xFF, 0x00, 0x00} ; frame_len = ubxm10_create_frame(&UBX_CFG_RST, payload, 4, frame); + nxmutex_lock(&dev->lock); /* UBX-CFG-RST does not guarantee an ACK, so just send it */ - return file_write(&dev->uart, frame, frame_len); + write_ret = file_write(&dev->uart, frame, frame_len); + nxmutex_unlock(&dev->lock); + } + + case SNIOC_SET_INTERVAL: + { + + /* UBX-CFG-VALSET Set Interval Payload */ + + uint8_t payload[9] = { + 0x00, 0x01, 0x00, /* Message version, ram only, reserved. */ + 0x01, 0x00, 0x21, 0x30, /* Key ID for CFG-RATE-MEAS in little endian. */ + (uint8_t)(arg & 0xFF), /* Value in ms low byte */ + (uint8_t)((arg >> 8) & 0xFF), /* Value in ms high byte */ + }; + + frame_len = ubxm10_create_frame(&UBX_CFG_VALSET, payload, 9, frame); + + nxmutex_lock(&dev->lock); + + write_ret = file_write(&dev->uart, frame, frame_len); + + if (write_ret < 0) { + nxmutex_unlock(&dev->lock); + snerr("Failed to send SET_INTERVAL frame\n"); + return write_ret; + } + + int ack_ret = ubxm10_wait_ack(dev, &UBX_CFG_VALSET); + nxmutex_unlock(&dev->lock); + + return ack_ret; } - // case SNIOC_SET_INTERVAL: // case SNIOC_SET_BAUD: default: return -ENOTTY; } + if (write_ret < 0) + { + snerr("Failed to send command frame to device\n"); + return write_ret; + } + + return 0; + } \ No newline at end of file diff --git a/include/nuttx/sensors/ubxm10.h b/include/nuttx/sensors/ubxm10.h index bd67781da0c41..630b18dd4e1fb 100644 --- a/include/nuttx/sensors/ubxm10.h +++ b/include/nuttx/sensors/ubxm10.h @@ -91,6 +91,7 @@ static const ubx_cmd_id_t UBX_ACK_NAK = { 0x5, 0x00 }; /* UBX Configuration Messages*/ static const ubx_cmd_id_t UBX_CFG_RST = { 0x06, 0x04 }; /* Reset and power config */ +static const ubx_cmd_id_t UBX_CFG_VALSET = { 0x06, 0x8a }; /* Set config value */ /* Need to figure out how to send to uorb */ From 3cfd890df5706ebe7a5a0becc7b43583cb66d94b Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Fri, 10 Apr 2026 01:55:37 -0400 Subject: [PATCH 08/11] Fix reserved size --- drivers/sensors/ubxm10_uorb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/sensors/ubxm10_uorb.c b/drivers/sensors/ubxm10_uorb.c index 82dd4a898e7d3..92c60a2f12494 100644 --- a/drivers/sensors/ubxm10_uorb.c +++ b/drivers/sensors/ubxm10_uorb.c @@ -221,14 +221,14 @@ static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *f /* UBX-CFG-VALSET Set Interval Payload */ - uint8_t payload[9] = { - 0x00, 0x01, 0x00, /* Message version, ram only, reserved. */ + uint8_t payload[10] = { + 0x00, 0x01, 0x00, 0x00, /* Message version, ram only, reserved, reserved. */ 0x01, 0x00, 0x21, 0x30, /* Key ID for CFG-RATE-MEAS in little endian. */ (uint8_t)(arg & 0xFF), /* Value in ms low byte */ (uint8_t)((arg >> 8) & 0xFF), /* Value in ms high byte */ }; - frame_len = ubxm10_create_frame(&UBX_CFG_VALSET, payload, 9, frame); + frame_len = ubxm10_create_frame(&UBX_CFG_VALSET, payload, 10, frame); nxmutex_lock(&dev->lock); From a95e4b7804d209079bd59340a59dc59db1474745 Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Sat, 25 Apr 2026 16:31:17 -0400 Subject: [PATCH 09/11] Uorb integration --- drivers/sensors/Kconfig | 13 ++ drivers/sensors/Make.defs | 4 + drivers/sensors/ubxm10_uorb.c | 354 +++++++++++++++++++++++++++++++++- 3 files changed, 368 insertions(+), 3 deletions(-) diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index 25f817f9a4d2a..71af6a35194cf 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -858,6 +858,19 @@ config L86_XXX_BAUD ---help--- Supported values are: 4800, 9600, 14400, 19200, 38400, 57600 and 115200 +config SENSORS_UBXM10 + bool "u-blox M10 GNSS support" + default n + depends on SERIAL && STANDARD_SERIAL && UORB && SENSORS_GNSS + ---help--- + Enable driver support for the u-blox M10 series of GNSS modules + using the UBX binary protocol over UART. + +config SENSORS_UBXM10_THREAD_STACKSIZE + int "Stack size for UBX M10 module collection thread" + default 10000 + depends on SENSORS_UBXM10 + config SENSORS_LIS2DH bool "STMicro LIS2DH device support" default n diff --git a/drivers/sensors/Make.defs b/drivers/sensors/Make.defs index 870afeb40dfac..b3a3e23e81a67 100644 --- a/drivers/sensors/Make.defs +++ b/drivers/sensors/Make.defs @@ -42,6 +42,10 @@ ifeq ($(CONFIG_SENSORS_L86_XXX),y) CSRCS += l86xxx_uorb.c endif +ifeq ($(CONFIG_SENSORS_UBXM10),y) + CSRCS += ubxm10_uorb.c +endif + ifeq ($(CONFIG_SENSORS_GNSS),y) CSRCS += gnss_uorb.c endif diff --git a/drivers/sensors/ubxm10_uorb.c b/drivers/sensors/ubxm10_uorb.c index 92c60a2f12494..35afc6bc60d0f 100644 --- a/drivers/sensors/ubxm10_uorb.c +++ b/drivers/sensors/ubxm10_uorb.c @@ -24,9 +24,36 @@ * ****************************************************************************/ -#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include #include +#include + +#ifndef CONFIG_SENSORS_UBXM10_THREAD_STACKSIZE +#define CONFIG_SENSORS_UBXM10_THREAD_STACKSIZE UBXM10_THREAD_STACK_SIZE +#endif + /**************************************************************************** * Name: ubxm10_wait_ack * @@ -169,6 +196,57 @@ int ubxm10_create_frame(const ubx_cmd_id_t *ubx_cmd_id, const uint8_t *payload, return frame_size; } +#ifdef CONFIG_SERIAL_TERMIOS +/**************************************************************************** + * Name: ubxm10_set_host_baud + * + * Description: + * Updates the host UART baud rate via termios after the module has been + * told (via UBX-CFG-VALSET) to switch its own UART baud rate. + ****************************************************************************/ + +static int ubxm10_set_host_baud(ubxm10_dev_s *dev, int baud) +{ + struct termios opt; + int err; + + err = file_ioctl(&dev->uart, TCGETS, &opt); + if (err < 0) + { + snwarn("Couldn't get interface settings: %d\n", err); + return err; + } + + cfmakeraw(&opt); + + switch (baud) + { + case 9600: + case 19200: + case 38400: + case 57600: + case 115200: + case 230400: + case 460800: + cfsetispeed(&opt, baud); + cfsetospeed(&opt, baud); + break; + + default: + snerr("Invalid baud rate: %d\n", baud); + return -EINVAL; + } + + err = file_ioctl(&dev->uart, TCSETS, &opt); + if (err < 0) + { + snerr("Couldn't set host UART baud: %d\n", err); + } + + return err; +} +#endif + static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *filep, int cmd, unsigned long arg) { FAR ubxm10_dev_s *dev = container_of(lower, FAR ubxm10_dev_s, lower); @@ -189,6 +267,7 @@ static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *f /* UBX-CFG-RST does not guarantee an ACK, so just send it */ write_ret = file_write(&dev->uart, frame, frame_len); nxmutex_unlock(&dev->lock); + break; } case SNIOC_WARM_START: @@ -201,6 +280,7 @@ static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *f /* UBX-CFG-RST does not guarantee an ACK, so just send it */ write_ret = file_write(&dev->uart, frame, frame_len); nxmutex_unlock(&dev->lock); + break; } case SNIOC_COLD_START: @@ -214,6 +294,7 @@ static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *f /* UBX-CFG-RST does not guarantee an ACK, so just send it */ write_ret = file_write(&dev->uart, frame, frame_len); nxmutex_unlock(&dev->lock); + break; } case SNIOC_SET_INTERVAL: @@ -246,7 +327,45 @@ static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *f return ack_ret; } - // case SNIOC_SET_BAUD: + case SNIOC_SET_BAUD: + { + /* UBX-CFG-VALSET with CFG-UART1-BAUDRATE key (U4 value, 4 bytes) */ + uint8_t payload[12] = { + 0x00, 0x01, 0x00, 0x00, /* version, layers=RAM, reserved */ + 0x01, 0x00, 0x52, 0x40, /* CFG-UART1-BAUDRATE key (0x40520001 LE) */ + (uint8_t)(arg & 0xFF), + (uint8_t)((arg >> 8) & 0xFF), + (uint8_t)((arg >> 16) & 0xFF), + (uint8_t)((arg >> 24) & 0xFF), + }; + + frame_len = ubxm10_create_frame(&UBX_CFG_VALSET, payload, 12, frame); + + nxmutex_lock(&dev->lock); + write_ret = file_write(&dev->uart, frame, frame_len); + if (write_ret < 0) + { + nxmutex_unlock(&dev->lock); + snerr("Failed to send SET_BAUD frame\n"); + return write_ret; + } + + int baud_ack = ubxm10_wait_ack(dev, &UBX_CFG_VALSET); + nxmutex_unlock(&dev->lock); + + if (baud_ack < 0) + { + return baud_ack; + } + +#ifdef CONFIG_SERIAL_TERMIOS + /* Give module time to switch before changing our own UART */ + nxsig_usleep(20000); + return ubxm10_set_host_baud(dev, (int)arg); +#else + return -ENOSYS; +#endif + } default: return -ENOTTY; @@ -259,6 +378,235 @@ static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, FAR struct file *f } return 0; +} + +/**************************************************************************** + * Name: ubxm10_activate + * + * Description: + * Enable or disable the GNSS module. When enabled, posts the run + * semaphore so the polling kthread starts reading from UART. + ****************************************************************************/ + +static int ubxm10_activate(FAR struct gnss_lowerhalf_s *lower, + FAR struct file *filep, bool enable) +{ + FAR ubxm10_dev_s *dev = container_of(lower, FAR ubxm10_dev_s, lower); + + if (enable && !dev->enabled) + { + nxsem_post(&dev->run); + dev->enabled = true; + } + else if (!enable && dev->enabled) + { + dev->enabled = false; + } + + return 0; +} + +/**************************************************************************** + * Name: ubxm10_set_interval + * + * Description: + * Sets the measurement interval of the UBX M10 by sending a UBX-CFG-VALSET + * with the CFG-RATE-MEAS key. period_us is converted to ms. + ****************************************************************************/ + +static int ubxm10_set_interval(FAR struct gnss_lowerhalf_s *lower, + FAR struct file *filep, + FAR uint32_t *period_us) +{ + FAR ubxm10_dev_s *dev = container_of(lower, FAR ubxm10_dev_s, lower); + uint32_t period_ms = *period_us / 1000; + uint8_t frame[UBX_PROTOCOL_BUFFER_MAX_LENGTH]; + int frame_len; + int write_ret; + int ack_ret; + + if (period_ms < 25 || period_ms > 65535) + { + return -EINVAL; + } + + uint8_t payload[10] = { + 0x00, 0x01, 0x00, 0x00, /* version, layers=RAM, reserved */ + 0x01, 0x00, 0x21, 0x30, /* CFG-RATE-MEAS key (little-endian) */ + (uint8_t)(period_ms & 0xFF), + (uint8_t)((period_ms >> 8) & 0xFF), + }; + + frame_len = ubxm10_create_frame(&UBX_CFG_VALSET, payload, 10, frame); + + nxmutex_lock(&dev->lock); + write_ret = file_write(&dev->uart, frame, frame_len); + if (write_ret < 0) + { + nxmutex_unlock(&dev->lock); + return write_ret; + } + + ack_ret = ubxm10_wait_ack(dev, &UBX_CFG_VALSET); + nxmutex_unlock(&dev->lock); + return ack_ret; +} + +/**************************************************************************** + * Name: ubxm10_thread + * + * Description: + * Kernel thread that polls the UART, then pushes raw bytes to the GNSS + * upper-half for NMEA parsing. + ****************************************************************************/ + +static int ubxm10_thread(int argc, FAR char *argv[]) +{ + FAR ubxm10_dev_s *dev = + (FAR ubxm10_dev_s *)((uintptr_t)strtoul(argv[1], NULL, 16)); + ssize_t bw; + int err; + + for (;;) + { + /* Wait until enabled by ubxm10_activate */ + if (!dev->enabled) + { + err = nxsem_wait(&dev->run); + if (err < 0) + { + snerr("Couldn't wait on semaphore\n"); + continue; + } + } + + nxmutex_lock(&dev->lock); + bw = file_read(&dev->uart, dev->buffer, sizeof(dev->buffer)); + + if (bw <= 0) + { + snerr("No data on UART: %d\n", (int)bw); + nxmutex_unlock(&dev->lock); + continue; + } + + /* Push raw bytes to GNSS upper-half for NMEA parsing */ + dev->lower.push_data(dev->lower.priv, dev->buffer, bw, true); + + nxmutex_unlock(&dev->lock); + } + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ubxm10_register + * + * Description: + * Register the UBX M10 GNSS driver. + * + * Arguments: + * uartpath - Path to the UART character driver connected to the module + * devno - Device number for the GNSS topic (e.g. /dev/uorb/sensor_gnss0) + ****************************************************************************/ + +int ubxm10_register(FAR const char *uartpath, int devno) +{ + FAR ubxm10_dev_s *priv = NULL; + int err; + uint32_t nbuffers[SENSOR_GNSS_IDX_GNSS_MAX]; + FAR char *argv[2]; + char arg1[32]; + + DEBUGASSERT(uartpath != NULL); + + priv = kmm_zalloc(sizeof(ubxm10_dev_s)); + if (priv == NULL) + { + snerr("Failed to allocate UBX M10 driver instance.\n"); + return -ENOMEM; + } + + err = nxmutex_init(&priv->lock); + if (err < 0) + { + snerr("Failed to initialize mutex: %d\n", err); + goto free_mem; + } + + err = nxsem_init(&priv->run, 0, 0); + if (err < 0) + { + snerr("Failed to initialize semaphore: %d\n", err); + goto destroy_mutex; + } + + err = file_open(&priv->uart, uartpath, O_RDWR | O_CLOEXEC); + if (err < 0) + { + snerr("Failed to open UART %s: %d\n", uartpath, err); + goto destroy_sem; + } + +#ifdef CONFIG_SERIAL_TERMIOS + /* Match the host UART to the module's default baud so reads/writes + * work before any runtime SET_BAUD is issued. + */ + err = ubxm10_set_host_baud(priv, UBXM10_BAUD_RATE); + if (err < 0) + { + snwarn("Failed to set initial baud rate: %d\n", err); + } +#endif + + priv->lower.ops = &g_gnss_ops; + priv->lower.priv = priv; + priv->enabled = false; + + nbuffers[SENSOR_GNSS_IDX_GNSS] = 2; + nbuffers[SENSOR_GNSS_IDX_GNSS_SATELLITE] = 1; + nbuffers[SENSOR_GNSS_IDX_GNSS_MEASUREMENT] = 1; + nbuffers[SENSOR_GNSS_IDX_GNSS_CLOCK] = 1; + nbuffers[SENSOR_GNSS_IDX_GNSS_GEOFENCE] = 1; + + err = gnss_register(&priv->lower, devno, nbuffers, + SENSOR_GNSS_IDX_GNSS_MAX); + if (err < 0) + { + snerr("Failed to register GNSS driver: %d\n", err); + goto close_file; + } + + snprintf(arg1, sizeof(arg1), "%p", priv); + argv[0] = arg1; + argv[1] = NULL; + + err = kthread_create("ubxm10_thread", SCHED_PRIORITY_DEFAULT, + CONFIG_SENSORS_UBXM10_THREAD_STACKSIZE, + ubxm10_thread, argv); + if (err < 0) + { + snerr("Failed to create ubxm10 kthread: %d\n", err); + goto sensor_unreg; + } + + sninfo("Registered UBX M10 driver on %s\n", uartpath); + return 0; - +sensor_unreg: + gnss_unregister(&priv->lower, devno); +close_file: + file_close(&priv->uart); +destroy_sem: + nxsem_destroy(&priv->run); +destroy_mutex: + nxmutex_destroy(&priv->lock); +free_mem: + kmm_free(priv); + + return err; } \ No newline at end of file From b34e96a961abe25fcc2e5894017780fd4870db62 Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Sat, 25 Apr 2026 23:37:29 -0400 Subject: [PATCH 10/11] Fix issues with bsp --- drivers/sensors/ubxm10_uorb.c | 24 +++++++++ include/nuttx/sensors/ubxm10.h | 92 ++++++++++++++++++---------------- 2 files changed, 73 insertions(+), 43 deletions(-) diff --git a/drivers/sensors/ubxm10_uorb.c b/drivers/sensors/ubxm10_uorb.c index 35afc6bc60d0f..84c92ff9c47b0 100644 --- a/drivers/sensors/ubxm10_uorb.c +++ b/drivers/sensors/ubxm10_uorb.c @@ -54,6 +54,30 @@ #define CONFIG_SENSORS_UBXM10_THREAD_STACKSIZE UBXM10_THREAD_STACK_SIZE #endif +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, + FAR struct file *filep, int cmd, + unsigned long arg); +static int ubxm10_activate(FAR struct gnss_lowerhalf_s *lower, + FAR struct file *filep, bool enable); +static int ubxm10_set_interval(FAR struct gnss_lowerhalf_s *lower, + FAR struct file *filep, + FAR uint32_t *period_us); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct gnss_ops_s g_gnss_ops = +{ + .control = ubxm10_control, + .activate = ubxm10_activate, + .set_interval = ubxm10_set_interval, +}; + /**************************************************************************** * Name: ubxm10_wait_ack * diff --git a/include/nuttx/sensors/ubxm10.h b/include/nuttx/sensors/ubxm10.h index 630b18dd4e1fb..56bd1bd633ae5 100644 --- a/include/nuttx/sensors/ubxm10.h +++ b/include/nuttx/sensors/ubxm10.h @@ -28,6 +28,13 @@ #define __DRIVERS_GPS_UBX_M10_H #include + +#include +#include + +#include +#include +#include #include #define UBXM10_BAUD_RATE 38400 @@ -41,17 +48,15 @@ #define UBX_PROTOCOL_ACK_RETRY_COUNT 5 #define UBX_PROTOCOL_BUFFER_MAX_LENGTH 256 -static int ubxm10_control(FAR struct gnss_lowerhalf_s *lower, - FAR struct file *filep, int cmd, - unsigned long arg); -static int ubxm10_activate(FAR struct gnss_lowerhalf_s *lower, - FAR struct file *filep, bool enable); -static int ubxm10_set_interval(FAR struct gnss_lowerhalf_s *lower, - FAR struct file *filep, - FAR uint32_t *period_us); - -int ubxm10_create_frame(const ubx_cmd_id_t *ubx_cmd_id, const uint8_t *payload, uint16_t payload_len, uint8_t *out_frame); +/**************************************************************************** + * Public Types + ****************************************************************************/ +typedef struct +{ + uint8_t cls; + uint8_t id; +} ubx_cmd_id_t; typedef struct { @@ -63,45 +68,46 @@ typedef struct sem_t run; /* Start/stop kthread */ } ubxm10_dev_s; -typedef struct { - uint8_t cls; - uint8_t id; -} ubx_cmd_id_t; - -static const struct gnss_ops_s g_gnss_ops = -{ - .control = ubxm10_control, - .activate = ubxm10_activate, - .set_interval = ubxm10_set_interval, -}; - - - - -// static int send_command(ubxm10_dev_s *dev, -// ubx_cmd_id_t cmd, unsigned long arg); -// static int read_line(ubxm10_dev_s *dev); - - - +/**************************************************************************** + * Public Constants + ****************************************************************************/ /* UBX Acknowledge Messages, outputs */ -static const ubx_cmd_id_t UBX_ACK_ACK = { 0x5, 0x01 }; -static const ubx_cmd_id_t UBX_ACK_NAK = { 0x5, 0x00 }; +static const ubx_cmd_id_t UBX_ACK_ACK = { 0x05, 0x01 }; +static const ubx_cmd_id_t UBX_ACK_NAK = { 0x05, 0x00 }; -/* UBX Configuration Messages*/ +/* UBX Configuration Messages */ static const ubx_cmd_id_t UBX_CFG_RST = { 0x06, 0x04 }; /* Reset and power config */ -static const ubx_cmd_id_t UBX_CFG_VALSET = { 0x06, 0x8a }; /* Set config value */ +static const ubx_cmd_id_t UBX_CFG_VALSET = { 0x06, 0x8A }; /* Set config value */ +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ -/* Need to figure out how to send to uorb */ +/**************************************************************************** + * Name: ubxm10_create_frame + * + * Description: + * Builds a UBX frame into out_frame and returns the total frame size. + * out_frame must be at least (payload_len + 8) bytes. + ****************************************************************************/ + +int ubxm10_create_frame(const ubx_cmd_id_t *ubx_cmd_id, + const uint8_t *payload, + uint16_t payload_len, + uint8_t *out_frame); -/* Private functions or something like that */ -/* Init module */ -/* Send command */ -/* Parse response */ +/**************************************************************************** + * Name: ubxm10_register + * + * Description: + * Register the UBX M10 GNSS driver. + * + * Arguments: + * uartpath - Path to the UART character driver connected to the module + * devno - Device number for the GNSS topic + ****************************************************************************/ -/* Public functions */ -/* Register module */ +int ubxm10_register(FAR const char *uartpath, int devno); -#endif \ No newline at end of file +#endif /* __DRIVERS_GPS_UBX_M10_H */ From fde2cbe9e74cffe411f53c17fbb4de082c62dd9d Mon Sep 17 00:00:00 2001 From: incogiscool <94598096+incogiscool@users.noreply.github.com> Date: Sun, 26 Apr 2026 22:02:59 -0400 Subject: [PATCH 11/11] Change baud to 9600 - 38400 doesnt work? --- include/nuttx/sensors/ubxm10.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nuttx/sensors/ubxm10.h b/include/nuttx/sensors/ubxm10.h index 56bd1bd633ae5..422ebab355fd1 100644 --- a/include/nuttx/sensors/ubxm10.h +++ b/include/nuttx/sensors/ubxm10.h @@ -37,7 +37,7 @@ #include #include -#define UBXM10_BAUD_RATE 38400 +#define UBXM10_BAUD_RATE 9600 #define UBXM10_THREAD_STACK_SIZE 10000 /* Depending on the start byte we decide which protocol we should be parsing. */