u-blox / ubxlib

Portable C libraries which provide APIs to build applications with u-blox products and services. Delivered as add-on to existing microcontroller and RTOS SDKs.
Apache License 2.0
287 stars 82 forks source link

sara-r412m-02b Unable to bring up the device! #164

Closed alexmaron81 closed 7 months ago

alexmaron81 commented 8 months ago

Sometimes it happens that the module no longer works. If it doesn't work once, the next attempts will also be unsuccessful until the device is disconnected from the power supply.

AT U_CELL_PWR: powering on. AT AT AT AT AT AT AT AT AT AT AT AT AT AT AT AT AT AT AT AT Opened device with return code -7. Unable to bring up the device!

RobMeades commented 8 months ago

Hi Alex: so is it the case that holding RESET_N low (e.g. by calling uCellPwrResetHard()) does not recover the device either? From the integration manual, section 1.6.3:

image

...and, from the data sheet, section 4.2.11:

image

The function uCellPwrResetHard() is aware of this timing and should hold the pin low for the correct amount of time.

alexmaron81 commented 7 months ago

Hi Rob,

yes the U_CFG_APP_PIN_CELL_RESET pin is defined for me and if "err = uDeviceOpen(&gDeviceCfg, &devHandle)" doesn't work, I call "uCellPwrResetHard(devHandle, U_CFG_APP_PIN_CELL_RESET);" on. Unfortunately the same thing happens the next time you connect. Can I check whether the "uCellPwrResetHard" is actually carried out?

alexmaron81 commented 7 months ago

Is the following way correct?

esp_err_t err = ESP_FAIL;

uPortInit();
uDeviceInit();

err = uDeviceOpen(&gDeviceCfg, &devHandle);
uPortLog("Opened device with return code %d.\n", err);

if (err == 0)
{
         // Connected
}
else
{

       uCellPwrResetHard(devHandle, U_CFG_APP_PIN_CELL_RESET);

}

alexmaron81 commented 7 months ago

u_cell_pwr.c -> if ((pInstance != NULL) && (pinReset >= 0)) {

the "pInstance" is NULL

RobMeades commented 7 months ago

Ah, sorry, I'd thought that in your application you would be using the module, so uDeviceOpen() would have returned a valid handle, you would find that the module had become unresponsive: then you would call uCellPwrResetHard().

None of the APIs in ubxlib will work if the module was already unresponsive at the point that uDeviceOpen() was called. For that case you just need to drive the GPIO pin of your MCU that is connected to the RESET_N pin of the module low for the requisite amount of time, doing this directly using your platform APIs. I believe you are using ESP-IDF so something like:

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/rtc_io.h"

gpio_config_t config;
int32_t x;

#define MY_RESET_N_PIN (U_CFG_APP_PIN_CELL_RESET & 0xFF)

// Only required if MY_RESET_N_PIN is an RTC pin but no harm in doing this in all cases
rtc_gpio_deinit(MY_RESET_N_PIN);

// Configure the pin
config.intr_type = GPIO_INTR_DISABLE;
config.mode = GPIO_MODE_OUTPUT_OD;
config.pull_down_en = GPIO_PULLDOWN_DISABLE;
config.pull_up_en = GPIO_PULLUP_DISABLE;
config.pin_bit_mask = 1ULL << MY_RESET_N_PIN;
x = gpio_config(&config);
if (x == ESP_OK) {
    // Set the pin low
    x = gpio_set_level((gpio_num_t) MY_RESET_N_PIN, 0); 
    if (x == ESP_OK) {
        // Wait for 15 seconds (only 10 required, being generous)
        vTaskDelay(15000/ portTICK_PERIOD_MS);
        // Set the pin high once more
        gpio_set_level((gpio_num_t) MY_RESET_N_PIN, 1);
    } else {
        printf("Unable to set level of pin %d (%d)!\n", MY_RESET_N_PIN, x);
    }
} else {
    printf("Unable to configure pin %d (%d)!\n", MY_RESET_N_PIN, x);
}
alexmaron81 commented 7 months ago

I'm relieved that it worked. Thanks Rob!

RobMeades commented 7 months ago

Good stuff!