diff --git a/gnss/api/u_gnss.h b/gnss/api/u_gnss.h index aaa525a2..4f6efa40 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 1e0bbc83..77a31404 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 f25fb3f6..f7237acb 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 b8a25d8b..264a2389 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 1ff273c8..cd091053 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 c16140f1..63e88e49 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 cd6a927a..6b3f0b76 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);