From 21c2360be3db4a079c10c75c27c0fda302d714b9 Mon Sep 17 00:00:00 2001 From: Rob Meades Date: Tue, 12 Sep 2023 19:04:16 +0100 Subject: [PATCH] GNSS change only: uGnssGetPortNumber(), uGnssPosGetStreamedStart() without uGnssPosGetStreamedStop(). (#1010) Similar to 795285c026c10f72b3120d736a858efdd13a8295, uGnssPosGetStreamedStart() can now be called multiple times, without calling uGnssPosGetStreamedStop() first; the new settings will be applied. Similar to 132f338ef49285b6c40d070b38fe558acb6d3030, 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). --- gnss/api/u_gnss.h | 15 +++ gnss/api/u_gnss_pos.h | 11 +- gnss/src/u_gnss.c | 25 ++++- gnss/src/u_gnss_pos.c | 193 +++++++++++++++++++----------------- gnss/src/u_gnss_private.c | 5 +- gnss/test/u_gnss_pos_test.c | 148 +++++++++++++++------------ gnss/test/u_gnss_test.c | 56 +++++++++++ 7 files changed, 292 insertions(+), 161 deletions(-) diff --git a/gnss/api/u_gnss.h b/gnss/api/u_gnss.h index aaa525a21..4f6efa402 100644 --- a/gnss/api/u_gnss.h +++ b/gnss/api/u_gnss.h @@ -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 diff --git a/gnss/api/u_gnss_pos.h b/gnss/api/u_gnss_pos.h index 1e0bbc836..77a314040 100644 --- a/gnss/api/u_gnss_pos.h +++ b/gnss/api/u_gnss_pos.h @@ -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. @@ -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 @@ -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. @@ -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 diff --git a/gnss/src/u_gnss.c b/gnss/src/u_gnss.c index f25fb3f66..f7237acb2 100644 --- a/gnss/src/u_gnss.c +++ b/gnss/src/u_gnss.c @@ -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 @@ -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 diff --git a/gnss/src/u_gnss_pos.c b/gnss/src/u_gnss_pos.c index b8a25d8b9..264a23893 100644 --- a/gnss/src/u_gnss_pos.c +++ b/gnss/src/u_gnss_pos.c @@ -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 @@ -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; } } } diff --git a/gnss/src/u_gnss_private.c b/gnss/src/u_gnss_private.c index 1ff273c81..cd091053a 100644 --- a/gnss/src/u_gnss_private.c +++ b/gnss/src/u_gnss_private.c @@ -1668,7 +1668,7 @@ void uGnssPrivateCleanUpStreamedPos(uGnssPrivateInstance_t *pInstance) uGnssPrivateMessageId_t privateMessageId = {.type = U_GNSS_PROTOCOL_UBX, .id.ubx = 0x0107 }; - uGnssCfgVal_t cfgVal = {.keyId = U_GNSS_CFG_VAL_KEY_ID_MSGOUT_UBX_NAV_PVT_I2C_U1}; + uGnssCfgVal_t cfgVal; if ((pInstance != NULL) && (pInstance->pStreamedPosition != NULL)) { pStreamedPosition = pInstance->pStreamedPosition; @@ -1700,6 +1700,9 @@ void uGnssPrivateCleanUpStreamedPos(uGnssPrivateInstance_t *pInstance) &privateMessageId, pStreamedPosition->messageRate); } else { + // The keyId for the msgout rates is port dependent: + // a base of the I2C value plus the port number (uGnssPort_t) + cfgVal.keyId = U_GNSS_CFG_VAL_KEY_ID_MSGOUT_UBX_NAV_PVT_I2C_U1 + pInstance->portNumber; cfgVal.value = pStreamedPosition->messageRate; y = uGnssCfgPrivateValSetList(pInstance, &cfgVal, 1, U_GNSS_CFG_VAL_TRANSACTION_NONE, diff --git a/gnss/test/u_gnss_pos_test.c b/gnss/test/u_gnss_pos_test.c index c16140f18..63e88e49f 100644 --- a/gnss/test/u_gnss_pos_test.c +++ b/gnss/test/u_gnss_pos_test.c @@ -104,12 +104,23 @@ * -------------------------------------------------------------- */ #ifndef U_GNSS_POS_TEST_REPEATS -/** How many times to repeat the body of the gnssPosPos test - * (i.e. it will be run this number of times + 1). +/** How many times to repeat the body of the gnssPosPos() test + * tests (i.e. it will be run this number of times + 1). */ # define U_GNSS_POS_TEST_REPEATS 2 #endif +#ifndef U_GNSS_POS_TEST_STREAMED_REPEATS +/** How many times to repeat the body of the gnssPosStreamed() test + * (i.e. it will be run this number of times + 1). While it would be + * nice if this were greater than 0, the problem is that the high + * message rate we use in the test hammers the interface to the GNSS + * device and control messages can get stuck behind a slew of location + * messages, leading to timeouts and test failues. + */ +# define U_GNSS_POS_TEST_STREAMED_REPEATS 0 +#endif + #ifndef U_GNSS_POS_TEST_TIMEOUT_SECONDS /** The timeout on position establishment. */ @@ -734,7 +745,7 @@ U_PORT_TEST_FUNCTION("[gnssPos]", "gnssPosStreamed") if (gMsgRate < 0) { gMsgRate = 0; if (uGnssCfgValGet(gnssHandle, - U_GNSS_CFG_VAL_KEY_ID_MSGOUT_UBX_NAV_PVT_I2C_U1, + U_GNSS_CFG_VAL_KEY_ID_MSGOUT_UBX_NAV_PVT_I2C_U1 + uGnssGetPortNumber(gnssHandle), (void *) &gMsgRate, sizeof(gMsgRate), U_GNSS_CFG_VAL_LAYER_RAM) != 0) { gMsgRate = -1; @@ -746,67 +757,80 @@ U_PORT_TEST_FUNCTION("[gnssPos]", "gnssPosStreamed") // Switch off message printing as we can't afford the time uGnssSetUbxMessagePrint(gnssHandle, false); - gErrorCode = 0xFFFFFFFF; - startTimeMs = uPortGetTickTimeMs(); - gStopTimeMs = startTimeMs + U_GNSS_POS_TEST_TIMEOUT_SECONDS * 1000; - U_PORT_TEST_ASSERT(uGnssPosGetStreamedStart(gnssHandle, - U_GNSS_POS_TEST_STREAMED_RATE_MS, - posCallback) == 0); - U_TEST_PRINT_LINE("waiting up to %d second(s) for first valid result from streamed API...", - U_GNSS_POS_TEST_TIMEOUT_SECONDS); - while ((gErrorCode != 0) && (uPortGetTickTimeMs() < gStopTimeMs)) { - uPortTaskBlock(1000); - } + // Do this a few times so that we can check if calling uGnssPosGetStreamedStart() + // without having called uGnssPosGetStreamedStop() etc. is a problem. + U_TEST_PRINT_LINE("testing streamed position API %d time(s).", + U_GNSS_POS_TEST_STREAMED_REPEATS + 1); + for (size_t z = 0; z < U_GNSS_POS_TEST_STREAMED_REPEATS + 1; z++) { + if (z == 0) { + // Check that calling stop first causes no problem + uGnssPosGetStreamedStop(gnssHandle); + } + gErrorCode = 0xFFFFFFFF; + startTimeMs = uPortGetTickTimeMs(); + gStopTimeMs = startTimeMs + U_GNSS_POS_TEST_TIMEOUT_SECONDS * 1000; + y = uGnssPosGetStreamedStart(gnssHandle, U_GNSS_POS_TEST_STREAMED_RATE_MS, posCallback); + U_TEST_PRINT_LINE_X("uGnssPosGetStreamedStart() returned %d.", z + 1, y); + U_PORT_TEST_ASSERT(y == 0); + U_TEST_PRINT_LINE_X("waiting up to %d second(s) for first valid result from streamed API...", + z + 1, U_GNSS_POS_TEST_TIMEOUT_SECONDS); + while ((gErrorCode != 0) && (uPortGetTickTimeMs() < gStopTimeMs)) { + uPortTaskBlock(1000); + } - if (gErrorCode == 0) { - posTimeMs = uPortGetTickTimeMs(); - U_TEST_PRINT_LINE("waiting %d second(s) for rate change to take effect...", - U_GNSS_POS_TEST_STREAMED_WAIT_SECONDS); - uPortTaskBlock(1000 * U_GNSS_POS_TEST_STREAMED_WAIT_SECONDS); - // gGoodPosCount should now be building up - gGoodPosCount = 0; - U_TEST_PRINT_LINE("waiting %d second(s) for streamed position calls to accumulate...", - U_GNSS_POS_TEST_STREAMED_SECONDS); - uPortTaskBlock(1000 * U_GNSS_POS_TEST_STREAMED_SECONDS); + if (gErrorCode == 0) { + posTimeMs = uPortGetTickTimeMs(); + U_TEST_PRINT_LINE_X("waiting %d second(s) for rate change to take effect...", + z + 1, U_GNSS_POS_TEST_STREAMED_WAIT_SECONDS); + uPortTaskBlock(1000 * U_GNSS_POS_TEST_STREAMED_WAIT_SECONDS); + // gGoodPosCount should now be building up + gGoodPosCount = 0; + U_TEST_PRINT_LINE_X("waiting %d second(s) for streamed position calls to accumulate...", + z + 1, U_GNSS_POS_TEST_STREAMED_SECONDS); + uPortTaskBlock(1000 * U_GNSS_POS_TEST_STREAMED_SECONDS); + // See what we're doing again now + uGnssSetUbxMessagePrint(gnssHandle, true); + + U_PORT_TEST_ASSERT(gGnssHandle == gnssHandle); + U_TEST_PRINT_LINE_X("streamed position callback received error code %d.", z + 1, gErrorCode); + U_PORT_TEST_ASSERT(gErrorCode == 0); + if (gGoodPosCount > 0) { + U_TEST_PRINT_LINE_X("position establishment took %d second(s).", z + 1, + (posTimeMs - startTimeMs) / 1000); + U_TEST_PRINT_LINE_X("the streamed position callback was called with a good position %d time(s)" + " in %d second(s), average every %d millisecond(s) (expected every" + " %d milliseconds).", z + 1, + gGoodPosCount, U_GNSS_POS_TEST_STREAMED_SECONDS, + (U_GNSS_POS_TEST_STREAMED_SECONDS * 1000) / gGoodPosCount, + U_GNSS_POS_TEST_STREAMED_RATE_MS); + U_PORT_TEST_ASSERT(gGoodPosCount >= (((U_GNSS_POS_TEST_STREAMED_SECONDS * 1000) / + U_GNSS_POS_TEST_STREAMED_RATE_MS) * + U_GNSS_POS_TEST_STREAMED_RATE_MARGIN_PERCENT) / 100); + prefix[0] = latLongToBits(gLatitudeX1e7, &(whole[0]), &(fraction[0])); + prefix[1] = latLongToBits(gLongitudeX1e7, &(whole[1]), &(fraction[1])); + U_TEST_PRINT_LINE_X("location %c%d.%07d/%c%d.%07d (radius %d metre(s)), %d metre(s) high," + " moving at %d metre(s)/second, %d satellite(s) visible, time %d.", z + 1, + prefix[0], whole[0], fraction[0], prefix[1], whole[1], fraction[1], + gRadiusMillimetres / 1000, gAltitudeMillimetres / 1000, + gSpeedMillimetresPerSecond / 1000, gSvs, (int32_t) gTimeUtc); + U_TEST_PRINT_LINE_X("paste this into a browser https://maps.google.com/?q=%c%d.%07d,%c%d.%07d", + z + 1, prefix[0], whole[0], fraction[0], prefix[1], whole[1], fraction[1]); + + U_PORT_TEST_ASSERT(gLatitudeX1e7 > INT_MIN); + U_PORT_TEST_ASSERT(gLongitudeX1e7 > INT_MIN); + // Don't test altitude as we may only have a 2D fix + U_PORT_TEST_ASSERT(gRadiusMillimetres > INT_MIN); + U_PORT_TEST_ASSERT(gSpeedMillimetresPerSecond > INT_MIN); + // Inertial fixes will be reported with no satellites, hence >= 0 + U_PORT_TEST_ASSERT(gSvs >= 0); + U_PORT_TEST_ASSERT(gTimeUtc > 0); + } + } + // Don't, stop, me, now. } - uGnssPosGetStreamedStop(gnssHandle); - - // See what we're doing again now - uGnssSetUbxMessagePrint(gnssHandle, true); - U_PORT_TEST_ASSERT(gGnssHandle == gnssHandle); - U_TEST_PRINT_LINE("streamed position callback received error code %d.", gErrorCode); - U_PORT_TEST_ASSERT(gErrorCode == 0); - if (gGoodPosCount > 0) { - U_TEST_PRINT_LINE("position establishment took %d second(s).", (posTimeMs - startTimeMs) / 1000); - U_TEST_PRINT_LINE("the streamed position callback was called with a good position %d time(s)" - " in %d second(s), average every %d millisecond(s) (expected every" - " %d milliseconds).", - gGoodPosCount, U_GNSS_POS_TEST_STREAMED_SECONDS, - (U_GNSS_POS_TEST_STREAMED_SECONDS * 1000) / gGoodPosCount, - U_GNSS_POS_TEST_STREAMED_RATE_MS); - U_PORT_TEST_ASSERT(gGoodPosCount >= (((U_GNSS_POS_TEST_STREAMED_SECONDS * 1000) / - U_GNSS_POS_TEST_STREAMED_RATE_MS) * - U_GNSS_POS_TEST_STREAMED_RATE_MARGIN_PERCENT) / 100); - prefix[0] = latLongToBits(gLatitudeX1e7, &(whole[0]), &(fraction[0])); - prefix[1] = latLongToBits(gLongitudeX1e7, &(whole[1]), &(fraction[1])); - U_TEST_PRINT_LINE("location %c%d.%07d/%c%d.%07d (radius %d metre(s)), %d metre(s) high," - " moving at %d metre(s)/second, %d satellite(s) visible, time %d.", - prefix[0], whole[0], fraction[0], prefix[1], whole[1], fraction[1], - gRadiusMillimetres / 1000, gAltitudeMillimetres / 1000, - gSpeedMillimetresPerSecond / 1000, gSvs, (int32_t) gTimeUtc); - U_TEST_PRINT_LINE("paste this into a browser https://maps.google.com/?q=%c%d.%07d,%c%d.%07d", - prefix[0], whole[0], fraction[0], prefix[1], whole[1], fraction[1]); - - U_PORT_TEST_ASSERT(gLatitudeX1e7 > INT_MIN); - U_PORT_TEST_ASSERT(gLongitudeX1e7 > INT_MIN); - // Don't test altitude as we may only have a 2D fix - U_PORT_TEST_ASSERT(gRadiusMillimetres > INT_MIN); - U_PORT_TEST_ASSERT(gSpeedMillimetresPerSecond > INT_MIN); - // Inertial fixes will be reported with no satellites, hence >= 0 - U_PORT_TEST_ASSERT(gSvs >= 0); - U_PORT_TEST_ASSERT(gTimeUtc > 0); - } + // Now stop + uGnssPosGetStreamedStop(gnssHandle); U_TEST_PRINT_LINE("waiting %d second(s) for things to calm down and then flushing...", U_GNSS_POS_TEST_STREAMED_WAIT_SECONDS); @@ -834,7 +858,7 @@ U_PORT_TEST_FUNCTION("[gnssPos]", "gnssPosStreamed") if (y < 0) { y = 0; U_PORT_TEST_ASSERT(uGnssCfgValGet(gnssHandle, - U_GNSS_CFG_VAL_KEY_ID_MSGOUT_UBX_NAV_PVT_I2C_U1, + U_GNSS_CFG_VAL_KEY_ID_MSGOUT_UBX_NAV_PVT_I2C_U1 + uGnssGetPortNumber(gnssHandle), (void *) &y, sizeof(y), U_GNSS_CFG_VAL_LAYER_RAM) == 0); } diff --git a/gnss/test/u_gnss_test.c b/gnss/test/u_gnss_test.c index cd6a927af..6b3f0b76f 100644 --- a/gnss/test/u_gnss_test.c +++ b/gnss/test/u_gnss_test.c @@ -219,18 +219,46 @@ U_PORT_TEST_FUNCTION("[gnss]", "gnssAddStream") case U_GNSS_TRANSPORT_UART: U_PORT_TEST_ASSERT(transportType == U_GNSS_TRANSPORT_UART); U_PORT_TEST_ASSERT(transportHandle.uart == transportHandleA.uart); +#if defined(_WIN32) || (defined(__ZEPHYR__) && defined(CONFIG_UART_NATIVE_POSIX)) + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_USB); +#else +# ifndef U_CFG_GNSS_PORT_NUMBER + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_UART1); +# else + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_CFG_GNSS_PORT_NUMBER); +# endif +#endif break; case U_GNSS_TRANSPORT_UART_2: U_PORT_TEST_ASSERT(transportType == U_GNSS_TRANSPORT_UART_2); U_PORT_TEST_ASSERT(transportHandle.uart == transportHandleA.uart); +#if defined(_WIN32) || (defined(__ZEPHYR__) && defined(CONFIG_UART_NATIVE_POSIX)) + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_USB); +#else +# ifndef U_CFG_GNSS_PORT_NUMBER + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_UART2); +# else + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_CFG_GNSS_PORT_NUMBER); +# endif +#endif break; case U_GNSS_TRANSPORT_I2C: U_PORT_TEST_ASSERT(transportType == U_GNSS_TRANSPORT_I2C); U_PORT_TEST_ASSERT(transportHandle.i2c == transportHandleA.i2c); +#ifndef U_CFG_GNSS_PORT_NUMBER + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_I2C); +#else + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_CFG_GNSS_PORT_NUMBER); +#endif break; case U_GNSS_TRANSPORT_SPI: U_PORT_TEST_ASSERT(transportType == U_GNSS_TRANSPORT_SPI); U_PORT_TEST_ASSERT(transportHandle.spi == transportHandleA.spi); +#ifndef U_CFG_GNSS_PORT_NUMBER + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_SPI); +#else + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_CFG_GNSS_PORT_NUMBER); +#endif break; default: U_PORT_TEST_ASSERT(false); @@ -334,18 +362,46 @@ U_PORT_TEST_FUNCTION("[gnss]", "gnssAddStream") case U_GNSS_TRANSPORT_UART: U_PORT_TEST_ASSERT(transportType == U_GNSS_TRANSPORT_UART); U_PORT_TEST_ASSERT(transportHandle.uart == transportHandleA.uart); +#if defined(_WIN32) || (defined(__ZEPHYR__) && defined(CONFIG_UART_NATIVE_POSIX)) + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_USB); +#else +# ifndef U_CFG_GNSS_PORT_NUMBER + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_UART1); +# else + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_CFG_GNSS_PORT_NUMBER); +# endif +#endif break; case U_GNSS_TRANSPORT_UART_2: U_PORT_TEST_ASSERT(transportType == U_GNSS_TRANSPORT_UART_2); U_PORT_TEST_ASSERT(transportHandle.uart == transportHandleA.uart); +#if defined(_WIN32) || (defined(__ZEPHYR__) && defined(CONFIG_UART_NATIVE_POSIX)) + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_USB); +#else +# ifndef U_CFG_GNSS_PORT_NUMBER + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_UART2); +# else + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_CFG_GNSS_PORT_NUMBER); +# endif +#endif break; case U_GNSS_TRANSPORT_I2C: U_PORT_TEST_ASSERT(transportType == U_GNSS_TRANSPORT_I2C); U_PORT_TEST_ASSERT(transportHandle.i2c == transportHandleA.i2c); +#ifndef U_CFG_GNSS_PORT_NUMBER + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_I2C); +#else + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_CFG_GNSS_PORT_NUMBER); +#endif break; case U_GNSS_TRANSPORT_SPI: U_PORT_TEST_ASSERT(transportType == U_GNSS_TRANSPORT_SPI); U_PORT_TEST_ASSERT(transportHandle.spi == transportHandleA.spi); +#ifndef U_CFG_GNSS_PORT_NUMBER + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_GNSS_PORT_SPI); +#else + U_PORT_TEST_ASSERT(uGnssGetPortNumber(gnssHandleA) == U_CFG_GNSS_PORT_NUMBER); +#endif break; default: U_PORT_TEST_ASSERT(false);