Skip to content
This repository has been archived by the owner on Nov 11, 2024. It is now read-only.

Commit

Permalink
GNSS feature addition: set/get message rate for M8/M9.
Browse files Browse the repository at this point in the history
It is now possible to get and set the rate that a given GNSS message ID is emitted with uGnssCfgGetMsgRate()/uGnssCfgSetMsgRate.  This ONLY works for M8/M9 modules: for M10 modules and later uGnssCfgValGet()/uGnssCfgValSet() with the appropriate key ID should be used as normal.
  • Loading branch information
RobMeades committed Feb 21, 2023
1 parent cb30578 commit 00b3fb2
Show file tree
Hide file tree
Showing 5 changed files with 304 additions and 6 deletions.
57 changes: 56 additions & 1 deletion gnss/api/u_gnss_cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,14 @@ int32_t uGnssCfgGetRate(uDeviceHandle_t gnssHandle,
int32_t *pNavigationCount,
uGnssTimeSystem_t *pTimeSystem);

/** Set the rate at which position is obtained.
/** Set the rate at which position is obtained. Note that, if you intend
* to obtain position at this rate using a particular protocol, you need to
* set the message rate for the navigation messsage ID on that protocol
* to a non-zero value by calling uGnssCfgSetMsgRate() with that message ID;
* by default NMEA navigation solutions (GGA etc.) are enabled at a rate of
* once for every message (so likely once a second), while the UBX-NAV
* messsages of the UBX protocol are by default set to a rate of 0
* (i.e. disabled).
*
* @param gnssHandle the handle of the GNSS instance.
* @param measurementPeriodMs the period between measurements in
Expand All @@ -225,6 +232,54 @@ int32_t uGnssCfgSetRate(uDeviceHandle_t gnssHandle,
int32_t navigationCount,
uGnssTimeSystem_t timeSystem);

/** Get the rate at which a given UBX message ID is emitted on the
* current transport; this ONLY WORKS FOR M8 AND M9 modules: for
* M10 modules and later you must find the relevant member from
* U_GNSS_CFG_VAL_KEY_ITEM_MSGOUT_* in u_gnss_cfg_val_key.h
* and get the value of that item, e.g.:
*
* ```
* uint8_t value;
* uGnssCfgValGet(devHandle,
* U_GNSS_CFG_VAL_KEY_ITEM_MSGOUT_UBX_NAV_PVT_I2C_U1,
* (void *) &value, sizeof(value),
* U_GNSS_CFG_VAL_LAYER_RAM);
* ```
*
* @param gnssHandle the handle of the GNSS instance.
* @param[in] pMessageId a pointer to the message ID; cannot
* be NULL and, for M8 modules, only UBX
* protocol message rates can currently be
* retrieved this way.
* @return on success the rate (0 for never, 1 for
* once every message, 2 for "emit every
* other message", etc.) else negative
* error code.
*/
int32_t uGnssCfgGetMsgRate(uDeviceHandle_t gnssHandle,
uGnssMessageId_t *pMessageId);

/** Set the rate at which a given UBX message ID is emitted on the
* current transport.; this ONLY WORKS FOR M8 AND M9 modules:
* for M10 modules and later you must find the relevant member
* from U_GNSS_CFG_VAL_KEY_ITEM_MSGOUT_* in u_gnss_cfg_val_key.h
* and set the value of that item, e.g.:
*
* U_GNSS_CFG_SET_VAL_RAM(devHandle, MSGOUT_UBX_NAV_PVT_I2C_U1, 1);
*
* @param gnssHandle the handle of the GNSS instance.
* @param[in] pMessageId a pointer to the message ID; cannot
* be NULL and only UBX protocol message
* rates can currently be configured this way.
* @param rate the rate: 0 for never, 1 for once every
* message, 2 for "emit every other message",
* etc.
* @return zero on success or negative error code.
*/
int32_t uGnssCfgSetMsgRate(uDeviceHandle_t gnssHandle,
uGnssMessageId_t *pMessageId,
int32_t rate);

/** Get the dynamic platform model from the GNSS chip.
*
* @param gnssHandle the handle of the GNSS instance.
Expand Down
53 changes: 53 additions & 0 deletions gnss/src/u_gnss_cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ int32_t uGnssCfgGetRate(uDeviceHandle_t gnssHandle,

U_PORT_MUTEX_LOCK(gUGnssPrivateMutex);

errorCodeOrRate = (int32_t) U_ERROR_COMMON_INVALID_PARAMETER;
pInstance = pUGnssPrivateGetInstance(gnssHandle);
if (pInstance != NULL) {
errorCodeOrRate = uGnssPrivateGetRate(pInstance,
Expand Down Expand Up @@ -630,6 +631,7 @@ int32_t uGnssCfgSetRate(uDeviceHandle_t gnssHandle,

U_PORT_MUTEX_LOCK(gUGnssPrivateMutex);

errorCode = (int32_t) U_ERROR_COMMON_INVALID_PARAMETER;
pInstance = pUGnssPrivateGetInstance(gnssHandle);
if (pInstance != NULL) {
errorCode = uGnssPrivateSetRate(pInstance, measurementPeriodMs,
Expand All @@ -642,6 +644,57 @@ int32_t uGnssCfgSetRate(uDeviceHandle_t gnssHandle,
return errorCode;
}

// Get the rate at which a message ID is emitted.
int32_t uGnssCfgGetMsgRate(uDeviceHandle_t gnssHandle,
uGnssMessageId_t *pMessageId)
{
int32_t errorCodeOrMsgRate = (int32_t) U_ERROR_COMMON_NOT_INITIALISED;
uGnssPrivateInstance_t *pInstance;
uGnssPrivateMessageId_t privateMessageId;

if (gUGnssPrivateMutex != NULL) {

U_PORT_MUTEX_LOCK(gUGnssPrivateMutex);

errorCodeOrMsgRate = (int32_t) U_ERROR_COMMON_INVALID_PARAMETER;
pInstance = pUGnssPrivateGetInstance(gnssHandle);
if ((pInstance != NULL) && (pMessageId != NULL) &&
(uGnssPrivateMessageIdToPrivate(pMessageId, &privateMessageId) == 0)) {
errorCodeOrMsgRate = uGnssPrivateGetMsgRate(pInstance, &privateMessageId);
}

U_PORT_MUTEX_UNLOCK(gUGnssPrivateMutex);
}

return errorCodeOrMsgRate;
}

// Set the rate at which a given message ID is emitted.
int32_t uGnssCfgSetMsgRate(uDeviceHandle_t gnssHandle,
uGnssMessageId_t *pMessageId,
int32_t rate)
{
int32_t errorCode = (int32_t) U_ERROR_COMMON_NOT_INITIALISED;
uGnssPrivateInstance_t *pInstance;
uGnssPrivateMessageId_t privateMessageId;

if (gUGnssPrivateMutex != NULL) {

U_PORT_MUTEX_LOCK(gUGnssPrivateMutex);

errorCode = (int32_t) U_ERROR_COMMON_INVALID_PARAMETER;
pInstance = pUGnssPrivateGetInstance(gnssHandle);
if ((pInstance != NULL) && (pMessageId != NULL) &&
(uGnssPrivateMessageIdToPrivate(pMessageId, &privateMessageId) == 0)) {
errorCode = uGnssPrivateSetMsgRate(pInstance, &privateMessageId, rate);
}

U_PORT_MUTEX_UNLOCK(gUGnssPrivateMutex);
}

return errorCode;
}

// Get the dynamic platform model from the GNSS chip.
int32_t uGnssCfgGetDynamic(uDeviceHandle_t gnssHandle)
{
Expand Down
88 changes: 86 additions & 2 deletions gnss/src/u_gnss_private.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,13 @@ uPortMutexHandle_t gUGnssPrivateMutex = NULL;
*/
const uGnssPrivateModule_t gUGnssPrivateModuleList[] = {
{
U_GNSS_MODULE_TYPE_M8, 0 /* features */
U_GNSS_MODULE_TYPE_M8,
(1UL << (int32_t) U_GNSS_PRIVATE_FEATURE_OLD_CFG_API) /* features */
},
{
U_GNSS_MODULE_TYPE_M9,
((1UL << (int32_t) U_GNSS_PRIVATE_FEATURE_CFGVALXXX) |
(1UL << (int32_t) U_GNSS_PRIVATE_FEATURE_OLD_CFG_API) |
(1UL << (int32_t) U_GNSS_PRIVATE_FEATURE_GEOFENCE) /* features */
)
},
Expand Down Expand Up @@ -1463,7 +1465,7 @@ int32_t uGnssPrivateGetRate(uGnssPrivateInstance_t *pInstance,
int32_t *pNavigationCount,
uGnssTimeSystem_t *pTimeSystem)
{
int32_t errorCodeOrRate = (int32_t) U_ERROR_COMMON_NOT_INITIALISED;
int32_t errorCodeOrRate = (int32_t) U_ERROR_COMMON_INVALID_PARAMETER;

if (pInstance != NULL) {
if (U_GNSS_PRIVATE_HAS(pInstance->pModule, U_GNSS_PRIVATE_FEATURE_CFGVALXXX)) {
Expand Down Expand Up @@ -1499,6 +1501,88 @@ int32_t uGnssPrivateSetRate(uGnssPrivateInstance_t *pInstance,
return errorCode;
}

// Get the rate at which a given message ID is emitted.
int32_t uGnssPrivateGetMsgRate(uGnssPrivateInstance_t *pInstance,
uGnssPrivateMessageId_t *pPrivateMessageId)
{
int32_t errorCodeOrRate = (int32_t) U_ERROR_COMMON_INVALID_PARAMETER;
// Message buffer for the 8-byte UBX-CFG-MSG that holds the rate for
// the given message ID on all transports
char message[8] = {0};
char messageClass;
char messageId;

if ((pInstance != NULL) && (pPrivateMessageId != NULL)) {
errorCodeOrRate = (int32_t) U_ERROR_COMMON_NOT_SUPPORTED;
if ((pPrivateMessageId->type == U_GNSS_PROTOCOL_UBX) &&
U_GNSS_PRIVATE_HAS(pInstance->pModule,
U_GNSS_PRIVATE_FEATURE_OLD_CFG_API)) {
errorCodeOrRate = (int32_t) U_ERROR_COMMON_PLATFORM;
messageClass = pPrivateMessageId->id.ubx >> 8;
messageId = pPrivateMessageId->id.ubx & 0xFF;
// The response is two bytes of header and then one byte for each
// port number; make sure we have room
if (pInstance->portNumber < sizeof(message) - 2) {
// Populate the message buffer with the UBX message class and ID
message[0] = messageClass;
message[1] = messageId;
// Poll for UBX-CFG-MSG
if (uGnssPrivateSendReceiveUbxMessage(pInstance,
0x06, 0x01,
message, 2,
message,
sizeof(message)) == sizeof(message)) {
// If the message class and ID are correct in the response,
// the rate at the offset that is the port number
if ((message[0] == messageClass) &&
(message[1] == messageId)) {
errorCodeOrRate = message[2 + pInstance->portNumber];
}
}
}
}
}

return errorCodeOrRate;
}

// Set the rate at which a given message ID is emitted.
int32_t uGnssPrivateSetMsgRate(uGnssPrivateInstance_t *pInstance,
uGnssPrivateMessageId_t *pPrivateMessageId,
int32_t rate)
{
int32_t errorCode = (int32_t) U_ERROR_COMMON_INVALID_PARAMETER;
// Message buffer for the 8-byte UBX-CFG-RATE message that sets the rate
// Note: we use this rather than the 3-byte version that just sets the
// rate on the current port since, in some cases we are using a UART
// to USB converter and so we will have fiddled with the port number;
// basically, gotta be symmetrical with uGnssPrivateGetMsgRate()
char message[8] = {0};

if ((pInstance != NULL) && (pPrivateMessageId != NULL)) {
errorCode = (int32_t) U_ERROR_COMMON_NOT_SUPPORTED;
if ((pPrivateMessageId->type == U_GNSS_PROTOCOL_UBX) &&
U_GNSS_PRIVATE_HAS(pInstance->pModule,
U_GNSS_PRIVATE_FEATURE_OLD_CFG_API)) {
errorCode = (int32_t) U_ERROR_COMMON_PLATFORM;
// The response is two bytes of header and then one byte for each
// port number; make sure we have room
if (pInstance->portNumber < sizeof(message) - 2) {
// Populate the message buffer with the UBX message class and ID
// and the rate in the right slot
message[0] = pPrivateMessageId->id.ubx >> 8;
message[1] = pPrivateMessageId->id.ubx & 0xFF;
message[2 + pInstance->portNumber] = rate;
// Send UBX-CFG-MSG
errorCode = uGnssPrivateSendUbxMessage(pInstance, 0x06, 0x01,
message, sizeof(message));
}
}
}

return errorCode;
}

// Set the protocol type output by the GNSS chip.
int32_t uGnssPrivateSetProtocolOut(uGnssPrivateInstance_t *pInstance,
uGnssProtocol_t protocol,
Expand Down
60 changes: 59 additions & 1 deletion gnss/src/u_gnss_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ extern "C" {
// Lint can't seem to find it inside macros.
typedef enum {
U_GNSS_PRIVATE_FEATURE_CFGVALXXX,
U_GNSS_PRIVATE_FEATURE_GEOFENCE
U_GNSS_PRIVATE_FEATURE_GEOFENCE,
U_GNSS_PRIVATE_FEATURE_OLD_CFG_API
} uGnssPrivateFeature_t;

/** The characteristics that may differ between GNSS modules.
Expand Down Expand Up @@ -347,6 +348,63 @@ int32_t uGnssPrivateSetRate(uGnssPrivateInstance_t *pInstance,
int32_t navigationCount,
uGnssTimeSystem_t timeSystem);

/** Get the rate at which a given UBX message ID is emitted on the
* current transport; this ONLY WORKS FOR M8 AND M9 modules: for
* M10 modules and later you must find the relevant member from
* U_GNSS_CFG_VAL_KEY_ITEM_MSGOUT_* in u_gnss_cfg_val_key.h
* and get the value of that item, e.g.:
*
* ```
* uint32_t keyId = U_GNSS_CFG_VAL_KEY_ITEM_MSGOUT_UBX_NAV_PVT_I2C_U1;
* uGnssCfgVal_t *pCfgVal = NULL;
* if (uGnssCfgPrivateValGetListAlloc(pInstance, &keyId, 1,
* &pCfgVal, U_GNSS_CFG_VAL_LAYER_RAM) == 0);
* // The rate is in pCfgVal->value
* // Don't forget to free pCfgVal afterwards
* uPortFree(pCfgVal);
* }
* ```
*
* @param[in] pInstance a pointer to the GNSS instance, cannot
* be NULL.
* @param[in] pPrivateMessageId a pointer to the private message ID; cannot
* be NULL and only UBX protocol message
* rates can currently be retrieved this way.
* @return on success the rate (0 for never, 1 for
* once every message, 2 for "emit every
* other message", etc.) else negative
* error code.
*/
int32_t uGnssPrivateGetMsgRate(uGnssPrivateInstance_t *pInstance,
uGnssPrivateMessageId_t *pPrivateMessageId);

/** Set the rate at which a given UBX message ID is emitted on the
* current transport; this ONLY WORKS FOR M8 AND M9 modules: for
* M10 modules and later you must find the relevant member from
* U_GNSS_CFG_VAL_KEY_ITEM_MSGOUT_* in u_gnss_cfg_val_key.h
* and set the value of that item, e.g.:
*
* ```
* uGnssCfgVal_t cfgVal[] = {{U_GNSS_CFG_VAL_KEY_ITEM_MSGOUT_UBX_NAV_PVT_I2C_U1, 1}};
* uGnssCfgPrivateValSetList(pInstance, &cfgVal, 1,
* U_GNSS_CFG_VAL_TRANSACTION_NONE,
* U_GNSS_CFG_VAL_LAYER_RAM);
* ```
*
* @param[in] pInstance a pointer to the GNSS instance, cannot
* be NULL.
* @param[in] pPrivateMessageId a pointer to the private message ID; cannot
* be NULL and only UBX protocol message
* rates can currently be configured this way.
* @param rate the rate: 0 for never, 1 for once every
* message, 2 for "emit every other message",
* etc.
* @return zero on success or negative error code.
*/
int32_t uGnssPrivateSetMsgRate(uGnssPrivateInstance_t *pInstance,
uGnssPrivateMessageId_t *pPrivateMessageId,
int32_t rate);

/** Get the protocol types output by the GNSS chip; not relevant
* where an AT transports is in use since only the UBX protocol is
* currently supported through that transport.
Expand Down
Loading

0 comments on commit 00b3fb2

Please sign in to comment.