Ground Control's RockBLOCK 9704 library is pinned untouched in west.yml and compiled here for any board with a UART: a serial port on the bus of the rock7,rockblock-9704 devicetree node, the library's timing calls on the kernel, and one worker thread that owns every call into it, since the library has no locking and shares static buffers. The worker sleeps until a request or a byte from the modem arrives. Requests (begin, end, power, send, info, signal) wait as long as the caller says; a send with K_NO_WAIT queues and reports through mo_done. Callbacks for a sent message, a received one, the signal and the provisioning; a status snapshot that never touches the modem. The library asks for provisioning once and keeps a miss for good; the worker clears its cache before a send whose topic is missing and after the modem refuses one, so a modem provisioned later is seen. The serial port and worker began in the OGLAS satellite bench and were carried through WII6's lib/wii6-sat.
95 lines
2.2 KiB
C
95 lines
2.2 KiB
C
/* SPDX-License-Identifier: MIT
|
|
*
|
|
* rb9704_power.c - the board's control pins, as the devicetree gives them.
|
|
*
|
|
* power-gpios P_EN, the supply
|
|
* iridium-enable-gpios I_EN, the modem, once the supply is up
|
|
* booted-gpios I_BTD, the modem saying it has booted
|
|
*
|
|
* Up: supply, a moment, enable, then the booted pin or boot-delay-ms.
|
|
* Down: enable, then supply. Called on the worker thread only.
|
|
*/
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/drivers/gpio.h>
|
|
#include <zephyr/logging/log.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include "rb9704_internal.h"
|
|
|
|
LOG_MODULE_DECLARE(rb9704, CONFIG_RB9704_LOG_LEVEL);
|
|
|
|
#define BOOT_TIMEOUT_MS 30000
|
|
|
|
static const struct gpio_dt_spec pwr = GPIO_DT_SPEC_GET_OR(RB9704_NODE, power_gpios, {0});
|
|
static const struct gpio_dt_spec en = GPIO_DT_SPEC_GET_OR(RB9704_NODE, iridium_enable_gpios, {0});
|
|
static const struct gpio_dt_spec btd = GPIO_DT_SPEC_GET_OR(RB9704_NODE, booted_gpios, {0});
|
|
|
|
static bool on;
|
|
|
|
bool rb9704_power_present(void)
|
|
{
|
|
return pwr.port != NULL;
|
|
}
|
|
|
|
bool rb9704_power_on(void)
|
|
{
|
|
return on;
|
|
}
|
|
|
|
int rb9704_power_init(void)
|
|
{
|
|
if (pwr.port == NULL) {
|
|
return -ENOTSUP;
|
|
}
|
|
if (!gpio_is_ready_dt(&pwr) || gpio_pin_configure_dt(&pwr, GPIO_OUTPUT_INACTIVE) != 0) {
|
|
return -EIO;
|
|
}
|
|
if (en.port != NULL &&
|
|
(!gpio_is_ready_dt(&en) || gpio_pin_configure_dt(&en, GPIO_OUTPUT_INACTIVE) != 0)) {
|
|
return -EIO;
|
|
}
|
|
if (btd.port != NULL && (!gpio_is_ready_dt(&btd) || gpio_pin_configure_dt(&btd, GPIO_INPUT) != 0)) {
|
|
return -EIO;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int rb9704_power_set(bool want)
|
|
{
|
|
if (pwr.port == NULL) {
|
|
return -ENOTSUP;
|
|
}
|
|
if (!want) {
|
|
if (en.port != NULL) {
|
|
(void)gpio_pin_set_dt(&en, 0);
|
|
}
|
|
(void)gpio_pin_set_dt(&pwr, 0);
|
|
on = false;
|
|
return 0;
|
|
}
|
|
if (on) {
|
|
return 0;
|
|
}
|
|
(void)gpio_pin_set_dt(&pwr, 1);
|
|
k_msleep(10);
|
|
if (en.port != NULL) {
|
|
(void)gpio_pin_set_dt(&en, 1);
|
|
}
|
|
if (btd.port != NULL) {
|
|
int64_t until = k_uptime_get() + BOOT_TIMEOUT_MS;
|
|
|
|
while (gpio_pin_get_dt(&btd) != 1) {
|
|
if (k_uptime_get() > until) {
|
|
LOG_ERR("modem did not signal booted in %d ms", BOOT_TIMEOUT_MS);
|
|
return -ETIMEDOUT;
|
|
}
|
|
k_msleep(50);
|
|
}
|
|
} else {
|
|
k_msleep(DT_PROP(RB9704_NODE, boot_delay_ms));
|
|
}
|
|
on = true;
|
|
return 0;
|
|
}
|