Skip to content

Commit

Permalink
GNSS change only: option for uDeviceClose() to call uGnssPwrOffBackup…
Browse files Browse the repository at this point in the history
…(). (#1187)

When uDeviceClose() is called with powerOff set to true on a GNSS device, the function uGnssPwrOff() is internally called to power the GNSS device down. This switches off the positioning engine but does not put the device into the lowest power state; the reason for this is that the mechanism through which the GNSS device is restored from back-up mode may require additional pins to be connected; e.g. toggling the I2C pins of the GNSS device will NOT cause it to return to normal operation (toggling the SPI or UART lines will).

With this commit the application can now set a Boolean flag, powerOffToBackup, in uDeviceCfgGnss_t; this will cause the device layer to call uGnssPwrOffBackup() instead of uGnssPwrOff(). It is up to the application to know how to restore the GNSS device to normal operation afterwards, e.g. it may be necessary to toggle RESET_N or connect a separate GPIO line; please refer to the section of the integration manual for your GNSS device that covers backup modes for details.
  • Loading branch information
RobMeades authored Jun 18, 2024
1 parent 0dd4e99 commit d4d58a5
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 5 deletions.
21 changes: 21 additions & 0 deletions common/device/api/u_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,27 @@ typedef struct {
the GNSS device is using is NOT the default
#U_GNSS_I2C_ADDRESS; otherwise let the
compiler initialise this to 0. */
bool powerOffToBackup; /**< Normally the GNSS device will be powered
off by the device layer with a call to
uGnssPwrOff(), however this only stops
GNSS; for least power consumption the
device should be powered off to back-up
mode with a call to uGnssPwrOffBackup();
setting this item to true will cause
uGnssPwrOffBackup() to be called instead
of uGnssPwrOff(). HOWEVER note that the
mechanism through which the GNSS device
is restored from back-up mode may require
additional pins to be connected; e.g.
toggling the I2C pins of the GNSS device
will NOT cause it to return to normal
operation (toggling the SPI and UART
lines will). Instead, for this case
the application must toggle the RESET_N
line or a chosen GPIO line. For more
details refer to the section of the
integration manual for your GNSS device
that covers backup modes. */
/* Add any new version 0 structure items to the end here.
*
* IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT:
Expand Down
13 changes: 10 additions & 3 deletions common/device/src/u_device_private_gnss.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ const uGnssTransportType_t gDeviceToGnssTransportType[] = {
// Populate the GNSS device context
static void populateContext(uDeviceGnssInstance_t *pContext,
uGnssTransportHandle_t gnssTransportHandle,
uDeviceTransportType_t deviceTransportType)
uDeviceTransportType_t deviceTransportType,
bool powerOffToBackup)
{
switch (deviceTransportType) {
case U_DEVICE_TRANSPORT_TYPE_UART:
Expand All @@ -114,6 +115,7 @@ static void populateContext(uDeviceGnssInstance_t *pContext,
break;
}
pContext->deviceTransportType = deviceTransportType;
pContext->powerOffToBackup = powerOffToBackup;
}

// Do all the leg-work to remove a GNSS device.
Expand All @@ -125,7 +127,11 @@ static int32_t removeDevice(uDeviceHandle_t devHandle, bool powerOff)
if (pContext != NULL) {
errorCode = (int32_t) U_ERROR_COMMON_SUCCESS;
if (powerOff) {
errorCode = uGnssPwrOff(devHandle);
if (pContext->powerOffToBackup) {
errorCode = uGnssPwrOffBackup(devHandle);
} else {
errorCode = uGnssPwrOff(devHandle);
}
if (errorCode == 0) {
// This will destroy the instance
uGnssRemove(devHandle);
Expand Down Expand Up @@ -160,7 +166,8 @@ static int32_t addDevice(uGnssTransportHandle_t gnssTransportHandle,
pContext = (uDeviceGnssInstance_t *) pUPortMalloc(sizeof(uDeviceGnssInstance_t));
if (pContext != NULL) {
memset(pContext, 0, sizeof(*pContext));
populateContext(pContext, gnssTransportHandle, deviceTransportType);
populateContext(pContext, gnssTransportHandle, deviceTransportType,
pCfgGnss->powerOffToBackup);
// Add the GNSS instance, which actually creates pDeviceHandle
errorCode = uGnssAdd((uGnssModuleType_t) pCfgGnss->moduleType,
gnssTransportType, gnssTransportHandle,
Expand Down
1 change: 1 addition & 0 deletions common/device/src/u_device_shared_gnss.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ typedef union {
typedef struct {
uDeviceGnssTransportHandle_t transportHandle;
uDeviceTransportType_t deviceTransportType;
bool powerOffToBackup;
} uDeviceGnssInstance_t;

#ifdef __cplusplus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,8 @@ properties:
gnss-uart2:
type: boolean
description: "Specify this flag if your UART connection is to the _second_ serial port of a GNSS device."
# request that the device layer powers the GNSS device off to back-up state
power-off-to-backup:
type: boolean
description: "Specify this flag if you want uDeviceClose(), when called with powerOff true, to call uGnssPwrOffBackup() instead of just uGnssPwrOff(); refer to the integration manual for your GNSS device, the backup or power section, for what the application must do to restore the GNSS device to normal operation afterwards."
# Note: there is no associated network configuration for the GNSS case
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
module-type = "U_GNSS_MODULE_TYPE_M9";
pin-enable-power = <1>;
pin-data-ready = <36>;
power-off-to-backup;
};
cfg-device-gnss-1 {
compatible = "u-blox,ubxlib-device-gnss";
Expand Down
17 changes: 15 additions & 2 deletions port/platform/zephyr/src/u_port_board_cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,16 @@ static const int32_t gDeviceCfgGnssPinDataReady[] = {
pin_data_ready)
};

/** Get whether the "power-off-to-backup" property is set
* for each ubxlib-device-gnss compatible device, in the
* order they appear in the device tree.
*/
static const bool gDeviceCfgGnssPowerOffToBackup[] = {
DT_FOREACH_STATUS_OKAY_VARGS(u_blox_ubxlib_device_gnss,
U_PORT_BOARD_CFG_GET_BOOLEAN,
power_off_to_backup)
};

#endif // #if DT_HAS_COMPAT_STATUS_OKAY(u_blox_ubxlib_device_gnss)

/* ----------------------------------------------------------------
Expand Down Expand Up @@ -1166,11 +1176,14 @@ static void cfgGnss(uDeviceCfg_t *pCfg, int32_t index)
pCfgGnss->pinEnablePower = gDeviceCfgGnssPinEnablePower[index];
pCfgGnss->pinDataReady = gDeviceCfgGnssPinDataReady[index];
pCfgGnss->i2cAddress = -1;
pCfgGnss->powerOffToBackup = gDeviceCfgGnssPowerOffToBackup[index];
uPortLog("U_PORT_BOARD_CFG: using GNSS device \"%s\" from the device tree,"
" module-type %d with pin-enable-power %d (0x%02x), pin-data-ready %d (0x%02x)...\n",
" module-type %d with pin-enable-power %d (0x%02x),"
" pin-data-ready %d (0x%02x)%s...\n",
gpCfgGnssDeviceName[index], pCfgGnss->moduleType,
pCfgGnss->pinEnablePower, pCfgGnss->pinEnablePower,
pCfgGnss->pinDataReady, pCfgGnss->pinDataReady);
pCfgGnss->pinDataReady, pCfgGnss->pinDataReady,
pCfgGnss->powerOffToBackup ? ", power-off-to-backup" : "");
// Don't need to check for NULL here as transport is a required field for GNSS
x = getPort(gpDeviceCfgGnssTransportType[index], &(pCfg->transportType));
switch (pCfg->transportType) {
Expand Down
3 changes: 3 additions & 0 deletions port/platform/zephyr/test/u_zephyr_port_board_cfg_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ U_PORT_TEST_FUNCTION("[zephyrPortBoardCfg]", "zephyrPortBoardCfgBasic")
U_PORT_TEST_ASSERT(pCfgGnss->i2cAddress == 0x43);
U_PORT_TEST_ASSERT(pCfgGnss->pinEnablePower == 1);
U_PORT_TEST_ASSERT(pCfgGnss->pinDataReady == 36);
U_PORT_TEST_ASSERT(pCfgGnss->powerOffToBackup);
// Set the second valid configuration
setDeviceCfg(&deviceCfg, &instance, U_DEVICE_TYPE_GNSS, "cfg-device-gnss-1");
U_PORT_TEST_ASSERT(uPortBoardCfgDevice(&deviceCfg) == 0);
Expand Down Expand Up @@ -448,6 +449,7 @@ U_PORT_TEST_FUNCTION("[zephyrPortBoardCfg]", "zephyrPortBoardCfgBasic")
U_PORT_TEST_ASSERT(pCfgGnss->moduleType == U_GNSS_MODULE_TYPE_M8);
U_PORT_TEST_ASSERT(pCfgGnss->pinEnablePower == 2);
U_PORT_TEST_ASSERT(pCfgGnss->pinDataReady == 37);
U_PORT_TEST_ASSERT(!pCfgGnss->powerOffToBackup);
// Set the final valid configuration
setDeviceCfg(&deviceCfg, &instance, U_DEVICE_TYPE_GNSS, "cfg-device-gnss-2");
U_PORT_TEST_ASSERT(uPortBoardCfgDevice(&deviceCfg) == 0);
Expand All @@ -468,6 +470,7 @@ U_PORT_TEST_FUNCTION("[zephyrPortBoardCfg]", "zephyrPortBoardCfgBasic")
U_PORT_TEST_ASSERT(pCfgGnss->moduleType == U_GNSS_MODULE_TYPE_ANY);
U_PORT_TEST_ASSERT(pCfgGnss->pinEnablePower == -1);
U_PORT_TEST_ASSERT(pCfgGnss->pinDataReady == -1);
U_PORT_TEST_ASSERT(!pCfgGnss->powerOffToBackup);

// Let debug printing catch up
uPortTaskBlock(100);
Expand Down

0 comments on commit d4d58a5

Please sign in to comment.