1st working program

Dependencies:   mbed-os_TYBLE16 BME280_SPI RX8025NB nRF51_Vdd MB85RSxx_SPI

see /users/kenjiArai/notebook/tyble16-module-as-mbed-os-5-board-mbedlization/

main.cpp

Committer:
kenjiArai
Date:
2019-12-22
Revision:
9:8c9e6e270b67
Parent:
8:7e42f8dc42a2

File content as of revision 9:8c9e6e270b67:

/*
 * Mbed Application program / TYBLE-16 Data logger
 *
 * Copyright (c) 2019 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  https://os.mbed.com/users/kenjiArai/
 *      Created:    December  14th, 2019
 *      Revised:    December  22nd, 2019
 */

//  Include --------------------------------------------------------------------
#include "mbed.h"
#include "TYBLE16_BASE.h"
#include "dt_logger.h"
#include "nRF51_Vdd.h"
#include "RX8025NB.h"
#include "BME280_SPI.h"
#include "MB85RSxx_SPI.h"

//  Definition -----------------------------------------------------------------
#define KEPP_SLEEP_TIME 1               // 0= continuos mode (every 10sec)           
#define SLEEP_TIME      2               // Sleep 2 minutes
#define FRAM_ID         (0x047f4803)    // Fijitsu 2Mbits

//  Constructor ----------------------------------------------------------------
DigitalOut  bme280_pwr(D9, 1);  // BME280 sensor power on
DigitalOut  fram_pwr(D5, 1);    // FRAM power on
DigitalInOut  x0(I2C_SDA, PIN_OUTPUT, PullUp, 1);    // I2C for dummy
DigitalInOut  x1(I2C_SCL, PIN_OUTPUT, PullUp, 1);    // I2C for dummy
InterruptIn rtc_irq(P0_2, PullUp);
Serial      pc(USBTX, USBRX);
nRF51_Vdd   vdd(3.6f, 1.6f, ONLY4VDD);

//  RAM ------------------------------------------------------------------------
uint8_t fram_id[4];
bool fram_ready = false;

// Global data
time_t log_sec;
float vcc_voltage;
float barometer;
float temperature;
float humidity;

//  ROM / Constant data --------------------------------------------------------
const char *const opngmsg0 =
    "\r\n---------\r\nCompiled on " __DATE__ " " __TIME__ " (UTC)\r\n";
const char *const opngmsg1 =
    "Project: TYBLE16_simple_data_logger  by Kenji Arai\r\n";

//  Function prototypes --------------------------------------------------------
static void rtc_interrupt(void);
static void goto_standby(void);
static void priparation_for_sleep(void);
time_t w_check_rtc_time(RX8025 &ex_rtc);

//------------------------------------------------------------------------------
//  Control Program
//------------------------------------------------------------------------------
int main()
{
    char buf[64];               // data buffer for text
    time_t seconds;

    // open message
    pc.puts(opngmsg0);
    pc.puts(opngmsg1);
    // Check TYBLE-16 configuration
    cpu_sys();
    compile_condition();
    // Create constructor
    // BM280
    BME280_SPI bme280(SPIS_PSELMOSI, SPIS_PSELMISO, SPIS_PSELSCK, P0_25);
    // FRAM
    MB85RSxx_SPI fram(SPIS_PSELMOSI, SPIS_PSELMISO, SPIS_PSELSCK, P0_6);
    fram.read_device_id(fram_id);
    uint32_t id = 0, num = 24;
    for (uint32_t i = 0; i < 4; i++) {
        id += fram_id[i] << num;
        num -= 8;
    }
    pc.printf("FRAM ID=0x%08x", id);
    if (id == FRAM_ID) {
        fram_ready = true;
    }
    if (fram_ready == true) {
        pc.printf("(looks like Fujitsu MB85RS2M)\r\n");
    } else {
        pc.printf("(unknown device)\r\n");
    }
    // RX8025
    RX8025 ex_rtc(I2C_SDA, I2C_SCL);    // RTC(RX8025) (Fixed address)
    ThisThread::sleep_for(20);
    ex_rtc.clear_alarmD_INTA();
    w_check_rtc_time(ex_rtc);
    int32_t count = 3;
    while(true) {
        seconds = w_check_rtc_time(ex_rtc);
        log_sec = seconds;
        strftime(buf, 50, "%Y/%m/%d,%H:%M:%S, ", localtime(&seconds));
        barometer = bme280.getPressure();
        temperature = bme280.getTemperature();
        humidity = bme280.getHumidity();
        vcc_voltage = vdd.read_real_value();
        if (count == 1) {
            pc.printf("%s", buf);
            pc.printf("%+2.2f,%2.2f,%04.2f,",
                      temperature, humidity, barometer);
            pc.printf("%3.2f\r\n", vcc_voltage);
        }
        ThisThread::sleep_for(200);
        if (pc.readable() == 1) {
            mon(ex_rtc, fram);
        }
        if (--count <= 0) {
            break;
        }
    }
    dtlog_data_pack();          // Data preparation for FRAM
    dtlog_one_write(fram);      // Write data to FRAM
#if KEPP_SLEEP_TIME
    rtc_irq.fall(&rtc_interrupt);
    uint16_t sleeping_time = SLEEP_TIME;
    pc.printf("Enter sleep mode and wake up after %d minutes\r\n",
              sleeping_time);
    ex_rtc.set_next_alarmD_INTA(sleeping_time);
    //----- SLEEP --------------------------------------------------------------
    // FRAM & BME280 power off
    bme280_pwr = 0;
    fram_pwr = 0;
    priparation_for_sleep();
    // Enter sleep mode
    ThisThread::sleep_for((sleeping_time) * 60 * 1000 + 10000);
    system_reset();
#else
    // FRAM & BME280 power off
    bme280_pwr = 0;
    fram_pwr = 0;
    priparation_for_sleep();
    ThisThread::sleep_for(8000);
    system_reset();
#endif
}

void priparation_for_sleep(void)
{
    // SPI output keeps low
    DigitalOut p0(SPIS_PSELMOSI, 0);
    DigitalOut p1(SPIS_PSELSCK, 0);
    DigitalOut p2(P0_25, 0);
    DigitalOut p3(P0_6, 0);
    // SPI MISO sets pulldown
    DigitalIn  p4(SPIS_PSELMISO, PullDown);
    // Periperal power off
    NRF_UART0->ENABLE = 0;
    NRF_UART0->POWER  = 0;
    NRF_TWI1->ENABLE  = 0;
    NRF_TWI1->POWER   = 0;
    NRF_SPI0->ENABLE  = 0;
    NRF_SPI0->POWER   = 0;
    NRF_SPIS1->ENABLE = 0;
    NRF_SPIS1->POWER  = 0;
    NRF_ADC->ENABLE   = 0;
    NRF_ADC->POWER    = 0;
}

void rtc_interrupt(void)
{
    system_reset();
}

time_t w_check_rtc_time(RX8025 &ex_rtc)
{
    time_t seconds_1st, seconds_2nd, diff;
    struct tm t;

    for (uint32_t i = 0; i < 10; i++) {
        ex_rtc.get_time_rtc(&t);   // read External RTC data
        seconds_1st = mktime(&t);
        ex_rtc.get_time_rtc(&t);   // read External RTC data again (make sure)
        seconds_2nd = mktime(&t);
        diff = seconds_2nd - seconds_1st;
        if ((diff == 0) || (diff == 1)) {
            if (seconds_2nd > DATE_COUNT_START) {
                return seconds_2nd;
            }
        }
    }
    // Without success
    system_reset();
}