Fork for Get Started Demo

Dependencies:   DebouncedInterrupt dash7-alp mbed-rtos mbed wizzi-utils

Fork of D7A_Demo_full by WizziLab

main.cpp

Committer:
Jeej
Date:
2015-11-19
Revision:
3:b77b01171cc0
Parent:
2:c3cfaa7d5bb8
Child:
4:1edd956b015f

File content as of revision 3:b77b01171cc0:

#include "mbed.h"
#include "rtos.h"
#include "dbg.h"
#include "shield.h"
#include "alp_serial.h"
#include "alp_device.h"
#include "alp_file.h"
#include "alp_report.h"
#include "DebouncedInterrupt.h"


/*
These data are user defined and will be used by the dash7board
to identify the device
*/

#define __MANUFACTURER_ID__         0x01234567 // Identify the manufacturer
#define __DEVICE_ID__               0x89ABCDEF // Identify the device type

#define __FW_ID__                   0x01 // Firmware ID

// Firmware version
#define __FW_MAJOR__                0x02
#define __FW_MINOR__                0x03
#define __FW_PATCH__                0x0045
#define __FW_HASH__                 0x86605dba

#define __HW_ID__                   0x01520C02 // Hardware ID

revision_t revision = {
    // The two first bytes must be present in all reported files
    // They are parsed by the dash7board
    .nw_stat = 0,
    .nw_seq = 255,
    // These data are parsed to identify the device
    .manufacturer_id    = __MANUFACTURER_ID__,
    .device_id          = __DEVICE_ID__,
    .fw_version.fw_id   = __FW_ID__,
    .fw_version.major   = __FW_MAJOR__,
    .fw_version.minor   = __FW_MINOR__,
    .fw_version.patch   = __FW_PATCH__,
    .fw_version.hash    = __FW_HASH__,
    .hw_version         = __HW_ID__,
    .fs_crc             = 0
};

// Alarm data structure
TYPEDEF_STRUCT_PACKED
{
    uint8_t  nw_stat;
    uint8_t  nw_seq;
    uint8_t  status; // Alarm state true/false
} alarm_data_t;

#define ALARM_DATA_FILE_ID          (224)
#define ALARM_DATA_FILE_SIZE        ((uint16_t) sizeof(alarm_data_t))

alarm_data_t alarm_data = {
    .nw_stat = 0,
    .nw_seq = 255,
    .status = 0
};

// Checks the status of the report send.
void check_status( AlpReport* report, void* param )
{
    char* message = (char*)param;
    uint8_t status = report->get_status();
    switch (status)
    {
        case ALP_CMD_OK: // message is send and acknowleged
            DPRINT("%s OK\r\n", message);
        break;
        case ALP_CMD_TIMEOUT: // message has not been acknowleged by modem
            DPRINT("%s CMD TIMEOUT\r\n", message);
        break;
        case ALP_CMD_ERROR: // message has been acknowleged by modem but returned an error
            DPRINT("%s CMD ERROR\r\n", message);
        break;
        case ALP_D7_TIMEOUT: // message has not been acknowleged by gateway
            DPRINT("%s D7 TIMEOUT\r\n", message);
        break;
        case ALP_D7_ERROR: // message has been acknowleged by gateway but returned an error
            DPRINT("%s D7 ERROR\r\n", message);
        break;
        default:
            DPRINT("%s UNKNOWN ERROR %d\r\n", message, status);
        break;
    }
}


// Semaphore for notifiying button presses
Semaphore button_user(1);


// Prints the alarm status.
void print_alarm( AlpReport* report, void* param )
{
    alarm_data_t* alarm = (alarm_data_t*)report->get_content();
    DPRINT("SENDING REPORT ALARM %d\r\n", alarm->status);
}

// Interrupt Service Routine on button press.
// Inverts alarm status and releases button Semaphore.
void button_push_isr( void )
{
    DPRINT("BUTTON PUSH\r\n");
    // Retrieve file content
    alarm_data_t* alarm = (alarm_data_t*)alp_file_get_content(ALARM_DATA_FILE_ID);
    // Invert alarm status
    alarm->status = !alarm->status;
    // Release button Semaphore
    button_user.release();
}

// This Thread monitors the user button
// and reports the alarm status
void alarm_thread( const void* args )
{
    // Get shield device
    AlpDevice* shield = (AlpDevice*)args;
    
    // Create new report
    AlpReport report_alarm(shield, ALARM_DATA_FILE_ID);
    report_alarm.attach_before(print_alarm, NULL);
    report_alarm.attach_after(check_status, (void*)"REPORT ALARM");
    
    // Enable interrupt on User button
    //__enable_irq(); // Enable Interrupts
    DebouncedInterrupt button(USER_BUTTON);
    button.attach(&button_push_isr, IRQ_FALL, 200);

    while(true)
    {
        // Wait for button press
        button_user.wait();

        // Notify alarm status
        report_alarm.send();
    }
}

int main()
{
    // ----- Debug session over USB Serial ----- //
    DBG_OPEN();
        
    // Clear some lines on the terminal
    DPRINT("\r\n\nBOOT\r\n");
    
    // Declare Shield NRST pin
    DigitalOut shield_nrst(PB_0);
    
    // Reset shield
    shield_nrst = 0;
    
    // Open ALP port over serial
    // This is the physical ALP serial port
    AlpSerial serial_shield;

    // Initialize ALP device
    // This creates an AlpDevice object abstracting the shield1001
    // The parameters describe how to access it
    AlpDevice shield(&serial_shield, 0, ACCESS_CLASS_EP, ALP_FILE_BLOCK_ISFB, true);

    // Release reset
    shield_nrst = 1;
    
    // Check the shield boot packets
    shield_check_boot(&shield);
    
    // Wait for Shield to notify its files if there is any
    Thread::wait(1000);
    
    // Add the files to the file system
    alp_file_add(ALARM_DATA_FILE_ID,      ALARM_DATA_FILE_SIZE,      (uint8_t*)&alarm_data);
    alp_file_add(REVISION_DEVICE_FILE_ID, REVISION_DEVICE_FILE_SIZE, (uint8_t*)&revision);
    
    // Create the Revision report
    AlpReport report_revision(&shield, REVISION_DEVICE_FILE_ID);
    
    // Attach callback after report is send
    report_revision.attach_after(check_status, (void*)"REPORT REVISION");
    
    // Send the Revision report
    DPRINT("SENDING REPORT REVISION\r\n");
    report_revision.send();
    
    // Init Thread
    Thread t_alarm_thread(alarm_thread, &shield);
    
    // Set main task to lowest priority
    osThreadSetPriority(osThreadGetId(), osPriorityIdle);
    while(true)
    {
        // Wait to avoid beeing stuck in loop
        Thread::wait(osWaitForever);
    }
}