TEAMUSB_SLAVE

Dependencies:   USBHost mbed

Fork of USBHostKeyboard_HelloWorld by TEAMUSB

main.cpp

Committer:
armdran
Date:
2015-05-04
Revision:
15:363c54cb2032
Parent:
14:c820ae094728

File content as of revision 15:363c54cb2032:

#include "mbed.h"
#include "USBHostKeyboard.h"
#include "time.h"

extern "C" void mbed_reset();

clock_t spi_begin = 0;
clock_t spi_end = 0;

typedef struct {
    uint8_t key;        
    uint8_t modifier;
} keyPress_t;

DigitalOut led(LED1);
SPISlave device(p5, p6, p7, p8);
DigitalOut ir(p21);
Queue<keyPress_t, 1024> _keyQueue;
MemoryPool<keyPress_t, 1024> mpool;

uint8_t spi_reply_blocking(uint8_t reply = 0x00, bool sendIr = 0) {
    device.reply(reply);
    if(sendIr == 1) { 
        ir = 1; ir = 0;
    }
    while(!device.receive()) { 
        // busy
    }
    uint8_t instruction = device.read();
    return instruction;  
}


void onKeyMod(uint8_t key, uint8_t modifier) {
    keyPress_t *keypress = mpool.alloc();
    keypress->key = key;
    keypress->modifier = modifier;
    _keyQueue.put(keypress);
}

void spi_task(void const *) {
    
    while(1){
        osEvent evt = _keyQueue.get();
        if (evt.status == osEventMessage) {
            
            spi_begin = clock(); 
            
            keyPress_t *keypress = (keyPress_t*)evt.value.p;
            uint8_t key = keypress->key;
            uint8_t modifier = keypress->modifier;
            
            printf("    sending key %x and modifier %x \r\n", key, modifier);
            uint8_t instruction = spi_reply_blocking(key, 1);
    
            while(instruction != 0xFE) {
                printf("    out of sync.\r\n");
                instruction = spi_reply_blocking(key);
            }
         
            uint8_t ack_key = spi_reply_blocking(modifier);
            
            uint8_t ack_keychar = spi_reply_blocking();
            
            if(ack_key != key) 
                printf("    key ack failed (is %x, should be %x)!!!\r\n", ack_key, key);
            else
                printf("    key ack ok\r\n");
             
            mpool.free(keypress);
            
            spi_end = clock();
                            
        }            
    }
}

void keyboard_task(void const *) {
    
    USBHostKeyboard keyboard;
    
    while(1) {
        
        printf("trying to connect\r\n");
        
        // try to connect a USB keyboard
        while(!keyboard.connect()) {
            Thread::wait(500);
        }
        printf("connected\r\n");
        // when connected, attach handler called on keyboard event
        keyboard.attach(onKeyMod);
        printf("eventhandler attached\r\n");
        // wait until the keyboard is disconnected
        while(keyboard.connected()) {
            //USBHost::poll();
            Thread::wait(500);
        }
        printf("disconnected\r\n");
    }
}

void alive_task(void const *) {
    while(1) {
        if(spi_begin > spi_end) {
            float diff = ((float)clock() - (float)spi_begin) / CLOCKS_PER_SEC;
            if(diff > .5) {
                mbed_reset();
            }
        }
        Thread::wait(2000);
    }
}

int main() {
    ir = 0;
    Thread keyboardTask(keyboard_task, NULL, osPriorityNormal, 256 * 4);
    Thread spiTask(spi_task, NULL, osPriorityNormal, 256 * 4);
    Thread aliveTask(alive_task, NULL, osPriorityNormal, 256 * 4);
    device.frequency(1000000);
    device.format(8, 1);
    while(1) {}
    
}