New work version with additional functions

Dependencies:   4DGL-UC ConfigFile MODSERIAL mbed mbos

Fork of CDU_Mbed_35 by Engravity-CDU

main.cpp

Committer:
WillemBraat
Date:
2014-10-08
Revision:
20:2d6ac4577e68
Parent:
17:b3545e9d38f7

File content as of revision 20:2d6ac4577e68:

// L. van der Kolk,  W.Braat  
// File:  main.cpp  
// CDU Mbed version 30
// ----------------------------------------- 

#include "mbed.h"
#include "MODSERIAL.h"
#include "mbos.h"
#include "mbos_def2.h"   // : Mbos tasks, timer and resource definitions
#include "pins.h"
#include "main.h"

// Setup USB communication defined by Mbed USB TX and RX lines
// with TX and RX ringbuffers :
MODSERIAL USB(USBTX, USBRX, 256, 1024);    //256, 1024
DigitalOut alive_led( HEARTBEAT ); // : LED 1 on Mbed board toggles when CDU is alive
DigitalOut PWR_led( PWR_ON );      // : LED 4 on Mbed board is ON when external power applied to board
InterruptIn PWR_MON( PWR_IN );     // : Power monitor: input is connected to +5V and indirect to +12V
 
 //void test_update_flags(); // << for testing only << !!!!!!!

// --- Debug only ----------------------------------------
// extra serial port to show debug info :
  MODSERIAL SERIAL_DEBUG(MODSERIAL_TX, MODSERIAL_RX, 512, 64);  //: tx, rx
// -------------------------------------------------------

int CDU_FS_interface = Serial_USB;   // : defines interface to FS: 0 = Serial_USB, 1 = Ethernet
extern int key_hit_ID;
extern PwmOut BGL_LED;

void init_USB(void);
void set_initial_data(void); // : fill datastructures with initial data
void Send_KEY_message(int key_nr);
void Send_ALIVE_message(int seconds);
void collect_FSdata();

mbos CDU_OS( 9, 5, 5); // : instantiate mbos O.S (tasks, timers, resources)

// Task function prototypes:
void ALIVE_TASK(void);
void RECEIVE_DECODE_TASK(void);
void SEND_KEYMESSAGE_TASK(void);
void CDU_DSP_CSS_TASK(void);
void READ_POT_TASK(void);

// keyboard function prototypes:
void CDU_KB_COMM_INIT(void);
void CDU_KB_INT_START(void);
void CDU_KB_GET_KEY(void);
void CDU_SET_BGL_INTENSITY(int);

// display function prototypes:
void CDU_InitDisplay(void);
void CDU_ScreenAlign(void);
void CDU_StartScreen(void);
void CDU_LogoScreen(void);
void CDU_Waiting(void);
void CDU_Page(void);
void CDU_DSP_CSS(void);
void CDU_displayclear(void);

void CDU_Screens();

void CDU_BOOT();    //reboot CDU


//------ USB buffer overflow interrupt handling: -------------
void rx_buf_overflow(MODSERIAL_IRQ_INFO *q)
{   // This functiom will be called when RX buffer overflows.
    // Blue-Leds-of-Death will be showed on Mbed board
    error("RX OVERFLOW !");
}

void tx_buf_overflow(MODSERIAL_IRQ_INFO *q)
{   // This functiom will be called when TX buffer overflows.
    // Blue-Leds-of-Death will be showed on Mbed board
    error("RX OVERFLOW !");
}
//------------------------------------------------------------

void init_USB()
{   // -- This function controls the setup for the CDU-FS USB communication --
    // Function char_received() will be attached to RX interrupt.
    USB.baud(38400);     // :  set default baudrate to 38400
    USB.rxBufferFlush(); // : empty USB rx buffer in case it is not empty:
    USB.txBufferFlush(); // : empty USB tx buffer in case it is not empty:
    USB.attach(&rx_buf_overflow, MODSERIAL::RxOvIrq); // : attach function to call when USB RX buffer overflows
    USB.attach(&tx_buf_overflow, MODSERIAL::TxOvIrq); // : attach function to call when USB TX buffer overflows
}

char CheckExtPower()
{
    char ExtPower =0;
    ExtPower = PWR_MON; //check on power input: if +5V is ON return 1 else 0
    //PWR_led  = ExtPower;
    return ExtPower;
}

void EXT_PWR_DN()
{
    //external power failed, reboot CDU!
    CDU_BOOT();
}



main() // : MBOS main() 
{
    /* Check for a valid external power flag during boot sequence
       When no external power is applied the VGA board and Keyboard chip are not operational
       After initialization disconnecting external power will trigger interrupt to reboot.
    */  
    
    PWR_MON.mode( PullDown );    //create a solid 0 when no external power supplied
    while (! CheckExtPower() );  //wait for external power to come up
    PWR_led = PWR_MON ;          //switch on LED for external power indicator
    PWR_MON.fall(&EXT_PWR_DN);   //Bind function to handle interrupt when external power fails
    
    init_USB();  // : setup USB communication to FS
     
    // CDU keyboard initialisation and keyboard interrupt setup:
    CDU_KB_COMM_INIT();
    CDU_KB_INT_START();
    BGL_LED.period(0.01);
    
    // CDU display initialisation:
    CDU_InitDisplay();
    //CDU_StartScreen();
    //CDU_LogoScreen();
    wait(2);
    //CDU_Screens();
    CDU_Waiting();
    //CDU_Page();
    //CDU_ScreenAlign();
    //        
    set_initial_data(); //: fill FS datastructures with initial data

    // -- debug only -------------------------------------      
    SERIAL_DEBUG.baud(38400); // : set baudrate to 38400
    SERIAL_DEBUG.printf("\n--- CDU_Mbed_30 ---\r\n");
    // ---------------------------------------------------

    // Create all mbos tasks, timers and resources:
    // Tasks:
    CDU_OS.CreateTask(ALIVE_TASK_ID, ALIVE_TASK_PRIO, ALIVE_TASK_STACK_SZ, ALIVE_TASK);
    CDU_OS.CreateTask(RECEIVE_DECODE_TASK_ID, RECEIVE_DECODE_TASK_PRIO, RECEIVE_DECODE_TASK_STACK_SZ, RECEIVE_DECODE_TASK);
    CDU_OS.CreateTask(SEND_KEYMESSAGE_TASK_ID, SEND_KEYMESSAGE_TASK_PRIO, SEND_KEYMESSAGE_TASK_STACK_SZ, SEND_KEYMESSAGE_TASK);
    CDU_OS.CreateTask(CDU_DSP_CSS_TASK_ID, CDU_DSP_CSS_TASK_PRIO, CDU_DSP_CSS_TASK_STACK_SZ, CDU_DSP_CSS_TASK );
    CDU_OS.CreateTask(READ_POT_TASK_ID, READ_POT_TASK_PRIO, READ_POT_TASK_STACK_SZ, READ_POT_TASK );
    // Timers:
    CDU_OS.CreateTimer(READ_POT_TIMER_ID, READ_POT_TASK_ID, READ_POT_TIMER_EVENT);
    CDU_OS.CreateTimer(ALIVE_TIMER_ID, ALIVE_TASK_ID, ALIVE_EVENT);
    CDU_OS.CreateTimer(DECODE_TIMER_ID, RECEIVE_DECODE_TASK_ID, DECODE_TIMER_EVENT); 
    // Resources:
    CDU_OS.CreateResource(USB_TX_RESOURCE, USB_TX_PRIO);
    CDU_OS.CreateResource(FS_DATA_RESOURCE, FS_DATA_PRIO); 

    // Start mbos O.S with a final statement in main() :
    CDU_OS.Start(); // : MBOS is running tasks now....
    // end of main  <<---- program never reaches this point !
}

void RECEIVE_DECODE_TASK(void)
{   // Mbos task triggered by mbos timer to scan USB receive buffer every 100 msec.
    // Collects and decodes data received from USB.
    CDU_OS.SetTimer( DECODE_TIMER_ID, DECODE_TIMER_PERIOD, DECODE_TIMER_PERIOD );
    while(1) { // : loop forever because it is a mbos taskfunction
        CDU_OS.WaitEvent(DECODE_TIMER_EVENT );   // : wait for Mbos timer event
        // start collecting and decoding of received data:
        CDU_OS.LockResource(FS_DATA_RESOURCE); // : lock FS database 
        collect_FSdata();
        CDU_OS.FreeResource(FS_DATA_RESOURCE); // : free FS database
    }
}

void SEND_KEYMESSAGE_TASK(void)
{   // Mbos task triggered by a KEY_EVENT ( = "CDU key pressed" )
    while(1) {  // : loop forever because it is a mbos taskfunction
        CDU_OS.WaitEvent(KEY_EVENT); // : wait for KEY event 
        CDU_KB_GET_KEY(); // : read key from CDU keyboard
        CDU_OS.LockResource(USB_TX_RESOURCE);
        Send_KEY_message(key_hit_ID);
        CDU_OS.FreeResource(USB_TX_RESOURCE);
        key_hit_ID = 0;   // : reset key_hit_ID flag
    }
}

void ALIVE_TASK(void)
{   // Mbos task triggered by mbos timer to send ALIVE message to FS every 5 sec.
    CDU_OS.SetTimer( ALIVE_TIMER_ID, ALIVE_TIMER_PERIOD, ALIVE_TIMER_PERIOD );
    static int seconds = 0;
    while(1) { // : loop forever because it is a mbos taskfunction
        CDU_OS.WaitEvent(ALIVE_EVENT ); // : wait for Mbos timer event (5 sec)
        seconds += 5 ; // : increase seconds by 5
        if (seconds >= 60) seconds = 0 ; // : overflow handling
        CDU_OS.LockResource(USB_TX_RESOURCE);
        Send_ALIVE_message(seconds);
        CDU_OS.FreeResource(USB_TX_RESOURCE);
        alive_led = !alive_led;  // : toggle LED
    }
}

void CDU_DSP_CSS_TASK(void) 
{   // Mbos task to read new screendata from FS datastructures and show on CDU screen.
    // Triggered by FS_DATA_EVENT ( = "new screendata available" )
    while(1) { // : loop forever because it is a mbos taskfunction
    
              if (CDU_OS.TestResource(FS_DATA_RESOURCE) == 0) {
                // FS_DATA_RESOURCE is free to access.
                // Lock it to get exclusive access and prevent intermediate updates:
                CDU_OS.LockResource(FS_DATA_RESOURCE); 
                CDU_OS.WaitEvent(FS_DATA_EVENT); //  wait for FS_DATA_EVENT
                //test_update_flags(); // : >>>>> debug ONLY !!!
                CDU_DSP_CSS(); // : get data and show on screen
                CDU_OS.FreeResource(FS_DATA_RESOURCE); // : free FS_DATA_RESOURCE
              }
              else {
                 // FS_DATA_RESOURCE is occupied, don’t read it !
              }
     }
}


void READ_POT_TASK(void) 
{    // Mbos task started by mbos timer to scan potmeter every 100 msec
    CDU_OS.SetTimer( READ_POT_TIMER_ID, READ_POT_TIMER_PERIOD, READ_POT_TIMER_PERIOD );
    while(1) { // : loop forever because it is a mbos taskfunction
        CDU_OS.WaitEvent(READ_POT_TIMER_EVENT );  // : wait for Mbos timer event
        CDU_SET_BGL_INTENSITY(255);
    }
}