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

Commit

Permalink
GNSS change only: uGnssGetPortNumber(), uGnssPosGetStreamedStart() wi…
Browse files Browse the repository at this point in the history
…thout uGnssPosGetStreamedStop(). (#1010)

Similar to 795285c, uGnssPosGetStreamedStart() can now be called multiple times, without calling uGnssPosGetStreamedStop() first; the new settings will be applied.

Similar to 132f338, uGnssPosGetStreamedStop() had an issue where it would not restore the previous message rates correctly when using the UART port on an M10 GNSS device; this is now fixed.

As part of this change, a new GNSS API function is introduced: uGnssGetPortNumber().  This allows the internal port number, as seen by the GNSS device, to be read, required in order to set/get the values of `UBX-CFG-VAL` key IDs that are port-number dependent (e.g. the U_GNSS_CFG_VAL_KEY_ID_MSGOUT_XXX key IDs).
  • Loading branch information
RobMeades authored Sep 12, 2023
1 parent 132f338 commit 21c2360
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 161 deletions.
15 changes: 15 additions & 0 deletions gnss/api/u_gnss.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,21 @@ void uGnssSetRetries(uDeviceHandle_t gnssHandle, int32_t retries);
*/
int32_t uGnssGetRetries(uDeviceHandle_t gnssHandle);

/** Get the internal port number that we are using inside the
* GNSS device; this is dictated by the physical transport that
* is in use (NOT necessarily the #uGnssTransportType_t as, for
* instance, UART interfaces may be delivered as USB and Virtual
* Serial ports may be absolutely anything). It may be useful to
* know this port number if you are using the uGnssCfgValXxx()
* functions to set or get a value which is dependent upon it
* (e.g. the one of the U_GNSS_CFG_VAL_KEY_ID_MSGOUT_XXX key IDs).
*
* @param gnssHandle the handle of the GNSS instance.
* @return on success the port number, else negative
* error code.
*/
int32_t uGnssGetPortNumber(uDeviceHandle_t gnssHandle);

#ifdef __cplusplus
}
#endif
Expand Down
11 changes: 7 additions & 4 deletions gnss/api/u_gnss_pos.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void uGnssPosGetStop(uDeviceHandle_t gnssHandle);
/** Get position readings streamed constantly to a callback; this will
* only work with one of the streamed transports (for instance UART, I2C,
* SPI or Virtual Serial), it will NOT work with AT-command-based transport
* (#U_GNSS_TRANSPORT_AT). uGnssPosGetStart() allocates some storage
* (#U_GNSS_TRANSPORT_AT). uGnssPosGetStreamedStart() allocates some storage
* which remains in memory until the GNSS API is deinitialised; should
* you wish to free that memory then calling uGnssPosGetStreamedStop()
* will also do that.
Expand All @@ -226,7 +226,10 @@ void uGnssPosGetStop(uDeviceHandle_t gnssHandle);
* Note: this uses one of the #U_GNSS_MSG_RECEIVER_MAX_NUM message
* handles from the uGnssMsg API.
*
* To cancel streamed position, call uGnssPosGetStreamedStop().
* To cancel streamed position, call uGnssPosGetStreamedStop(). If
* uGnssPosGetStreamedStart() is called again without calling
* uGnssPosGetStreamedStop() first, the new settings will be applied (i.e.
* as if uGnssPosGetStreamedStop() had been called first).
*
* @param gnssHandle the handle of the GNSS instance to use.
* @param rateMs the desired time between position fixes in
Expand All @@ -235,7 +238,7 @@ void uGnssPosGetStop(uDeviceHandle_t gnssHandle);
* the navigation count (i.e. the number of measurements
* required to make a navigation solution) will
* be 1. If you want to use a navigation count
* greater 1 one you may set that by calling
* greater than 1 you may set that by calling
* uGnssCfgSetRate() before this function and
* then setting rateMs here to -1, which will leave
* the rate settings unchanged.
Expand All @@ -245,7 +248,7 @@ void uGnssPosGetStop(uDeviceHandle_t gnssHandle);
* Note: don't call back into this API from your
* pCallback, it could lead to recursion.
* IMPORTANT: you should check the value of
* errorCode before treating rhe parameters:
* errorCode before treating the parameters:
* a value of zero means that a position fix
* has been achieved but a value of
* #U_ERROR_COMMON_TIMEOUT may be used to
Expand Down
25 changes: 24 additions & 1 deletion gnss/src/u_gnss.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,8 @@ int32_t uGnssAdd(uGnssModuleType_t moduleType,
pInstance->portNumber = U_GNSS_PORT_SPI;
}
#if defined(_WIN32) || (defined(__ZEPHYR__) && defined(CONFIG_UART_NATIVE_POSIX))
// For Windows and Linux the GNSS-side connection is assumed to be USB
// For Windows and Posix-Zephyr the GNSS-side connection is assumed to be USB
// (for Linux, on a Raspberry Pi, it's not forced, just good 'ole UART)
pInstance->portNumber = 3;
#endif
#ifdef U_CFG_GNSS_PORT_NUMBER
Expand Down Expand Up @@ -817,4 +818,26 @@ int32_t uGnssGetRetries(uDeviceHandle_t gnssHandle)
return errorCodeOrRetries;
}

// Get the internal port number that we are using inside GNSS.
int32_t uGnssGetPortNumber(uDeviceHandle_t gnssHandle)
{
int32_t errorCodeOrPortNumber = (int32_t) U_ERROR_COMMON_NOT_INITIALISED;
uGnssPrivateInstance_t *pInstance;

if (gUGnssPrivateMutex != NULL) {

U_PORT_MUTEX_LOCK(gUGnssPrivateMutex);

errorCodeOrPortNumber = (int32_t) U_ERROR_COMMON_INVALID_PARAMETER;
pInstance = pUGnssPrivateGetInstance(gnssHandle);
if (pInstance != NULL) {
errorCodeOrPortNumber = pInstance->portNumber;
}

U_PORT_MUTEX_UNLOCK(gUGnssPrivateMutex);
}

return errorCodeOrPortNumber;
}

// End of file
193 changes: 100 additions & 93 deletions gnss/src/u_gnss_pos.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,8 +586,8 @@ int32_t uGnssPosGetStreamedStart(uDeviceHandle_t gnssHandle,
int32_t errorCode = (int32_t) U_ERROR_COMMON_NOT_INITIALISED;
uGnssPrivateInstance_t *pInstance;
uGnssPrivateStreamedPosition_t *pStreamedPosition;
int32_t measurementPeriodMs;
int32_t navigationCount;
int32_t measurementPeriodMs = -1;
int32_t navigationCount = -1;
int32_t messageRate = -1;
uGnssPrivateMessageId_t ubxNavPvtMessageId = {.type = U_GNSS_PROTOCOL_UBX,
.id.ubx = 0x0107
Expand All @@ -613,111 +613,118 @@ int32_t uGnssPosGetStreamedStart(uDeviceHandle_t gnssHandle,
keyId = U_GNSS_CFG_VAL_KEY_ID_MSGOUT_UBX_NAV_PVT_I2C_U1 + pInstance->portNumber;
cfgVal.keyId = keyId;
cfgVal.value = 1;
bool temp = pInstance->printUbxMessages;
pInstance->printUbxMessages = true;
pStreamedPosition = pInstance->pStreamedPosition;
if (pStreamedPosition != NULL) {
// Stop the previous streamed position
uGnssPrivateCleanUpStreamedPos(pInstance);
}
// Malloc memory to copy the parameters into:
// this memory will be free'd when
// uGnssPosGetStreamedStop() is called
errorCode = (int32_t) U_ERROR_COMMON_NO_MEMORY;
if (pInstance->pStreamedPosition == NULL) {
// Malloc memory to copy the parameters into:
// this memory will be free'd when
// uGnssPosGetStreamedStop() is called
pStreamedPosition = (uGnssPrivateStreamedPosition_t *) pUPortMalloc(sizeof(*pStreamedPosition));
if (pStreamedPosition != NULL) {
pInstance->pStreamedPosition = pStreamedPosition;
memset(pStreamedPosition, 0, sizeof(*pStreamedPosition));
errorCode = (int32_t) U_ERROR_COMMON_SUCCESS;
// Put defaults in place so that we know
// to change things back only if necessary
pStreamedPosition->measurementPeriodMs = -1;
pStreamedPosition->navigationCount = -1;
pStreamedPosition->messageRate = -1;
pStreamedPosition->asyncHandle = -1;
pStreamedPosition->pCallback = pCallback;
if (rateMs >= 0) {
// Get the existing measurement/navigation rate
// and, if it is not rateMs, set it to rateMs
if (uGnssPrivateGetRate(pInstance,
&measurementPeriodMs,
&navigationCount,
NULL) != rateMs) {
// Set the measurement rate, with a navigation count of 1
// and leaving the time system unchanged
errorCode = uGnssPrivateSetRate(pInstance, rateMs, 1,
U_GNSS_TIME_SYSTEM_NONE);
if (errorCode == 0) {
pStreamedPosition->measurementPeriodMs = measurementPeriodMs;
pStreamedPosition->navigationCount = navigationCount;
}
pStreamedPosition = (uGnssPrivateStreamedPosition_t *) pUPortMalloc(sizeof(*pStreamedPosition));
if (pStreamedPosition != NULL) {
memset(pStreamedPosition, 0, sizeof(*pStreamedPosition));
// Put defaults in place so that we know
// to change things back only if necessary
pStreamedPosition->measurementPeriodMs = -1;
pStreamedPosition->navigationCount = -1;
pStreamedPosition->messageRate = -1;
pStreamedPosition->asyncHandle = -1;
pStreamedPosition->pCallback = pCallback;
pInstance->pStreamedPosition = pStreamedPosition;
errorCode = (int32_t) U_ERROR_COMMON_SUCCESS;
if (rateMs >= 0) {
// Get the existing measurement/navigation rate
// and, if it is not rateMs, set it to rateMs
if (uGnssPrivateGetRate(pInstance,
&measurementPeriodMs,
&navigationCount,
NULL) != rateMs) {
// Set the measurement rate, with a navigation count of 1
// and leaving the time system unchanged
errorCode = uGnssPrivateSetRate(pInstance, rateMs, 1,
U_GNSS_TIME_SYSTEM_NONE);
if (errorCode == 0) {
pStreamedPosition->measurementPeriodMs = measurementPeriodMs;
pStreamedPosition->navigationCount = navigationCount;
}
}
if (errorCode == 0) {
// Make sure that the UBX-NAV-PVT message
// is enabled at once per measurement
if (U_GNSS_PRIVATE_HAS(pInstance->pModule,
U_GNSS_PRIVATE_FEATURE_OLD_CFG_API)) {
messageRate = uGnssPrivateGetMsgRate(pInstance,
&ubxNavPvtMessageId);
if (messageRate != 1) {
errorCode = uGnssPrivateSetMsgRate(pInstance,
&ubxNavPvtMessageId, 1);
if (errorCode == 0) {
pStreamedPosition->messageRate = messageRate;
}
}
} else {
if (uGnssCfgPrivateValGetListAlloc(pInstance,
&keyId, 1,
&pCfgVal,
U_GNSS_CFG_VAL_LAYER_RAM) == 1) {
messageRate = (int32_t) pCfgVal->value;
uPortFree(pCfgVal);
}
if (errorCode == 0) {
// Make sure that the UBX-NAV-PVT message
// is enabled at once per measurement
if (U_GNSS_PRIVATE_HAS(pInstance->pModule,
U_GNSS_PRIVATE_FEATURE_OLD_CFG_API)) {
messageRate = uGnssPrivateGetMsgRate(pInstance,
&ubxNavPvtMessageId);
if (messageRate != 1) {
errorCode = uGnssPrivateSetMsgRate(pInstance,
&ubxNavPvtMessageId, 1);
if (errorCode == 0) {
pStreamedPosition->messageRate = messageRate;
}
if (messageRate != (int32_t) cfgVal.value) {
errorCode = uGnssCfgPrivateValSetList(pInstance, &cfgVal, 1,
U_GNSS_CFG_VAL_TRANSACTION_NONE,
U_GNSS_CFG_LAYERS_SET);
if (errorCode == 0) {
pStreamedPosition->messageRate = messageRate;
}
}
} else {
if (uGnssCfgPrivateValGetListAlloc(pInstance,
&keyId, 1,
&pCfgVal,
U_GNSS_CFG_VAL_LAYER_RAM) == 1) {
messageRate = (int32_t) pCfgVal->value;
uPortFree(pCfgVal);
}
if (messageRate != (int32_t) cfgVal.value) {
errorCode = uGnssCfgPrivateValSetList(pInstance, &cfgVal, 1,
U_GNSS_CFG_VAL_TRANSACTION_NONE,
U_GNSS_CFG_LAYERS_SET);
if (errorCode == 0) {
pStreamedPosition->messageRate = messageRate;
}
}
}
if (errorCode == 0) {
}
if (errorCode == 0) {
#ifdef U_CFG_SARA_R5_M8_WORKAROUND
if (uGnssPrivateGetIntermediateAtHandle(pInstance) != NULL) {
// Temporary change: on prototype versions of the
// SARA-R510M8S module (production week (printed on the
// module label, upper right) earlier than 20/27)
// the LNA in the GNSS chip is not automatically switched
// on by the firmware in the cellular module, so we need
// to switch it on ourselves by sending UBX-CFG-ANT
// with contents 02000f039
message[0] = 0x02;
message[1] = 0;
message[2] = 0xf0;
message[3] = 0x39;
uGnssPrivateSendUbxMessage(pInstance, 0x06, 0x13,
(const char *) message, 4);
}
if (uGnssPrivateGetIntermediateAtHandle(pInstance) != NULL) {
// Temporary change: on prototype versions of the
// SARA-R510M8S module (production week (printed on the
// module label, upper right) earlier than 20/27)
// the LNA in the GNSS chip is not automatically switched
// on by the firmware in the cellular module, so we need
// to switch it on ourselves by sending UBX-CFG-ANT
// with contents 02000f039
message[0] = 0x02;
message[1] = 0;
message[2] = 0xf0;
message[3] = 0x39;
uGnssPrivateSendUbxMessage(pInstance, 0x06, 0x13,
(const char *) message, 4);
}
#endif
// Start a message received for the UBX-NAV-PVT message,
// which will ultimately call pCallback
errorCode = uGnssMsgPrivateReceiveStart(pInstance,
&ubxNavPvtMessageId,
messageCallback,
pInstance);
if (errorCode >= 0) {
// And we're off
pStreamedPosition->gnssHandle = gnssHandle;
pStreamedPosition->asyncHandle = errorCode;
} else {
// If we couldn't create the asynchronous
// message receiver, clean up
uGnssPrivateCleanUpStreamedPos(pInstance);
}
pInstance->printUbxMessages = temp;
// Start a message received for the UBX-NAV-PVT message,
// which will ultimately call pCallback
errorCode = uGnssMsgPrivateReceiveStart(pInstance,
&ubxNavPvtMessageId,
messageCallback,
pInstance);
if (errorCode >= 0) {
// And we're off
pStreamedPosition->gnssHandle = gnssHandle;
pStreamedPosition->asyncHandle = errorCode;
} else {
// If we couldn't set the rate, clean up
// If we couldn't create the asynchronous
// message receiver, clean up
uGnssPrivateCleanUpStreamedPos(pInstance);
}
} else {
// If we couldn't set the rate, clean up
uGnssPrivateCleanUpStreamedPos(pInstance);
}
}
pInstance->printUbxMessages = temp;
}
}
}
Expand Down
Loading

0 comments on commit 21c2360

Please sign in to comment.