
USB IO module
Revision 0:08e9f3bccfda, committed 2016-01-05
- Comitter:
- BPPearson
- Date:
- Tue Jan 05 16:45:45 2016 +0000
- Commit message:
- USB IO module
Changed in this revision
diff -r 000000000000 -r 08e9f3bccfda ByteOperations.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ByteOperations.cpp Tue Jan 05 16:45:45 2016 +0000 @@ -0,0 +1,37 @@ +#include "ByteOperations.h" +#include <stdint.h> + + +/* low index equals low nibble */ +/* Write 32 bit var to 4 bytes */ +void write_32_to_8(int *i, uint8_t dst[], uint32_t src){ + dst[(*i)++] = (src >> 0)&0xFF ; + dst[(*i)++] = (src >> 8)&0xFF ; + dst[(*i)++] = (src >> 16)&0xFF; + dst[(*i)++] = (src >> 24)&0xFF; +} + +/* Write 16 bit var to 2 bytes */ +void write_16_to_8(int *i, uint8_t dst[], uint16_t src){ + dst[(*i)++] = (src >> 0)&0xFF ; + dst[(*i)++] = (src >> 8)&0xFF ; +} + +/* Write 4 bytes to 32 bit var*/ +uint32_t read_8_to_32(int *i, uint8_t *src){ + uint32_t data = 0; + data |= (src[(*i)++] << 0) ; + data |= (src[(*i)++] << 8) ; + data |= (src[(*i)++] << 16); + data |= (src[(*i)++] << 24); + return data; +} + +/* Write 2 bytes to 16 bit var*/ +uint16_t read_8_to_16(int *i, uint8_t *src){ + uint16_t data = 0; + data |= (src[(*i)++] << 0) ; + data |= (src[(*i)++] << 8) ; + return data; +} +
diff -r 000000000000 -r 08e9f3bccfda ByteOperations.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ByteOperations.h Tue Jan 05 16:45:45 2016 +0000 @@ -0,0 +1,278 @@ +#ifndef BYTEOPERATION_H_ +#define BYTEOPERATION_H_ + +#include <stdint.h> + +/* low index equals low nibble */ +/* Write 32 bit var to 4 bytes */ +void write_32_to_8(int *i, uint8_t dst[], uint32_t src); + +/* Write 16 bit var to 2 bytes */ +void write_16_to_8(int *i, uint8_t dst[], uint16_t src); + +/* Write 4 bytes to 32 bit var*/ +uint32_t read_8_to_32(int *i, uint8_t *src); + +/* Write 2 bytes to 16 bit var*/ +uint16_t read_8_to_16(int *i, uint8_t *src); + + +const uint8_t logaritmify[0xFF] = { +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +1 , +2 , +2 , +2 , +2 , +2 , +2 , +2 , +2 , +2 , +2 , +2 , +2 , +2 , +3 , +3 , +3 , +3 , +3 , +3 , +3 , +3 , +3 , +3 , +3 , +4 , +4 , +4 , +4 , +4 , +4 , +4 , +4 , +5 , +5 , +5 , +5 , +5 , +5 , +5 , +6 , +6 , +6 , +6 , +6 , +6 , +7 , +7 , +7 , +7 , +7 , +7 , +8 , +8 , +8 , +8 , +9 , +9 , +9 , +9 , +9 , +10 , +10 , +10 , +10 , +11 , +11 , +11 , +11 , +12 , +12 , +12 , +13 , +13 , +13 , +14 , +14 , +14 , +15 , +15 , +15 , +16 , +16 , +16 , +17 , +17 , +18 , +18 , +19 , +19 , +19 , +20 , +20 , +21 , +21 , +22 , +22 , +23 , +23 , +24 , +25 , +25 , +26 , +26 , +27 , +28 , +28 , +29 , +29 , +30 , +31 , +32 , +32 , +33 , +34 , +35 , +35 , +36 , +37 , +38 , +39 , +40 , +40 , +41 , +42 , +43 , +44 , +45 , +46 , +47 , +48 , +50 , +51 , +52 , +53 , +54 , +55 , +57 , +58 , +59 , +61 , +62 , +63 , +65 , +66 , +68 , +69 , +71 , +72 , +74 , +76 , +77 , +79 , +81 , +83 , +85 , +86 , +88 , +90 , +92 , +94 , +97 , +99 , +101, +103, +105, +108, +110, +113, +115, +118, +120, +123, +126, +129, +131, +134, +137, +140, +143, +147, +150, +153, +157, +160, +164, +167, +171, +175, +179, +183, +187, +191, +195, +199, +204, +208, +213, +218, +222, +227, +232, +237, +243, +248}; + +#endif +
diff -r 000000000000 -r 08e9f3bccfda USBDevice.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBDevice.lib Tue Jan 05 16:45:45 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/mbed_official/code/USBDevice/#1dbc943a21cf
diff -r 000000000000 -r 08e9f3bccfda USBHIDProtocol.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBHIDProtocol.h Tue Jan 05 16:45:45 2016 +0000 @@ -0,0 +1,31 @@ +#ifndef USBHIDPROTOCOL_H_ +#define USBHIDPROTOCOL_H_ +/* Command list */ +// Devices verifies with same CMD and optional data + +// System commands + #define CMD_SYS_CHECK 0x00 // Args: return version + #define CMD_SYS_RESET 0xFF // Args: bool softreset + +// Miscellaneous + #define CMD_LED_OFF 0x10 // Args, int led 1..4 + #define CMD_LED_ON 0x11 // Args, int led 1..4 + +// Digital input commands + #define CMD_READ_DIG_INPUT 0x20 // Args, int channel, return int + #define CMD_READ_ALL_DIG_INPUTS 0x21 // No args, return int + +// Digital output commands + #define CMD_READ_DIG_OUTPUT 0x22 // Args, int channel, return int + #define CMD_READ_ALL_DIG_OUTPUTS 0x23 // No args, return int + #define CMD_WRITE_DIG_OUTPUT 0x24 // Args, int channel + #define CMD_WRITE_ALL_DIG_OUTPUTS 0x25 // Args, int output value + +// Analog input command + #define CMD_READ_ANALOG_INPUT 0x30 // Args, int channel, return int + +// Analog output command + #define CMD_WRITE_ANALOG_OUTPUT 0x31 // Args, int value + +#endif //USBHIDPROTOCOL_H_ +
diff -r 000000000000 -r 08e9f3bccfda main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Jan 05 16:45:45 2016 +0000 @@ -0,0 +1,333 @@ +#include "mbed.h" +#include "watchdog.h" +#include "USBHID.h" +#include "ByteOperations.h" +#include "USBHIDProtocol.h" + +#define VERSION 0x01 + + +// define all I/O +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +DigitalIn digIn1(p6); +DigitalIn digIn2(p7); +DigitalIn digIn3(p8); +DigitalIn digIn4(p9); +DigitalIn digIn5(p10); +DigitalIn digIn6(p11); +DigitalIn digIn7(p12); +DigitalIn digIn8(p13); +//DigitalIn digIn9(p13); +//DigitalIn digIn10(p14); +DigitalOut digOut1(p21); +DigitalOut digOut2(p22); +DigitalOut digOut3(p23); +DigitalOut digOut4(p24); +DigitalOut digOut5(p25); +DigitalOut digOut6(p26); +DigitalOut digOut7(p27); +DigitalOut digOut8(p28); +AnalogIn anIn1(p16); +AnalogIn anIn2(p17); +AnalogIn anIn3(p19); +AnalogIn anIn4(p20); +AnalogOut anOut(p18); + +//Serial pc(USBTX, USBRX); + +USBHID *hid; +HID_REPORT send_report __attribute__((aligned (4))); // Aligned for fast access +HID_REPORT recv_report __attribute__((aligned (4))); // Aligned for fast access + + +/** + * @brief Clear buffer contents + * @note Requires 4 byte alignement of data + * @param[in] c Pointer to @p HID_REPORT. + */ +void empty_report(HID_REPORT *data){ + register uint32_t *p = (uint32_t *)data->data; + for( register int i=0; i<((sizeof(HID_REPORT)-1)/4); i++ ){ + *p = 0xFFFFFFFF; + p++; + } +} + + +int main(void) +{ + uint16_t channel; + uint16_t value; + + // USB Initialize + static USBHID hid_object(64, 64); + hid = &hid_object; + send_report.length = 64; + + //pc.printf("Start of main\n"); + + // Ready + while(1){ + // insert idle time, since we cant be running USB stuff all the time + wait_us(5000); + + //try to read a msg + if(hid->readNB(&recv_report)){ + // Data packet received, start parsing + int irx=0; + int itx=0; + + send_report.data[itx++] = recv_report.data[0]; + + switch ( recv_report.data[irx++] ){ + case CMD_SYS_CHECK : + send_report.data[itx++] = VERSION; + break; + + case CMD_SYS_RESET : + // Soft reset + empty_report(&recv_report); + break; + + case CMD_LED_OFF : + // CMD_LED_OFF Args, byte led 1..4 + channel = recv_report.data[irx++]; + switch (channel){ + case 1: + led1 = 1; // inverted led + break; + case 2: + led2 = 1; // inverted led + break; + case 3: + led3 = 0; // inverted led + break; + case 4: + led4 = 0; // inverted led + break; + default: + send_report.data[0] = 0xFF; //Failure + } + break; + + case CMD_LED_ON : + // CMD_LED_ON Args, byte led 1..4 + channel = recv_report.data[irx++]; + switch (channel){ + case 1: + led1 = 0; // inverted led + break; + case 2: + led2 = 0; // inverted led + break; + case 3: + led3 = 1; // inverted led + break; + case 4: + led4 = 1; // inverted led + break; + default: + send_report.data[0] = 0xFF; //Failure + } + break; + + case CMD_READ_DIG_INPUT : + // CMD_READ_DIG_INPUT Args, byte channel, return int + channel = recv_report.data[irx++]; + value = 0; + switch (channel){ + case 1: + value = digIn1.read(); + break; + case 2: + value = digIn2.read(); + break; + case 3: + value = digIn3.read(); + break; + case 4: + value = digIn4.read(); + break; + case 5: + value = digIn5.read(); + break; + case 6: + value = digIn6.read(); + break; + case 7: + value = digIn7.read(); + break; + case 8: + value = digIn8.read(); + break; + default: + send_report.data[0] = 0xFF; //Failure + } + write_16_to_8(&itx, send_report.data, value); + break; + + case CMD_READ_ALL_DIG_INPUTS : + // CMD_READ_ALL_DIG_INPUTS No args, return int + value = 0; + value = digIn1.read(); + value |= ((digIn2.read() & 1) << 1); + value |= ((digIn3.read() & 1) << 2); + value |= ((digIn4.read() & 1) << 3); + value |= ((digIn5.read() & 1) << 4); + value |= ((digIn6.read() & 1) << 5); + value |= ((digIn7.read() & 1) << 6); + value |= ((digIn8.read() & 1) << 7); + write_16_to_8(&itx, send_report.data, value); + break; + + case CMD_READ_DIG_OUTPUT : + // CMD_READ_DIG_OUTPUT Args, byte channel, return int + channel = recv_report.data[irx++]; + value = 0; + switch (channel){ + case 1: + value = digOut1.read(); + break; + case 2: + value = digOut2.read(); + break; + case 3: + value = digOut3.read(); + break; + case 4: + value = digOut4.read(); + break; + case 5: + value = digOut5.read(); + break; + case 6: + value = digOut6.read(); + break; + case 7: + value = digOut7.read(); + break; + case 8: + value = digOut8.read(); + break; + default: + send_report.data[0] = 0xFF; //Failure + } + write_16_to_8(&itx, send_report.data, value); + break; + + case CMD_READ_ALL_DIG_OUTPUTS : + // CMD_READ_ALL_DIG_OUTPUTS No args, return int + value = 0; + value = digOut1.read(); + value |= ((digOut2.read() & 1) << 1); + value |= ((digOut3.read() & 1) << 2); + value |= ((digOut4.read() & 1) << 3); + value |= ((digOut5.read() & 1) << 4); + value |= ((digOut6.read() & 1) << 5); + value |= ((digOut7.read() & 1) << 6); + value |= ((digOut8.read() & 1) << 7); + write_16_to_8(&itx, send_report.data, value); + break; + + case CMD_WRITE_DIG_OUTPUT : + // CMD_WRITE_DIG_OUTPUT Args, byte channel, int value + channel = recv_report.data[irx++]; + value = recv_report.data[irx++]; + switch (channel){ + case 1: + digOut1.write(!(value & 1)); + break; + case 2: + digOut2.write(!(value & 1)); + break; + case 3: + digOut3.write(value & 1); + break; + case 4: + digOut4.write(value & 1); + break; + case 5: + digOut5.write(value & 1); + break; + case 6: + digOut6.write(value & 1); + break; + case 7: + digOut7.write(value & 1); + break; + case 8: + digOut8.write(value & 1); + break; + default: + send_report.data[0] = 0xFF; //Failure + } + break; + + case CMD_WRITE_ALL_DIG_OUTPUTS : + // CMD_WRIE_ALL_DIG_OUTPUTS Args, byte output value + uint16_t value = recv_report.data[irx++]; + digOut1.write(value & 1); + digOut2.write((value >> 1) & 1); + digOut3.write((value >> 2) & 1); + digOut4.write((value >> 3) & 1); + digOut5.write((value >> 4) & 1); + digOut6.write((value >> 5) & 1); + digOut7.write((value >> 6) & 1); + digOut8.write((value >> 7) & 1); + break; + + case CMD_READ_ANALOG_INPUT : + // CMD_READ_ANALOG_INPUT Args, byte channel, return int + channel = recv_report.data[irx++]; + //pc.printf("Channel %d\n", channel); + switch (channel){ + case 1: + uint16_t value = anIn1.read_u16(); + write_16_to_8(&itx, send_report.data, value); + //pc.printf("Value %d\n", value ); + break; + case 2: + value = anIn2.read_u16(); + write_16_to_8(&itx, send_report.data, value); + break; + case 3: + value = anIn3.read_u16(); + write_16_to_8(&itx, send_report.data, value); + break; + case 4: + value = anIn4.read_u16(); + write_16_to_8(&itx, send_report.data, value); + break; + default: + send_report.data[0] = 0xFF; //Failure + } + break; + + case CMD_WRITE_ANALOG_OUTPUT : + // CMD_WRITE_ANALOG_OUTPUT Args, int value + value = read_8_to_16(&irx, recv_report.data); + anOut.write_u16(value); + break; + + case 0xEE : { + hid->sendNB(&send_report); + WatchDog_us bello(100); + } + break; + + default: + send_report.data[0] = 0xFF; //Failure + break; + } // Switch + // Return command + optional new args + hid->send(&send_report); + // 0xFF unused bytes + empty_report(&recv_report); + empty_report(&send_report); + } // if packet + } // While +} +
diff -r 000000000000 -r 08e9f3bccfda mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Jan 05 16:45:45 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/4fc01daae5a5 \ No newline at end of file
diff -r 000000000000 -r 08e9f3bccfda watchdog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/watchdog.cpp Tue Jan 05 16:45:45 2016 +0000 @@ -0,0 +1,98 @@ +/* +* Source code is free to use and distribute. +* Software originally written by Simon Ford, +* altered by Lerche. +* +* 02-07-2012 - Added LPC11U24 Watchdog functions. Lerche +* 23-10-2012 - Trying to publish the library which seems VERY difficult +*/ + +#include "mbed.h" +#include "watchdog.h" + + +WatchDog::WatchDog(float s) { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) + LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK + uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4 + LPC_WDT->WDTC = s * (float)clk; // Load WD Timer Constant with value determined by float s + LPC_WDT->WDMOD = 0x3; // Enabled and Reset + feed(); +#elif defined(TARGET_LPC11U24) + LPC_SYSCON->SYSAHBCLKCTRL |= 0x8000; + LPC_SYSCON->PDRUNCFG &= 0xFFBF; + LPC_SYSCON->WDTOSCCTRL = 0x40; + uint32_t clk = 100000; + LPC_WWDT->TC = s * (float)clk; + LPC_WWDT->CLKSEL = 0x1; + LPC_WWDT->MOD = 0x3; + feed(); +#endif +} + +WatchDog_ms::WatchDog_ms(int ms) { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) + LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK + uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4 + LPC_WDT->WDTC = ((float)ms * (float)clk) /1000; // Load WD Timer Constant with value determined by int ms + LPC_WDT->WDMOD = 0x3; // Enabled and Reset + feed(); +#elif defined(TARGET_LPC11U24) + LPC_SYSCON->SYSAHBCLKCTRL |= 0x8000; + LPC_SYSCON->PDRUNCFG &= 0xFFBF; + LPC_SYSCON->WDTOSCCTRL = 0x40; + uint32_t clk = 100000; + LPC_WWDT->TC = ((float)ms * (float)clk) / 1000; + LPC_WWDT->CLKSEL = 0x1; + LPC_WWDT->MOD = 0x3; + feed(); +#endif +} + +WatchDog_us::WatchDog_us(int us) { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) + LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK + uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4 + LPC_WDT->WDTC = ((float)us * (float)clk) /1000000; // Load WD Timer Constant with value determined by int us + LPC_WDT->WDMOD = 0x3; // Enabled and Reset + feed(); +#elif defined(TARGET_LPC11U24) + LPC_SYSCON->SYSAHBCLKCTRL |= 0x8000; + LPC_SYSCON->PDRUNCFG &= 0xFFBF; + LPC_SYSCON->WDTOSCCTRL = 0x40; + uint32_t clk = 100000; + LPC_WWDT->TC = ((float)us * (float)clk) / 1000000; + LPC_WWDT->CLKSEL = 0x1; + LPC_WWDT->MOD = 0x3; + feed(); +#endif +} + +void WatchDog::feed() { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) + LPC_WDT->WDFEED = 0xAA; // Routine to feed the WatchDog + LPC_WDT->WDFEED = 0x55; // according to user manual +#elif defined(TARGET_LPC11U24) + LPC_WWDT->FEED = 0xAA; + LPC_WWDT->FEED = 0x55; +#endif +} +void WatchDog_ms::feed() { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) + LPC_WDT->WDFEED = 0xAA; // Routine to feed the WatchDog + LPC_WDT->WDFEED = 0x55; // according to user manual +#elif defined(TARGET_LPC11U24) + LPC_WWDT->FEED = 0xAA; + LPC_WWDT->FEED = 0x55; +#endif +} +void WatchDog_us::feed() { +#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) + LPC_WDT->WDFEED = 0xAA; // Routine to feed the WatchDog + LPC_WDT->WDFEED = 0x55; // according to user manual +#elif defined(TARGET_LPC11U24) + LPC_WWDT->FEED = 0xAA; + LPC_WWDT->FEED = 0x55; +#endif +} +
diff -r 000000000000 -r 08e9f3bccfda watchdog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/watchdog.h Tue Jan 05 16:45:45 2016 +0000 @@ -0,0 +1,58 @@ +/* +* Using code Simon Ford written in his example +* to implement WDT. +* It can run in seconds, milliseconds, and microseconds. +* All there is to do, is keep feeding the watchdog. +*/ + +#ifndef WATCHDOG_H +#define WATCHDOG_H + +#include "mbed.h" + +/** Watchdog timer implementation (in seconds) */ +class WatchDog { +public: + /** Creates Watchdog timer + * + * @param Sets the WDT in seconds + */ + WatchDog(float s); + + /** Keep feeding the watchdog in routine + * + * xxx.feed(); does the trick + */ + void feed(); +}; +/** Watchdog timer implementation (in milliseconds) */ +class WatchDog_ms { +public: + /** Creates Watchdog timer + * + * @param Sets the WDT in milliseconds + */ + WatchDog_ms(int ms); + /** Keep feeding the watchdog in routine + * + * xxx.feed(); does the trick + */ + void feed(); +}; +/** Watchdog timer implementation (in microseconds) */ +class WatchDog_us { +public: + /** Creates Watchdog timer + * + * @param Sets the WDT in microseconds + */ + WatchDog_us(int us); + /** Keep feeding the watchdog in routine + * + * xxx.feed(); does the trick + */ + void feed(); +}; + +#endif +