Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

src/d7a_modem.cpp

Committer:
Jeej
Date:
2016-08-30
Revision:
44:8ebe6b70f932
Parent:
43:28202405094d
Parent:
42:1578f0480dcb
Child:
45:b85384e7d825

File content as of revision 44:8ebe6b70f932:

#include "mbed.h"
#include "rtos.h"
#include "dbg.h"
#include "d7a_com.h"
#include "d7a_fs.h"
#include "d7a_modem.h"
#include "d7a_sys.h"
#include "d7a_common.h"
#include "d7a.h"

#define MODEM_TO    (5000)

typedef struct {
    Thread* thread;
    Queue<void, 8> ready;
    Queue<void, 2> boot;
    Queue<d7a_com_rx_msg_t, 16> pkt_queue;
    Queue<register_file_param_t, 64> registered_files;
    uint8_t nb_files;
    int8_t status;
    DigitalInOut* reset;
    bool booted;
} d7a_modem_ctx_t;

d7a_modem_ctx_t g_modem_ctx;

void d7a_modem_thread(const void *p);

void d7a_modem_open( PinName reset_pin )
{
    FPRINT("\r\n");
    
    g_modem_ctx.thread = new Thread(d7a_modem_thread, NULL, osPriorityHigh, DEFAULT_STACK_SIZE);
    g_modem_ctx.booted = false;
    g_modem_ctx.nb_files = 0;
    
    if (reset_pin == NC)
    {
        g_modem_ctx.reset = NULL;
    }
    else
    {
        g_modem_ctx.reset = new DigitalInOut(reset_pin, PIN_OUTPUT, OpenDrain, 1);
    }

    d7a_modem_reset();
}

static bool d7a_modem_wait_boot( uint32_t millisec )
{
    FPRINT("(%d)\r\n", millisec);
    osEvent evt = g_modem_ctx.boot.get(millisec);
    return (evt.status == osEventMessage)? true: false;
}


static bool d7a_modem_wait_ready( uint32_t millisec )
{
    FPRINT("(%d)\r\n", millisec);
    osEvent evt = g_modem_ctx.ready.get(millisec);
    return (evt.status == osEventMessage)? true: false;
}

static void d7a_modem_soft_reset(void)
{
    FPRINT("\r\n");
    IPRINT("MODEM Soft Reset.\r\n");
            
    // Clean buffer and queues
    d7a_com_restart();
    
    // Try software reset
    d7a_sys_software_reset();
}

static void d7a_modem_hard_reset(void)
{
    FPRINT("\r\n");
    
    ASSERT(g_modem_ctx.reset != NULL, "No reset PIN specified\r\n");
    
    IPRINT("MODEM Hard Reset.\r\n");
    
    // Use hardware reset
    // Assert reset pin
    *(g_modem_ctx.reset) = 0;
    
    // Clean buffer and queues
    d7a_com_restart();
    Thread::wait(100);
    
    // Release reset pin
    *(g_modem_ctx.reset) = 1;
    
}

void d7a_modem_reset(void)
{
    FPRINT("\r\n");
    bool reset_ok = false;
    g_modem_ctx.booted = false;

    //d7a_modem_soft_reset();
    //reset_ok = d7a_modem_wait_boot(5000);
    
    if (!reset_ok)
    {
        d7a_modem_hard_reset();
        reset_ok = d7a_modem_wait_boot(MODEM_TO);
    }
    ASSERT(reset_ok, "MODEM BOOT Timeout\r\n");
    g_modem_ctx.booted = true;
    
    ASSERT(d7a_modem_wait_ready(MODEM_TO), "MODEM READY Timeout\r\n");
    IPRINT("MODEM Ready.\r\n");
}

void d7a_modem_new_pkt(d7a_com_rx_msg_t* pkt)
{
    FPRINT("\r\n");
    ASSERT(g_modem_ctx.pkt_queue.put(pkt) == osOK, "MODEM queue full!\r\n");
}

d7a_com_rx_msg_t* d7a_modem_wait_pkt(uint32_t millisec)
{
    FPRINT("(millisec:%d)\r\n", millisec);
    osEvent evt = g_modem_ctx.pkt_queue.get(millisec);
    return (evt.status == osEventMessage)? (d7a_com_rx_msg_t*)evt.value.p : NULL;
}

void d7a_modem_msg(uint8_t value, uint8_t* buf, uint8_t len)
{
    FPRINT("(value:0x%02X, buf:0x%08x, len:%d)\r\n", value, buf, len);
    d7a_com_tx_msg_t msg;
    uint8_t val = value;
    msg.id = KAL_COM_FLOW_CMD;
    msg.pbuf = &val;
    msg.abuf = buf;
    msg.plen = 1;
    msg.alen = len;
    d7a_com_post_msg(&msg);
}

bool d7a_modem_register(register_file_param_t* file_infos)
{
    bool err;
    
    DPRINT("Declare %d.\r\n", file_infos->fid);

    d7a_modem_msg(WM_CMD_DECLARE_FILE, (uint8_t*)file_infos, sizeof(register_file_param_t));
    err = d7a_modem_wait_ready(TO_FS);
    
    WARNING(!err, "Timeout on declare FID:%d\r\n", file_infos->fid);
        
    DPRINT("Declare %d done.\r\n", file_infos->fid);
    
    return err;
}

bool d7a_modem_start(void)
{
    bool err;
    
    DPRINT("Start modem.\r\n");

    d7a_modem_msg(WM_CMD_START_STACK, NULL, 0);
    err = d7a_modem_wait_ready(TO_FS);
    
    WARNING(!err, "Timeout on start\r\n");
        
    DPRINT("Start done.\r\n");
    
    return err;
}

bool d7a_modem_stop(void)
{
    bool err;
    
    DPRINT("Stop modem.\r\n");

    d7a_modem_msg(WM_CMD_STOP_STACK, NULL, 0);
    err = d7a_modem_wait_ready(TO_FS);
    
    WARNING(!err, "Timeout on stop\r\n");
        
    DPRINT("Stop done.\r\n");
    
    return err;
}

void d7a_modem_print_infos( void )
{
    uint8_t uid[8];
    d7a_revision_t rev;
    
    //D7A_FS_READ(0, uid, 0, 8);
    //D7A_FS_READ(2, &rev, 0, sizeof(d7a_revision_t));
    
    PRINT("------------ D7A Modem infos ------------\r\n");
    PRINT("| UID:              %02X%02X%02X%02X%02X%02X%02X%02X    |\r\n", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7]);
    PRINT("| Manufacturer ID:  %08X            |\r\n", rev.manufacturer_id);
    PRINT("| Device ID:        %08X            |\r\n", rev.device_id);
    PRINT("| Hardware version: %08X            |\r\n", rev.hw_version);
    PRINT("| Firmware version: %d-%d.%d.%d-%08x \t|\r\n", rev.fw_version.id, rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, rev.fw_version.hash);
    PRINT("| File system CRC:  0x%08x          |\r\n", rev.fs_crc);
    PRINT("-----------------------------------------\r\n");
    
}

void d7a_modem_thread(const void *p)
{
    FPRINT("\r\n");
    d7a_com_rx_msg_t* pkt;
    
    while (true)
    {
        pkt = d7a_modem_wait_pkt();
        ASSERT(pkt != NULL, "MODEM NULL pkt\r\n");

        switch(pkt->id)
        {
            case KAL_COM_FLOW_CMD:
                uint8_t cmd = pkt->buffer[0];
                if (cmd == WM_CMD_READY)
                {
                    DPRINT("Modem ready\r\n");
                    g_modem_ctx.ready.put(NULL);
                }
                else if (cmd == WM_CMD_BOOT)
                {
                    WARNING(false, "Modem booted CAUSE:%d NB_BOOT:%d\r\n", pkt->buffer[1], ((uint16_t)pkt->buffer[4])<<8 & pkt->buffer[3]);
                    
                    if (g_modem_ctx.booted == true)
                    {
                        // Do something?
                    }
                    else
                    {
                        g_modem_ctx.boot.put(NULL);
                    }
                }
                else
                {
                    EPRINT("MODEM Unknown cmd %d\r\n", cmd);
                }
                break;
            default:
                EPRINT("MODEM Unknown Flow ID 0x%02X\r\n", pkt->id);
                break;
        }
        
        FREE(pkt);
    }
}