Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

src/d7a_modem.cpp

Committer:
Jeej
Date:
2016-04-01
Revision:
27:934ab7455115
Parent:
26:9f0b9833cac6
Child:
28:0376b97b4b55

File content as of revision 27:934ab7455115:

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

typedef struct {
    Thread* thread;
    Queue<void, 8> ready;
    Queue<void, 2> boot;
    Queue<d7a_com_rx_msg_t, 16> pkt_queue;
    int8_t status;
    DigitalInOut* reset;
} 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, osPriorityBelowNormal, DEFAULT_STACK_SIZE*2);
    g_modem_ctx.reset = new DigitalInOut(reset_pin, PIN_OUTPUT, OpenDrain, 0);
    
    Thread::wait(10);
    
    // Release reset pin
    *(g_modem_ctx.reset) = 1;
    
    // Wait for modem ready
    osEvent evt = g_modem_ctx.boot.get(1000);
    ASSERT(evt.status == osEventMessage, "MODEM BOOT Timeout\r\n");
}


int32_t d7a_modem_wait_ready( uint32_t millisec )
{
    FPRINT("\r\n");
    int32_t ret;
    osEvent evt = g_modem_ctx.ready.get(millisec);
    if (evt.status == osEventMessage)
    {
        ret = (int32_t)evt.value.p;
    }
    else
    {
        ret = (int32_t)0xFFFFFFFF;
        EPRINT("MODEM Wait Timeout!\r\n");
    }
    return ret;
}

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("\r\n");
    osEvent evt = g_modem_ctx.pkt_queue.get(millisec);
    return (evt.status == osEventMessage)? (d7a_com_rx_msg_t*)evt.value.p : NULL;
}

static 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_send_msg(&msg);
}

void d7a_modem_register_file(uint8_t fid, uint8_t fifo_size, uint8_t flush_policy)
{
    FPRINT("(fid:%d, fifo_size:%d, flush_policy:0x%02X)\r\n", fid, fifo_size, flush_policy);
    register_file_param_t rparams = {
        .bf.fid = fid ,
        .bf.fifo_size = fifo_size,
        .bf.flush_policy = flush_policy
    };

    // Check If modem already has it
    DPRINT("Register: %d\n", rparams.bf.fid);
    d7a_fs_distant_stat(rparams.bf.fid, NULL);
    g_modem_ctx.status = (int32_t)d7a_fs_wait_done(TO_FS);
    if(g_modem_ctx.status < 0)
    {
        d7a_fs_properties_t props;
        // retrieve local properties
        d7a_fs_get_properties(rparams.bf.fid, KAL_FS_PROP_ALL, &props);
        // create a remote Host file matching our local one
        props.type = HOST;
        d7a_fs_distant_create(rparams.bf.fid, &props);
        g_modem_ctx.status = (int32_t)d7a_fs_wait_done(TO_FS);
    }
    if(g_modem_ctx.status == 0)
    {
        // Distant file is ready, lets register a D7A Interface for it
        d7a_modem_msg(WM_CMD_REGISTER_FILE,(uint8_t*)&rparams,sizeof(register_file_param_t));
        d7a_modem_wait_ready();
    }
}

void d7a_modem_notify_file(uint8_t fid, uint32_t offset, uint32_t length)
{
    FPRINT("(fid:%d, offset:%d, length:%d)\r\n", fid, offset, length);
    notify_file_param_t nfp = {
        .bf.fid = fid,
        .bf.offset = offset,
        .bf.size = length
    };

    d7a_modem_msg(WM_CMD_NOTIFY_FILE,(uint8_t*)&nfp,sizeof(notify_file_param_t));
    d7a_modem_wait_ready();
}

void d7a_modem_infos( void )
{
    uint8_t uid[8];
    revision_t rev;
    
    d7a_fs_read(0, uid, 0, 8);
    d7a_fs_wait_done();
    
    d7a_fs_read(2, &rev, 0, sizeof(revision_t));
    d7a_fs_wait_done();
    
    IPRINT("--- D7A Modem infos ---\r\n");
    IPRINT("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]);
    IPRINT("Manufacturer ID:  %08X\r\n", rev.manufacturer_id);
    IPRINT("Device ID:        %08X\r\n", rev.device_id);
    IPRINT("Hardware version: %08X\r\n", rev.hw_version);
    IPRINT("Firmware version: %d-%d.%d.%d-%08x\r\n", rev.fw_version.id, rev.fw_version.major, rev.fw_version.minor, rev.fw_version.patch, rev.fw_version.hash);
    IPRINT("File system CRC:  0x%08x\r\n", rev.fs_crc);
    IPRINT("-----------------------\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)
                {
                    DPRINT("Modem booted\r\n");
                    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);
    }
}