USED IMAGE2GLCD

Dependencies:   BLE_API SharpLCD_LucidaFont mbed nRF51822

Fork of Renard_YO by Andrea Corrado

main.cpp

Committer:
erigow01
Date:
2014-07-02
Revision:
0:9bea6067730f
Child:
1:f0635f12df8c

File content as of revision 0:9bea6067730f:

#include "mbed.h"
#include "DebouncedInterrupt.h"
#include "EaEpaper.h"
#include "Arial28x28.h"
#include "Arial12x12.h"

//I/O Initialisation
DigitalOut myled(LED1);
DigitalOut motor(P0_23);
#define BUTTON_INTERRUPT_DEBOUNCE_TIME_MS 150
DebouncedInterrupt buttonOne (P0_16);
DebouncedInterrupt buttonTwo (P0_17);

//Epaper Init
EaEpaper epaper(P0_0, //PWR_CONTROL
            P0_1,     //BORDER CONTROL
            P0_2,     //DISCHARGE
            P0_3,     //RESET
            P0_4,     //BUSY
            P0_5,     //SSEL
            P0_6,     //PWM
            P0_12,P0_13,P0_15, //MOSI,MISO,SCLK
            P0_22,P0_20);//SDA, SDL

//Notification Data struct
#define NOTIFICATION_TEXT_MAX_LENGTH 20
#define NOTIFICATION_TYPE_CALL     0x01
#define NOTIFICATION_TYPE_SMS      0x02
#define NOTIFICATION_TYPE_EMAIL    0x03
#define NOTIFICATION_TYPE_EVENT    0x04
#define NOTIFICATION_STATE_DELETED 0x00
#define NOTIFICATION_STATE_UNREAD  0x01
#define NOTIFICATION_STATE_READ    0x02
struct Notification{
    uint8_t type;
    uint8_t state;
    char primary_text[NOTIFICATION_TEXT_MAX_LENGTH];
    char secondary_text[NOTIFICATION_TEXT_MAX_LENGTH];
    };

//notification storage
#define MAX_NOTIFICATIONS 20
Notification notifications[MAX_NOTIFICATIONS];
uint8_t notification_count = 0;
int visible_notification_index = -1;

//States
uint8_t needs_display_update = 0;
uint8_t has_unread = 0;

//For LED
#define LED_BLINK_TIME_MS 500
uint8_t led_on = 0;
Timer led_timer;

//For Buzzer
#define BUZZ_TIME_MS 200
#define MAX_BUZZ_COUNT 3
uint8_t buzz_count = MAX_BUZZ_COUNT;
Timer buzz_timer;

void setType(Notification* note, uint8_t type) {
    note->type = type;
}

uint8_t isCall(Notification note) {
    return note.type == NOTIFICATION_TYPE_CALL;
}

uint8_t isSMS(Notification note) {
    return note.type == NOTIFICATION_TYPE_SMS;
}

uint8_t isEmail(Notification note) {
    return note.type == NOTIFICATION_TYPE_EMAIL;
}

uint8_t isEvent(Notification note) {
    return note.type == NOTIFICATION_TYPE_EVENT;
}

void setState(Notification* note, uint8_t state) {
    note->state = state;
}

uint8_t isDeleted(Notification note) {
    return note.state == NOTIFICATION_STATE_DELETED;
}

uint8_t isUnread(Notification note) {
    return note.state == NOTIFICATION_STATE_UNREAD;
}

uint8_t isRead(Notification note) {
    return note.state == NOTIFICATION_STATE_READ;
}

//Update Display to show current notification...
void doDisplayUpdate() {
    epaper.cls();
    if(visible_notification_index >= 0) {
        //Write current notification...
        epaper.set_font((unsigned char*)Arial12x12);
        epaper.locate(5,5);
        epaper.printf(notifications[visible_notification_index].primary_text);
        epaper.locate(5,15);
        epaper.printf(notifications[visible_notification_index].secondary_text);
    } else {
        //no notifications...
        //Write current notification...
        epaper.set_font((unsigned char*)Arial12x12);
        epaper.locate(5,5);
        epaper.printf("No Notifications");
    }
    epaper.write_disp();
    needs_display_update = 0;
}

//Request a display update..
void requestDisplayUpdate() {
    needs_display_update = 1;
}

//Starts buzz pattern...
void startBuzz() {
    //Buzz
    buzz_count = 0;
    buzz_timer.reset();
    buzz_timer.start();
}


//Add Notification...
int addNotification(Notification note) {
    //Find insertion point...
    uint8_t index = 0;
    for(index = 0; index < MAX_NOTIFICATIONS; index++) {
        if(isDeleted(notifications[index])) {
            //Here...
            break;
        }
    }
    //If here, didn't find insertion point... wrap to beginning.
    if(index >= MAX_NOTIFICATIONS) index = 0;
    notifications[index] = note;
    //Set buzzer
    startBuzz();
    //Set unread
    if(isUnread(note)) has_unread = 1;
    return index;
}

void deleteNotification(int index) {
    setState(&notifications[index], NOTIFICATION_STATE_DELETED);
    //Shift array elements left...
    int i = 0;
    for (i = index + 1; i < MAX_NOTIFICATIONS; i++) {
        notifications[i - 1] = notifications[i];
    }
}

void checkUnread(){
    uint8_t i = 0;
    led_timer.stop();
    has_unread = 0;
    for(i = 0; i < MAX_NOTIFICATIONS; i++) {
        if(isUnread(notifications[i])) {
            has_unread = 1;
            led_timer.reset();
            led_timer.start();
            break;
        }
    }
}

//Button One Handler
void buttonOnePressed(){
    if(visible_notification_index >= 0) {
        //Increment index, wrap to beginning if last.
        visible_notification_index++;
        if(visible_notification_index >= MAX_NOTIFICATIONS || isDeleted(notifications[visible_notification_index])) {
            visible_notification_index = 0;
            if(isDeleted(notifications[visible_notification_index])) {
                //Still deleted... none...
                visible_notification_index = -1;
            }
        }
        //Trigger display update...
        requestDisplayUpdate();
    }
}

//Button Two handler
void buttonTwoPressed(){
    if(visible_notification_index >= 0) {
        if(!isDeleted(notifications[visible_notification_index])) {
            //Exists.
            if(isUnread(notifications[visible_notification_index])) {
                //Toggle to 'read'
                setState(&notifications[visible_notification_index], NOTIFICATION_STATE_READ);
                checkUnread();
            } else if (isRead(notifications[visible_notification_index])) {
                //Already 'read'... delete, this also shifts remaining notifications down...
                deleteNotification(visible_notification_index);
                //If current is deleted...
                if(isDeleted(notifications[visible_notification_index])) {
                    //We're at end, so wrap...
                    visible_notification_index = 0;
                    if(isDeleted(notifications[visible_notification_index])) {
                        //Still deleted... so there are none...
                        visible_notification_index = -1;
                    }
                }
                //Otherwise, we've got one, so we should be ok...
            }
            
            //Trigger display update...
            requestDisplayUpdate();
        }
    }
}

//Initialise notification data...
void initNotificationData() {
    //For debug purposes...
    notifications[0].type = NOTIFICATION_TYPE_CALL;
    notifications[0].state = NOTIFICATION_STATE_UNREAD;
    strcpy(notifications[0].primary_text,"Eric Gowland");
    strcpy(notifications[0].secondary_text, "07770909177");
    
    notifications[1].type = NOTIFICATION_TYPE_EMAIL;
    notifications[1].state = NOTIFICATION_STATE_UNREAD;
    strcpy(notifications[1].primary_text, "Dear Sir I have $US");
    strcpy(notifications[1].secondary_text, "not@scam.net");
    
    //Set location, etc.
    visible_notification_index = 0;
    checkUnread();
    requestDisplayUpdate();
    startBuzz();
}

//Main Program Function
int main() {
    //Init Data
    initNotificationData();
    //Attach interrupt handlers...
    buttonOne.attach(buttonOnePressed, IRQ_RISE, BUTTON_INTERRUPT_DEBOUNCE_TIME_MS);
    buttonTwo.attach(buttonTwoPressed, IRQ_RISE, BUTTON_INTERRUPT_DEBOUNCE_TIME_MS);
    //Request display update...
    requestDisplayUpdate();
    while(1) {
        if(needs_display_update){
            doDisplayUpdate();
        } else {
            //If state hasn't changed, just action timers...
            //Unread LED
            if(has_unread) {
                //LED flashing...
                if(led_timer.read_ms() > LED_BLINK_TIME_MS) {
                    myled = !myled;
                    led_timer.reset();
                }
            } else {
                myled = 0;
                led_timer.stop();
            }
            
            //Buzz
            if(buzz_count < MAX_BUZZ_COUNT) {
                //Buzzing...
                if(buzz_timer.read_ms() > BUZZ_TIME_MS) {
                    motor = !motor;
                    if(!motor) buzz_count++;
                    buzz_timer.reset();
                }
            } else {
                motor = 0;
                buzz_timer.stop();
            }
        }
    }
}