diff options
Diffstat (limited to 'tmk_core/protocol/lufa')
-rw-r--r-- | tmk_core/protocol/lufa/adafruit_ble.cpp | 1117 | ||||
-rw-r--r-- | tmk_core/protocol/lufa/adafruit_ble.h | 30 | ||||
-rw-r--r-- | tmk_core/protocol/lufa/bluetooth.c | 20 | ||||
-rw-r--r-- | tmk_core/protocol/lufa/bluetooth.h | 37 | ||||
-rw-r--r-- | tmk_core/protocol/lufa/lufa.c | 692 | ||||
-rw-r--r-- | tmk_core/protocol/lufa/lufa.h | 20 | ||||
-rw-r--r-- | tmk_core/protocol/lufa/outputselect.c | 9 | ||||
-rw-r--r-- | tmk_core/protocol/lufa/outputselect.h | 14 |
8 files changed, 892 insertions, 1047 deletions
diff --git a/tmk_core/protocol/lufa/adafruit_ble.cpp b/tmk_core/protocol/lufa/adafruit_ble.cpp index 80839731fd..71d0936f8f 100644 --- a/tmk_core/protocol/lufa/adafruit_ble.cpp +++ b/tmk_core/protocol/lufa/adafruit_ble.cpp @@ -15,35 +15,34 @@ // You may define them to something else in your config.h // if yours is wired up differently. #ifndef AdafruitBleResetPin -#define AdafruitBleResetPin D4 +# define AdafruitBleResetPin D4 #endif #ifndef AdafruitBleCSPin -#define AdafruitBleCSPin B4 +# define AdafruitBleCSPin B4 #endif #ifndef AdafruitBleIRQPin -#define AdafruitBleIRQPin E6 +# define AdafruitBleIRQPin E6 #endif - #define SAMPLE_BATTERY #define ConnectionUpdateInterval 1000 /* milliseconds */ static struct { - bool is_connected; - bool initialized; - bool configured; + bool is_connected; + bool initialized; + bool configured; #define ProbedEvents 1 #define UsingEvents 2 - bool event_flags; + bool event_flags; #ifdef SAMPLE_BATTERY - uint16_t last_battery_update; - uint32_t vbat; + uint16_t last_battery_update; + uint32_t vbat; #endif - uint16_t last_connection_update; + uint16_t last_connection_update; } state; // Commands are encoded using SDEP and sent via SPI @@ -51,14 +50,14 @@ static struct { #define SdepMaxPayload 16 struct sdep_msg { - uint8_t type; - uint8_t cmd_low; - uint8_t cmd_high; - struct __attribute__((packed)) { - uint8_t len:7; - uint8_t more:1; - }; - uint8_t payload[SdepMaxPayload]; + uint8_t type; + uint8_t cmd_low; + uint8_t cmd_high; + struct __attribute__((packed)) { + uint8_t len : 7; + uint8_t more : 1; + }; + uint8_t payload[SdepMaxPayload]; } __attribute__((packed)); // The recv latency is relatively high, so when we're hammering keys quickly, @@ -68,28 +67,28 @@ struct sdep_msg { // information here. enum queue_type { - QTKeyReport, // 1-byte modifier + 6-byte key report - QTConsumer, // 16-bit key code + QTKeyReport, // 1-byte modifier + 6-byte key report + QTConsumer, // 16-bit key code #ifdef MOUSE_ENABLE - QTMouseMove, // 4-byte mouse report + QTMouseMove, // 4-byte mouse report #endif }; struct queue_item { - enum queue_type queue_type; - uint16_t added; - union __attribute__((packed)) { - struct __attribute__((packed)) { - uint8_t modifier; - uint8_t keys[6]; - } key; - - uint16_t consumer; - struct __attribute__((packed)) { - int8_t x, y, scroll, pan; - uint8_t buttons; - } mousemove; - }; + enum queue_type queue_type; + uint16_t added; + union __attribute__((packed)) { + struct __attribute__((packed)) { + uint8_t modifier; + uint8_t keys[6]; + } key; + + uint16_t consumer; + struct __attribute__((packed)) { + int8_t x, y, scroll, pan; + uint8_t buttons; + } mousemove; + }; }; // Items that we wish to send @@ -102,108 +101,104 @@ static RingBuffer<uint16_t, 2> resp_buf; static bool process_queue_item(struct queue_item *item, uint16_t timeout); enum sdep_type { - SdepCommand = 0x10, - SdepResponse = 0x20, - SdepAlert = 0x40, - SdepError = 0x80, - SdepSlaveNotReady = 0xfe, // Try again later - SdepSlaveOverflow = 0xff, // You read more data than is available + SdepCommand = 0x10, + SdepResponse = 0x20, + SdepAlert = 0x40, + SdepError = 0x80, + SdepSlaveNotReady = 0xfe, // Try again later + SdepSlaveOverflow = 0xff, // You read more data than is available }; enum ble_cmd { - BleInitialize = 0xbeef, - BleAtWrapper = 0x0a00, - BleUartTx = 0x0a01, - BleUartRx = 0x0a02, + BleInitialize = 0xbeef, + BleAtWrapper = 0x0a00, + BleUartTx = 0x0a01, + BleUartRx = 0x0a02, }; enum ble_system_event_bits { - BleSystemConnected = 0, - BleSystemDisconnected = 1, - BleSystemUartRx = 8, - BleSystemMidiRx = 10, + BleSystemConnected = 0, + BleSystemDisconnected = 1, + BleSystemUartRx = 8, + BleSystemMidiRx = 10, }; // The SDEP.md file says 2MHz but the web page and the sample driver // both use 4MHz #define SpiBusSpeed 4000000 -#define SdepTimeout 150 /* milliseconds */ -#define SdepShortTimeout 10 /* milliseconds */ -#define SdepBackOff 25 /* microseconds */ +#define SdepTimeout 150 /* milliseconds */ +#define SdepShortTimeout 10 /* milliseconds */ +#define SdepBackOff 25 /* microseconds */ #define BatteryUpdateInterval 10000 /* milliseconds */ -static bool at_command(const char *cmd, char *resp, uint16_t resplen, - bool verbose, uint16_t timeout = SdepTimeout); -static bool at_command_P(const char *cmd, char *resp, uint16_t resplen, - bool verbose = false); +static bool at_command(const char *cmd, char *resp, uint16_t resplen, bool verbose, uint16_t timeout = SdepTimeout); +static bool at_command_P(const char *cmd, char *resp, uint16_t resplen, bool verbose = false); struct SPI_Settings { - uint8_t spcr, spsr; + uint8_t spcr, spsr; }; static struct SPI_Settings spi; // Initialize 4Mhz MSBFIRST MODE0 void SPI_init(struct SPI_Settings *spi) { - spi->spcr = _BV(SPE) | _BV(MSTR); - spi->spsr = _BV(SPI2X); + spi->spcr = _BV(SPE) | _BV(MSTR); + spi->spsr = _BV(SPI2X); - static_assert(SpiBusSpeed == F_CPU / 2, "hard coded at 4Mhz"); + static_assert(SpiBusSpeed == F_CPU / 2, "hard coded at 4Mhz"); - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - // Ensure that SS is OUTPUT High - digitalWrite(B0, PinLevelHigh); - pinMode(B0, PinDirectionOutput); + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + // Ensure that SS is OUTPUT High + digitalWrite(B0, PinLevelHigh); + pinMode(B0, PinDirectionOutput); - SPCR |= _BV(MSTR); - SPCR |= _BV(SPE); - pinMode(B1 /* SCK */, PinDirectionOutput); - pinMode(B2 /* MOSI */, PinDirectionOutput); - } + SPCR |= _BV(MSTR); + SPCR |= _BV(SPE); + pinMode(B1 /* SCK */, PinDirectionOutput); + pinMode(B2 /* MOSI */, PinDirectionOutput); + } } -static inline void SPI_begin(struct SPI_Settings*spi) { - SPCR = spi->spcr; - SPSR = spi->spsr; +static inline void SPI_begin(struct SPI_Settings *spi) { + SPCR = spi->spcr; + SPSR = spi->spsr; } static inline uint8_t SPI_TransferByte(uint8_t data) { - SPDR = data; - asm volatile("nop"); - while (!(SPSR & _BV(SPIF))) { - ; // wait - } - return SPDR; + SPDR = data; + asm volatile("nop"); + while (!(SPSR & _BV(SPIF))) { + ; // wait + } + return SPDR; } static inline void spi_send_bytes(const uint8_t *buf, uint8_t len) { - if (len == 0) return; - const uint8_t *end = buf + len; - while (buf < end) { - SPDR = *buf; - while (!(SPSR & _BV(SPIF))) { - ; // wait + if (len == 0) return; + const uint8_t *end = buf + len; + while (buf < end) { + SPDR = *buf; + while (!(SPSR & _BV(SPIF))) { + ; // wait + } + ++buf; } - ++buf; - } } -static inline uint16_t spi_read_byte(void) { - return SPI_TransferByte(0x00 /* dummy */); -} +static inline uint16_t spi_read_byte(void) { return SPI_TransferByte(0x00 /* dummy */); } static inline void spi_recv_bytes(uint8_t *buf, uint8_t len) { - const uint8_t *end = buf + len; - if (len == 0) return; - while (buf < end) { - SPDR = 0; // write a dummy to initiate read - while (!(SPSR & _BV(SPIF))) { - ; // wait + const uint8_t *end = buf + len; + if (len == 0) return; + while (buf < end) { + SPDR = 0; // write a dummy to initiate read + while (!(SPSR & _BV(SPIF))) { + ; // wait + } + *buf = SPDR; + ++buf; } - *buf = SPDR; - ++buf; - } } #if 0 @@ -223,600 +218,572 @@ static void dump_pkt(const struct sdep_msg *msg) { // Send a single SDEP packet static bool sdep_send_pkt(const struct sdep_msg *msg, uint16_t timeout) { - SPI_begin(&spi); + SPI_begin(&spi); + + digitalWrite(AdafruitBleCSPin, PinLevelLow); + uint16_t timerStart = timer_read(); + bool success = false; + bool ready = false; + + do { + ready = SPI_TransferByte(msg->type) != SdepSlaveNotReady; + if (ready) { + break; + } - digitalWrite(AdafruitBleCSPin, PinLevelLow); - uint16_t timerStart = timer_read(); - bool success = false; - bool ready = false; + // Release it and let it initialize + digitalWrite(AdafruitBleCSPin, PinLevelHigh); + _delay_us(SdepBackOff); + digitalWrite(AdafruitBleCSPin, PinLevelLow); + } while (timer_elapsed(timerStart) < timeout); - do { - ready = SPI_TransferByte(msg->type) != SdepSlaveNotReady; if (ready) { - break; + // Slave is ready; send the rest of the packet + spi_send_bytes(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload)) + msg->len); + success = true; } - // Release it and let it initialize digitalWrite(AdafruitBleCSPin, PinLevelHigh); - _delay_us(SdepBackOff); - digitalWrite(AdafruitBleCSPin, PinLevelLow); - } while (timer_elapsed(timerStart) < timeout); - - if (ready) { - // Slave is ready; send the rest of the packet - spi_send_bytes(&msg->cmd_low, - sizeof(*msg) - (1 + sizeof(msg->payload)) + msg->len); - success = true; - } - digitalWrite(AdafruitBleCSPin, PinLevelHigh); - - return success; + return success; } -static inline void sdep_build_pkt(struct sdep_msg *msg, uint16_t command, - const uint8_t *payload, uint8_t len, - bool moredata) { - msg->type = SdepCommand; - msg->cmd_low = command & 0xff; - msg->cmd_high = command >> 8; - msg->len = len; - msg->more = (moredata && len == SdepMaxPayload) ? 1 : 0; +static inline void sdep_build_pkt(struct sdep_msg *msg, uint16_t command, const uint8_t *payload, uint8_t len, bool moredata) { + msg->type = SdepCommand; + msg->cmd_low = command & 0xff; + msg->cmd_high = command >> 8; + msg->len = len; + msg->more = (moredata && len == SdepMaxPayload) ? 1 : 0; - static_assert(sizeof(*msg) == 20, "msg is correctly packed"); + static_assert(sizeof(*msg) == 20, "msg is correctly packed"); - memcpy(msg->payload, payload, len); + memcpy(msg->payload, payload, len); } // Read a single SDEP packet static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) { - bool success = false; - uint16_t timerStart = timer_read(); - bool ready = false; + bool success = false; + uint16_t timerStart = timer_read(); + bool ready = false; + + do { + ready = digitalRead(AdafruitBleIRQPin); + if (ready) { + break; + } + _delay_us(1); + } while (timer_elapsed(timerStart) < timeout); - do { - ready = digitalRead(AdafruitBleIRQPin); if (ready) { - break; - } - _delay_us(1); - } while (timer_elapsed(timerStart) < timeout); + SPI_begin(&spi); - if (ready) { - SPI_begin(&spi); + digitalWrite(AdafruitBleCSPin, PinLevelLow); - digitalWrite(AdafruitBleCSPin, PinLevelLow); + do { + // Read the command type, waiting for the data to be ready + msg->type = spi_read_byte(); + if (msg->type == SdepSlaveNotReady || msg->type == SdepSlaveOverflow) { + // Release it and let it initialize + digitalWrite(AdafruitBleCSPin, PinLevelHigh); + _delay_us(SdepBackOff); + digitalWrite(AdafruitBleCSPin, PinLevelLow); + continue; + } + + // Read the rest of the header + spi_recv_bytes(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload))); + + // and get the payload if there is any + if (msg->len <= SdepMaxPayload) { + spi_recv_bytes(msg->payload, msg->len); + } + success = true; + break; + } while (timer_elapsed(timerStart) < timeout); - do { - // Read the command type, waiting for the data to be ready - msg->type = spi_read_byte(); - if (msg->type == SdepSlaveNotReady || msg->type == SdepSlaveOverflow) { - // Release it and let it initialize digitalWrite(AdafruitBleCSPin, PinLevelHigh); - _delay_us(SdepBackOff); - digitalWrite(AdafruitBleCSPin, PinLevelLow); - continue; - } - - // Read the rest of the header - spi_recv_bytes(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload))); - - // and get the payload if there is any - if (msg->len <= SdepMaxPayload) { - spi_recv_bytes(msg->payload, msg->len); - } - success = true; - break; - } while (timer_elapsed(timerStart) < timeout); - - digitalWrite(AdafruitBleCSPin, PinLevelHigh); - } - return success; + } + return success; } static void resp_buf_read_one(bool greedy) { - uint16_t last_send; - if (!resp_buf.peek(last_send)) { - return; - } + uint16_t last_send; + if (!resp_buf.peek(last_send)) { + return; + } - if (digitalRead(AdafruitBleIRQPin)) { - struct sdep_msg msg; + if (digitalRead(AdafruitBleIRQPin)) { + struct sdep_msg msg; -again: - if (sdep_recv_pkt(&msg, SdepTimeout)) { - if (!msg.more) { - // We got it; consume this entry - resp_buf.get(last_send); - dprintf("recv latency %dms\n", TIMER_DIFF_16(timer_read(), last_send)); - } + again: + if (sdep_recv_pkt(&msg, SdepTimeout)) { + if (!msg.more) { + // We got it; consume this entry + resp_buf.get(last_send); + dprintf("recv latency %dms\n", TIMER_DIFF_16(timer_read(), last_send)); + } - if (greedy && resp_buf.peek(last_send) && digitalRead(AdafruitBleIRQPin)) { - goto again; - } - } + if (greedy && resp_buf.peek(last_send) && digitalRead(AdafruitBleIRQPin)) { + goto again; + } + } - } else if (timer_elapsed(last_send) > SdepTimeout * 2) { - dprintf("waiting_for_result: timeout, resp_buf size %d\n", - (int)resp_buf.size()); + } else if (timer_elapsed(last_send) > SdepTimeout * 2) { + dprintf("waiting_for_result: timeout, resp_buf size %d\n", (int)resp_buf.size()); - // Timed out: consume this entry - resp_buf.get(last_send); - } + // Timed out: consume this entry + resp_buf.get(last_send); + } } static void send_buf_send_one(uint16_t timeout = SdepTimeout) { - struct queue_item item; - - // Don't send anything more until we get an ACK - if (!resp_buf.empty()) { - return; - } - - if (!send_buf.peek(item)) { - return; - } - if (process_queue_item(&item, timeout)) { - // commit that peek - send_buf.get(item); - dprintf("send_buf_send_one: have %d remaining\n", (int)send_buf.size()); - } else { - dprint("failed to send, will retry\n"); - _delay_ms(SdepTimeout); - resp_buf_read_one(true); - } + struct queue_item item; + + // Don't send anything more until we get an ACK + if (!resp_buf.empty()) { + return; + } + + if (!send_buf.peek(item)) { + return; + } + if (process_queue_item(&item, timeout)) { + // commit that peek + send_buf.get(item); + dprintf("send_buf_send_one: have %d remaining\n", (int)send_buf.size()); + } else { + dprint("failed to send, will retry\n"); + _delay_ms(SdepTimeout); + resp_buf_read_one(true); + } } static void resp_buf_wait(const char *cmd) { - bool didPrint = false; - while (!resp_buf.empty()) { - if (!didPrint) { - dprintf("wait on buf for %s\n", cmd); - didPrint = true; + bool didPrint = false; + while (!resp_buf.empty()) { + if (!didPrint) { + dprintf("wait on buf for %s\n", cmd); + didPrint = true; + } + resp_buf_read_one(true); } - resp_buf_read_one(true); - } } static bool ble_init(void) { - state.initialized = false; - state.configured = false; - state.is_connected = false; + state.initialized = false; + state.configured = false; + state.is_connected = false; - pinMode(AdafruitBleIRQPin, PinDirectionInput); - pinMode(AdafruitBleCSPin, PinDirectionOutput); - digitalWrite(AdafruitBleCSPin, PinLevelHigh); + pinMode(AdafruitBleIRQPin, PinDirectionInput); + pinMode(AdafruitBleCSPin, PinDirectionOutput); + digitalWrite(AdafruitBleCSPin, PinLevelHigh); - SPI_init(&spi); + SPI_init(&spi); - // Perform a hardware reset - pinMode(AdafruitBleResetPin, PinDirectionOutput); - digitalWrite(AdafruitBleResetPin, PinLevelHigh); - digitalWrite(AdafruitBleResetPin, PinLevelLow); - _delay_ms(10); - digitalWrite(AdafruitBleResetPin, PinLevelHigh); + // Perform a hardware reset + pinMode(AdafruitBleResetPin, PinDirectionOutput); + digitalWrite(AdafruitBleResetPin, PinLevelHigh); + digitalWrite(AdafruitBleResetPin, PinLevelLow); + _delay_ms(10); + digitalWrite(AdafruitBleResetPin, PinLevelHigh); - _delay_ms(1000); // Give it a second to initialize + _delay_ms(1000); // Give it a second to initialize - state.initialized = true; - return state.initialized; + state.initialized = true; + return state.initialized; } -static inline uint8_t min(uint8_t a, uint8_t b) { - return a < b ? a : b; -} +static inline uint8_t min(uint8_t a, uint8_t b) { return a < b ? a : b; } static bool read_response(char *resp, uint16_t resplen, bool verbose) { - char *dest = resp; - char *end = dest + resplen; - - while (true) { - struct sdep_msg msg; - - if (!sdep_recv_pkt(&msg, 2 * SdepTimeout)) { - dprint("sdep_recv_pkt failed\n"); - return false; + char *dest = resp; + char *end = dest + resplen; + + while (true) { + struct sdep_msg msg; + + if (!sdep_recv_pkt(&msg, 2 * SdepTimeout)) { + dprint("sdep_recv_pkt failed\n"); + return false; + } + + if (msg.type != SdepResponse) { + *resp = 0; + return false; + } + + uint8_t len = min(msg.len, end - dest); + if (len > 0) { + memcpy(dest, msg.payload, len); + dest += len; + } + + if (!msg.more) { + // No more data is expected! + break; + } } - if (msg.type != SdepResponse) { - *resp = 0; - return false; - } + // Ensure the response is NUL terminated + *dest = 0; - uint8_t len = min(msg.len, end - dest); - if (len > 0) { - memcpy(dest, msg.payload, len); - dest += len; + // "Parse" the result text; we want to snip off the trailing OK or ERROR line + // Rewind past the possible trailing CRLF so that we can strip it + --dest; + while (dest > resp && (dest[0] == '\n' || dest[0] == '\r')) { + *dest = 0; + --dest; } - if (!msg.more) { - // No more data is expected! - break; + // Look back for start of preceeding line + char *last_line = strrchr(resp, '\n'); + if (last_line) { + ++last_line; + } else { + last_line = resp; } - } - - // Ensure the response is NUL terminated - *dest = 0; - // "Parse" the result text; we want to snip off the trailing OK or ERROR line - // Rewind past the possible trailing CRLF so that we can strip it - --dest; - while (dest > resp && (dest[0] == '\n' || dest[0] == '\r')) { - *dest = 0; - --dest; - } + bool success = false; + static const char kOK[] PROGMEM = "OK"; - // Look back for start of preceeding line - char *last_line = strrchr(resp, '\n'); - if (last_line) { - ++last_line; - } else { - last_line = resp; - } + success = !strcmp_P(last_line, kOK); - bool success = false; - static const char kOK[] PROGMEM = "OK"; + if (verbose || !success) { + dprintf("result: %s\n", resp); + } + return success; +} - success = !strcmp_P(last_line, kOK ); +static bool at_command(const char *cmd, char *resp, uint16_t resplen, bool verbose, uint16_t timeout) { + const char * end = cmd + strlen(cmd); + struct sdep_msg msg; - if (verbose || !success) { - dprintf("result: %s\n", resp); - } - return success; -} + if (verbose) { + dprintf("ble send: %s\n", cmd); + } -static bool at_command(const char *cmd, char *resp, uint16_t resplen, - bool verbose, uint16_t timeout) { - const char *end = cmd + strlen(cmd); - struct sdep_msg msg; - - if (verbose) { - dprintf("ble send: %s\n", cmd); - } - - if (resp) { - // They want to decode the response, so we need to flush and wait - // for all pending I/O to finish before we start this one, so - // that we don't confuse the results - resp_buf_wait(cmd); - *resp = 0; - } - - // Fragment the command into a series of SDEP packets - while (end - cmd > SdepMaxPayload) { - sdep_build_pkt(&msg, BleAtWrapper, (uint8_t *)cmd, SdepMaxPayload, true); - if (!sdep_send_pkt(&msg, timeout)) { - return false; + if (resp) { + // They want to decode the response, so we need to flush and wait + // for all pending I/O to finish before we start this one, so + // that we don't confuse the results + resp_buf_wait(cmd); + *resp = 0; } - cmd += SdepMaxPayload; - } - sdep_build_pkt(&msg, BleAtWrapper, (uint8_t *)cmd, end - cmd, false); - if (!sdep_send_pkt(&msg, timeout)) { - return false; - } + // Fragment the command into a series of SDEP packets + while (end - cmd > SdepMaxPayload) { + sdep_build_pkt(&msg, BleAtWrapper, (uint8_t *)cmd, SdepMaxPayload, true); + if (!sdep_send_pkt(&msg, timeout)) { + return false; + } + cmd += SdepMaxPayload; + } - if (resp == NULL) { - auto now = timer_read(); - while (!resp_buf.enqueue(now)) { - resp_buf_read_one(false); + sdep_build_pkt(&msg, BleAtWrapper, (uint8_t *)cmd, end - cmd, false); + if (!sdep_send_pkt(&msg, timeout)) { + return false; } - auto later = timer_read(); - if (TIMER_DIFF_16(later, now) > 0) { - dprintf("waited %dms for resp_buf\n", TIMER_DIFF_16(later, now)); + + if (resp == NULL) { + auto now = timer_read(); + while (!resp_buf.enqueue(now)) { + resp_buf_read_one(false); + } + auto later = timer_read(); + if (TIMER_DIFF_16(later, now) > 0) { + dprintf("waited %dms for resp_buf\n", TIMER_DIFF_16(later, now)); + } + return true; } - return true; - } - return read_response(resp, resplen, verbose); + return read_response(resp, resplen, verbose); } bool at_command_P(const char *cmd, char *resp, uint16_t resplen, bool verbose) { - auto cmdbuf = (char *)alloca(strlen_P(cmd) + 1); - strcpy_P(cmdbuf, cmd); - return at_command(cmdbuf, resp, resplen, verbose); + auto cmdbuf = (char *)alloca(strlen_P(cmd) + 1); + strcpy_P(cmdbuf, cmd); + return at_command(cmdbuf, resp, resplen, verbose); } -bool adafruit_ble_is_connected(void) { - return state.is_connected; -} +bool adafruit_ble_is_connected(void) { return state.is_connected; } bool adafruit_ble_enable_keyboard(void) { - char resbuf[128]; - - if (!state.initialized && !ble_init()) { - return false; - } - - state.configured = false; - - // Disable command echo - static const char kEcho[] PROGMEM = "ATE=0"; - // Make the advertised name match the keyboard - static const char kGapDevName[] PROGMEM = "AT+GAPDEVNAME=" STR(PRODUCT); - // Turn on keyboard support - static const char kHidEnOn[] PROGMEM = "AT+BLEHIDEN=1"; - - // Adjust intervals to improve latency. This causes the "central" - // system (computer/tablet) to poll us every 10-30 ms. We can't - // set a smaller value than 10ms, and 30ms seems to be the natural - // processing time on my macbook. Keeping it constrained to that - // feels reasonable to type to. - static const char kGapIntervals[] PROGMEM = "AT+GAPINTERVALS=10,30,,"; - - // Reset the device so that it picks up the above changes - static const char kATZ[] PROGMEM = "ATZ"; - - // Turn down the power level a bit - static const char kPower[] PROGMEM = "AT+BLEPOWERLEVEL=-12"; - static PGM_P const configure_commands[] PROGMEM = { - kEcho, - kGapIntervals, - kGapDevName, - kHidEnOn, - kPower, - kATZ, - }; - - uint8_t i; - for (i = 0; i < sizeof(configure_commands) / sizeof(configure_commands[0]); - ++i) { - PGM_P cmd; - memcpy_P(&cmd, configure_commands + i, sizeof(cmd)); - - if (!at_command_P(cmd, resbuf, sizeof(resbuf))) { - dprintf("failed BLE command: %S: %s\n", cmd, resbuf); - goto fail; - } - } - - state.configured = true; - - // Check connection status in a little while; allow the ATZ time - // to kick in. - state.last_connection_update = timer_read(); + char resbuf[128]; + + if (!state.initialized && !ble_init()) { + return false; + } + + state.configured = false; + + // Disable command echo + static const char kEcho[] PROGMEM = "ATE=0"; + // Make the advertised name match the keyboard + static const char kGapDevName[] PROGMEM = "AT+GAPDEVNAME=" STR(PRODUCT); + // Turn on keyboard support + static const char kHidEnOn[] PROGMEM = "AT+BLEHIDEN=1"; + + // Adjust intervals to improve latency. This causes the "central" + // system (computer/tablet) to poll us every 10-30 ms. We can't + // set a smaller value than 10ms, and 30ms seems to be the natural + // processing time on my macbook. Keeping it constrained to that + // feels reasonable to type to. + static const char kGapIntervals[] PROGMEM = "AT+GAPINTERVALS=10,30,,"; + + // Reset the device so that it picks up the above changes + static const char kATZ[] PROGMEM = "ATZ"; + + // Turn down the power level a bit + static const char kPower[] PROGMEM = "AT+BLEPOWERLEVEL=-12"; + static PGM_P const configure_commands[] PROGMEM = { + kEcho, kGapIntervals, kGapDevName, kHidEnOn, kPower, kATZ, + }; + + uint8_t i; + for (i = 0; i < sizeof(configure_commands) / sizeof(configure_commands[0]); ++i) { + PGM_P cmd; + memcpy_P(&cmd, configure_commands + i, sizeof(cmd)); + + if (!at_command_P(cmd, resbuf, sizeof(resbuf))) { + dprintf("failed BLE command: %S: %s\n", cmd, resbuf); + goto fail; + } + } + + state.configured = true; + + // Check connection status in a little while; allow the ATZ time + // to kick in. + state.last_connection_update = timer_read(); fail: - return state.configured; + return state.configured; } static void set_connected(bool connected) { - if (connected != state.is_connected) { - if (connected) { - print("****** BLE CONNECT!!!!\n"); - } else { - print("****** BLE DISCONNECT!!!!\n"); - } - state.is_connected = connected; - - // TODO: if modifiers are down on the USB interface and - // we cut over to BLE or vice versa, they will remain stuck. - // This feels like a good point to do something like clearing - // the keyboard and/or generating a fake all keys up message. - // However, I've noticed that it takes a couple of seconds - // for macOS to to start recognizing key presses after BLE - // is in the connected state, so I worry that doing that - // here may not be good enough. - } + if (connected != state.is_connected) { + if (connected) { + print("****** BLE CONNECT!!!!\n"); + } else { + print("****** BLE DISCONNECT!!!!\n"); + } + state.is_connected = connected; + + // TODO: if modifiers are down on the USB interface and + // we cut over to BLE or vice versa, they will remain stuck. + // This feels like a good point to do something like clearing + // the keyboard and/or generating a fake all keys up message. + // However, I've noticed that it takes a couple of seconds + // for macOS to to start recognizing key presses after BLE + // is in the connected state, so I worry that doing that + // here may not be good enough. + } } void adafruit_ble_task(void) { - char resbuf[48]; - - if (!state.configured && !adafruit_ble_enable_keyboard()) { - return; - } - resp_buf_read_one(true); - send_buf_send_one(SdepShortTimeout); - - if (resp_buf.empty() && (state.event_flags & UsingEvents) && - digitalRead(AdafruitBleIRQPin)) { - // Must be an event update - if (at_command_P(PSTR("AT+EVENTSTATUS"), resbuf, sizeof(resbuf))) { - uint32_t mask = strtoul(resbuf, NULL, 16); - - if (mask & BleSystemConnected) { - set_connected(true); - } else if (mask & BleSystemDisconnected) { - set_connected(false); - } - } - } - - if (timer_elapsed(state.last_connection_update) > ConnectionUpdateInterval) { - bool shouldPoll = true; - if (!(state.event_flags & ProbedEvents)) { - // Request notifications about connection status changes. - // This only works in SPIFRIEND firmware > 0.6.7, which is why - // we check for this conditionally here. - // Note that at the time of writing, HID reports only work correctly - // with Apple products on firmware version 0.6.7! - // https://forums.adafruit.com/viewtopic.php?f=8&t=104052 - if (at_command_P(PSTR("AT+EVENTENABLE=0x1"), resbuf, sizeof(resbuf))) { - at_command_P(PSTR("AT+EVENTENABLE=0x2"), resbuf, sizeof(resbuf)); - state.event_flags |= UsingEvents; - } - state.event_flags |= ProbedEvents; - - // leave shouldPoll == true so that we check at least once - // before relying solely on events - } else { - shouldPoll = false; - } + char resbuf[48]; - static const char kGetConn[] PROGMEM = "AT+GAPGETCONN"; - state.last_connection_update = timer_read(); + if (!state.configured && !adafruit_ble_enable_keyboard()) { + return; + } + resp_buf_read_one(true); + send_buf_send_one(SdepShortTimeout); + + if (resp_buf.empty() && (state.event_flags & UsingEvents) && digitalRead(AdafruitBleIRQPin)) { + // Must be an event update + if (at_command_P(PSTR("AT+EVENTSTATUS"), resbuf, sizeof(resbuf))) { + uint32_t mask = strtoul(resbuf, NULL, 16); + + if (mask & BleSystemConnected) { + set_connected(true); + } else if (mask & BleSystemDisconnected) { + set_connected(false); + } + } + } - if (at_command_P(kGetConn, resbuf, sizeof(resbuf))) { - set_connected(atoi(resbuf)); + if (timer_elapsed(state.last_connection_update) > ConnectionUpdateInterval) { + bool shouldPoll = true; + if (!(state.event_flags & ProbedEvents)) { + // Request notifications about connection status changes. + // This only works in SPIFRIEND firmware > 0.6.7, which is why + // we check for this conditionally here. + // Note that at the time of writing, HID reports only work correctly + // with Apple products on firmware version 0.6.7! + // https://forums.adafruit.com/viewtopic.php?f=8&t=104052 + if (at_command_P(PSTR("AT+EVENTENABLE=0x1"), resbuf, sizeof(resbuf))) { + at_command_P(PSTR("AT+EVENTENABLE=0x2"), resbuf, sizeof(resbuf)); + state.event_flags |= UsingEvents; + } + state.event_flags |= ProbedEvents; + + // leave shouldPoll == true so that we check at least once + // before relying solely on events + } else { + shouldPoll = false; + } + + static const char kGetConn[] PROGMEM = "AT+GAPGETCONN"; + state.last_connection_update = timer_read(); + + if (at_command_P(kGetConn, resbuf, sizeof(resbuf))) { + set_connected(atoi(resbuf)); + } } - } #ifdef SAMPLE_BATTERY - // I don't know if this really does anything useful yet; the reported - // voltage level always seems to be around 3200mV. We may want to just rip - // this code out. - if (timer_elapsed(state.last_battery_update) > BatteryUpdateInterval && - resp_buf.empty()) { - state.last_battery_update = timer_read(); - - if (at_command_P(PSTR("AT+HWVBAT"), resbuf, sizeof(resbuf))) { - state.vbat = atoi(resbuf); + // I don't know if this really does anything useful yet; the reported + // voltage level always seems to be around 3200mV. We may want to just rip + // this code out. + if (timer_elapsed(state.last_battery_update) > BatteryUpdateInterval && resp_buf.empty()) { + state.last_battery_update = timer_read(); + + if (at_command_P(PSTR("AT+HWVBAT"), resbuf, sizeof(resbuf))) { + state.vbat = atoi(resbuf); + } } - } #endif } static bool process_queue_item(struct queue_item *item, uint16_t timeout) { - char cmdbuf[48]; - char fmtbuf[64]; + char cmdbuf[48]; + char fmtbuf[64]; - // Arrange to re-check connection after keys have settled - state.last_connection_update = timer_read(); + // Arrange to re-check connection after keys have settled + state.last_connection_update = timer_read(); #if 1 - if (TIMER_DIFF_16(state.last_connection_update, item->added) > 0) { - dprintf("send latency %dms\n", - TIMER_DIFF_16(state.last_connection_update, item->added)); - } + if (TIMER_DIFF_16(state.last_connection_update, item->added) > 0) { + dprintf("send latency %dms\n", TIMER_DIFF_16(state.last_connection_update, item->added)); + } #endif - switch (item->queue_type) { - case QTKeyReport: - strcpy_P(fmtbuf, - PSTR("AT+BLEKEYBOARDCODE=%02x-00-%02x-%02x-%02x-%02x-%02x-%02x")); - snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->key.modifier, - item->key.keys[0], item->key.keys[1], item->key.keys[2], - item->key.keys[3], item->key.keys[4], item->key.keys[5]); - return at_command(cmdbuf, NULL, 0, true, timeout); + switch (item->queue_type) { + case QTKeyReport: + strcpy_P(fmtbuf, PSTR("AT+BLEKEYBOARDCODE=%02x-00-%02x-%02x-%02x-%02x-%02x-%02x")); + snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->key.modifier, item->key.keys[0], item->key.keys[1], item->key.keys[2], item->key.keys[3], item->key.keys[4], item->key.keys[5]); + return at_command(cmdbuf, NULL, 0, true, timeout); - case QTConsumer: - strcpy_P(fmtbuf, PSTR("AT+BLEHIDCONTROLKEY=0x%04x")); - snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->consumer); - return at_command(cmdbuf, NULL, 0, true, timeout); + case QTConsumer: + strcpy_P(fmtbuf, PSTR("AT+BLEHIDCONTROLKEY=0x%04x")); + snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->consumer); + return at_command(cmdbuf, NULL, 0, true, timeout); #ifdef MOUSE_ENABLE - case QTMouseMove: - strcpy_P(fmtbuf, PSTR("AT+BLEHIDMOUSEMOVE=%d,%d,%d,%d")); - snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->mousemove.x, - item->mousemove.y, item->mousemove.scroll, item->mousemove.pan); - if (!at_command(cmdbuf, NULL, 0, true, timeout)) { - return false; - } - strcpy_P(cmdbuf, PSTR("AT+BLEHIDMOUSEBUTTON=")); - if (item->mousemove.buttons & MOUSE_BTN1) { - strcat(cmdbuf, "L"); - } - if (item->mousemove.buttons & MOUSE_BTN2) { - strcat(cmdbuf, "R"); - } - if (item->mousemove.buttons & MOUSE_BTN3) { - strcat(cmdbuf, "M"); - } - if (item->mousemove.buttons == 0) { - strcat(cmdbuf, "0"); - } - return at_command(cmdbuf, NULL, 0, true, timeout); + case QTMouseMove: + strcpy_P(fmtbuf, PSTR("AT+BLEHIDMOUSEMOVE=%d,%d,%d,%d")); + snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->mousemove.x, item->mousemove.y, item->mousemove.scroll, item->mousemove.pan); + if (!at_command(cmdbuf, NULL, 0, true, timeout)) { + return false; + } + strcpy_P(cmdbuf, PSTR("AT+BLEHIDMOUSEBUTTON=")); + if (item->mousemove.buttons & MOUSE_BTN1) { + strcat(cmdbuf, "L"); + } + if (item->mousemove.buttons & MOUSE_BTN2) { + strcat(cmdbuf, "R"); + } + if (item->mousemove.buttons & MOUSE_BTN3) { + strcat(cmdbuf, "M"); + } + if (item->mousemove.buttons == 0) { + strcat(cmdbuf, "0"); + } + return at_command(cmdbuf, NULL, 0, true, timeout); #endif - default: - return true; - } -} - -bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, - uint8_t nkeys) { - struct queue_item item; - bool didWait = false; - - item.queue_type = QTKeyReport; - item.key.modifier = hid_modifier_mask; - item.added = timer_read(); - - while (nkeys >= 0) { - item.key.keys[0] = keys[0]; - item.key.keys[1] = nkeys >= 1 ? keys[1] : 0; - item.key.keys[2] = nkeys >= 2 ? keys[2] : 0; - item.key.keys[3] = nkeys >= 3 ? keys[3] : 0; - item.key.keys[4] = nkeys >= 4 ? keys[4] : 0; - item.key.keys[5] = nkeys >= 5 ? keys[5] : 0; - - if (!send_buf.enqueue(item)) { - if (!didWait) { - dprint("wait for buf space\n"); - didWait = true; - } - send_buf_send_one(); - continue; + default: + return true; } +} - if (nkeys <= 6) { - return true; +bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys) { + struct queue_item item; + bool didWait = false; + + item.queue_type = QTKeyReport; + item.key.modifier = hid_modifier_mask; + item.added = timer_read(); + + while (nkeys >= 0) { + item.key.keys[0] = keys[0]; + item.key.keys[1] = nkeys >= 1 ? keys[1] : 0; + item.key.keys[2] = nkeys >= 2 ? keys[2] : 0; + item.key.keys[3] = nkeys >= 3 ? keys[3] : 0; + item.key.keys[4] = nkeys >= 4 ? keys[4] : 0; + item.key.keys[5] = nkeys >= 5 ? keys[5] : 0; + + if (!send_buf.enqueue(item)) { + if (!didWait) { + dprint("wait for buf space\n"); + didWait = true; + } + send_buf_send_one(); + continue; + } + + if (nkeys <= 6) { + return true; + } + + nkeys -= 6; + keys += 6; } - nkeys -= 6; - keys += 6; - } - - return true; + return true; } bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration) { - struct queue_item item; + struct queue_item item; - item.queue_type = QTConsumer; - item.consumer = keycode; + item.queue_type = QTConsumer; + item.consumer = keycode; - while (!send_buf.enqueue(item)) { - send_buf_send_one(); - } - return true; + while (!send_buf.enqueue(item)) { + send_buf_send_one(); + } + return true; } #ifdef MOUSE_ENABLE -bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, - int8_t pan, uint8_t buttons) { - struct queue_item item; - - item.queue_type = QTMouseMove; - item.mousemove.x = x; - item.mousemove.y = y; - item.mousemove.scroll = scroll; - item.mousemove.pan = pan; - item.mousemove.buttons = buttons; - - while (!send_buf.enqueue(item)) { - send_buf_send_one(); - } - return true; +bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons) { + struct queue_item item; + + item.queue_type = QTMouseMove; + item.mousemove.x = x; + item.mousemove.y = y; + item.mousemove.scroll = scroll; + item.mousemove.pan = pan; + item.mousemove.buttons = buttons; + + while (!send_buf.enqueue(item)) { + send_buf_send_one(); + } + return true; } #endif -uint32_t adafruit_ble_read_battery_voltage(void) { - return state.vbat; -} +uint32_t adafruit_ble_read_battery_voltage(void) { return state.vbat; } bool adafruit_ble_set_mode_leds(bool on) { - if (!state.configured) { - return false; - } - - // The "mode" led is the red blinky one - at_command_P(on ? PSTR("AT+HWMODELED=1") : PSTR("AT+HWMODELED=0"), NULL, 0); - - // Pin 19 is the blue "connected" LED; turn that off too. - // When turning LEDs back on, don't turn that LED on if we're - // not connected, as that would be confusing. - at_command_P(on && state.is_connected ? PSTR("AT+HWGPIO=19,1") - : PSTR("AT+HWGPIO=19,0"), - NULL, 0); - return true; + if (!state.configured) { + return false; + } + + // The "mode" led is the red blinky one + at_command_P(on ? PSTR("AT+HWMODELED=1") : PSTR("AT+HWMODELED=0"), NULL, 0); + + // Pin 19 is the blue "connected" LED; turn that off too. + // When turning LEDs back on, don't turn that LED on if we're + // not connected, as that would be confusing. + at_command_P(on && state.is_connected ? PSTR("AT+HWGPIO=19,1") : PSTR("AT+HWGPIO=19,0"), NULL, 0); + return true; } // https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le/ble-generic#at-plus-blepowerlevel bool adafruit_ble_set_power_level(int8_t level) { - char cmd[46]; - if (!state.configured) { - return false; - } - snprintf(cmd, sizeof(cmd), "AT+BLEPOWERLEVEL=%d", level); - return at_command(cmd, NULL, 0, false); + char cmd[46]; + if (!state.configured) { + return false; + } + snprintf(cmd, sizeof(cmd), "AT+BLEPOWERLEVEL=%d", level); + return at_command(cmd, NULL, 0, false); } diff --git a/tmk_core/protocol/lufa/adafruit_ble.h b/tmk_core/protocol/lufa/adafruit_ble.h index 5d26a9d5a3..cef46fe9f7 100644 --- a/tmk_core/protocol/lufa/adafruit_ble.h +++ b/tmk_core/protocol/lufa/adafruit_ble.h @@ -4,16 +4,16 @@ */ #pragma once #ifdef MODULE_ADAFRUIT_BLE -#include <stdbool.h> -#include <stdint.h> -#include <string.h> +# include <stdbool.h> +# include <stdint.h> +# include <string.h> -#include "config_common.h" -#include "progmem.h" +# include "config_common.h" +# include "progmem.h" -#ifdef __cplusplus +# ifdef __cplusplus extern "C" { -#endif +# endif /* Instruct the module to enable HID keyboard support and reset */ extern bool adafruit_ble_enable_keyboard(void); @@ -34,20 +34,18 @@ extern void adafruit_ble_task(void); * this set of keys. * Also sends a key release indicator, so that the keys do not remain * held down. */ -extern bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, - uint8_t nkeys); +extern bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys); /* Send a consumer keycode, holding it down for the specified duration * (milliseconds) */ extern bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration); -#ifdef MOUSE_ENABLE +# ifdef MOUSE_ENABLE /* Send a mouse/wheel movement report. * The parameters are signed and indicate positive of negative direction * change. */ -extern bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, - int8_t pan, uint8_t buttons); -#endif +extern bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons); +# endif /* Compute battery voltage by reading an analog pin. * Returns the integer number of millivolts */ @@ -56,8 +54,8 @@ extern uint32_t adafruit_ble_read_battery_voltage(void); extern bool adafruit_ble_set_mode_leds(bool on); extern bool adafruit_ble_set_power_level(int8_t level); -#ifdef __cplusplus +# ifdef __cplusplus } -#endif +# endif -#endif // MODULE_ADAFRUIT_BLE +#endif // MODULE_ADAFRUIT_BLE diff --git a/tmk_core/protocol/lufa/bluetooth.c b/tmk_core/protocol/lufa/bluetooth.c index 549606162d..5eb52860b1 100644 --- a/tmk_core/protocol/lufa/bluetooth.c +++ b/tmk_core/protocol/lufa/bluetooth.c @@ -21,16 +21,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "debug.h" #include "bluetooth.h" -void bluefruit_keyboard_print_report(report_keyboard_t *report) -{ +void bluefruit_keyboard_print_report(report_keyboard_t *report) { if (!debug_keyboard) return; - dprintf("keys: "); for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) { debug_hex8(report->keys[i]); dprintf(" "); } - dprintf(" mods: "); debug_hex8(report->mods); - dprintf(" reserved: "); debug_hex8(report->reserved); + dprintf("keys: "); + for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) { + debug_hex8(report->keys[i]); + dprintf(" "); + } + dprintf(" mods: "); + debug_hex8(report->mods); + dprintf(" reserved: "); + debug_hex8(report->reserved); dprintf("\n"); } -void bluefruit_serial_send(uint8_t data) -{ - serial_send(data); -}
\ No newline at end of file +void bluefruit_serial_send(uint8_t data) { serial_send(data); }
\ No newline at end of file diff --git a/tmk_core/protocol/lufa/bluetooth.h b/tmk_core/protocol/lufa/bluetooth.h index f4b2f6f8b1..081271a4e6 100644 --- a/tmk_core/protocol/lufa/bluetooth.h +++ b/tmk_core/protocol/lufa/bluetooth.h @@ -41,39 +41,8 @@ void bluefruit_serial_send(uint8_t data); | Stop | 00000000 00010000 | 00 10 | +-------------------------------------+-------+ */ -#define CONSUMER2BLUEFRUIT(usage) \ - (usage == AUDIO_MUTE ? 0x0000 : \ - (usage == AUDIO_VOL_UP ? 0x1000 : \ - (usage == AUDIO_VOL_DOWN ? 0x2000 : \ - (usage == TRANSPORT_NEXT_TRACK ? 0x0002 : \ - (usage == TRANSPORT_PREV_TRACK ? 0x0004 : \ - (usage == TRANSPORT_STOP ? 0x0010 : \ - (usage == TRANSPORT_STOP_EJECT ? 0x0000 : \ - (usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : \ - (usage == AL_CC_CONFIG ? 0x0000 : \ - (usage == AL_EMAIL ? 0x0000 : \ - (usage == AL_CALCULATOR ? 0x0000 : \ - (usage == AL_LOCAL_BROWSER ? 0x0000 : \ - (usage == AC_SEARCH ? 0x0400 : \ - (usage == AC_HOME ? 0x0100 : \ - (usage == AC_BACK ? 0x0000 : \ - (usage == AC_FORWARD ? 0x0000 : \ - (usage == AC_STOP ? 0x0000 : \ - (usage == AC_REFRESH ? 0x0000 : \ - (usage == AC_BOOKMARKS ? 0x0000 : 0))))))))))))))))))) +#define CONSUMER2BLUEFRUIT(usage) (usage == AUDIO_MUTE ? 0x0000 : (usage == AUDIO_VOL_UP ? 0x1000 : (usage == AUDIO_VOL_DOWN ? 0x2000 : (usage == TRANSPORT_NEXT_TRACK ? 0x0002 : (usage == TRANSPORT_PREV_TRACK ? 0x0004 : (usage == TRANSPORT_STOP ? 0x0010 : (usage == TRANSPORT_STOP_EJECT ? 0x0000 : (usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : (usage == AL_CC_CONFIG ? 0x0000 : (usage == AL_EMAIL ? 0x0000 : (usage == AL_CALCULATOR ? 0x0000 : (usage == AL_LOCAL_BROWSER ? 0x0000 : (usage == AC_SEARCH ? 0x0400 : (usage == AC_HOME ? 0x0100 : (usage == AC_BACK ? 0x0000 : (usage == AC_FORWARD ? 0x0000 : (usage == AC_STOP ? 0x0000 : (usage == AC_REFRESH ? 0x0000 : (usage == AC_BOOKMARKS ? 0x0000 : 0))))))))))))))))))) -#define CONSUMER2RN42(usage) \ - (usage == AUDIO_MUTE ? 0x0040 : \ - (usage == AUDIO_VOL_UP ? 0x0010 : \ - (usage == AUDIO_VOL_DOWN ? 0x0020 : \ - (usage == TRANSPORT_NEXT_TRACK ? 0x0100 : \ - (usage == TRANSPORT_PREV_TRACK ? 0x0200 : \ - (usage == TRANSPORT_STOP ? 0x0400 : \ - (usage == TRANSPORT_STOP_EJECT ? 0x0800 : \ - (usage == TRANSPORT_PLAY_PAUSE ? 0x0080 : \ - (usage == AL_EMAIL ? 0x0200 : \ - (usage == AL_LOCAL_BROWSER ? 0x8000 : \ - (usage == AC_SEARCH ? 0x0400 : \ - (usage == AC_HOME ? 0x0100 : 0)))))))))))) +#define CONSUMER2RN42(usage) (usage == AUDIO_MUTE ? 0x0040 : (usage == AUDIO_VOL_UP ? 0x0010 : (usage == AUDIO_VOL_DOWN ? 0x0020 : (usage == TRANSPORT_NEXT_TRACK ? 0x0100 : (usage == TRANSPORT_PREV_TRACK ? 0x0200 : (usage == TRANSPORT_STOP ? 0x0400 : (usage == TRANSPORT_STOP_EJECT ? 0x0800 : (usage == TRANSPORT_PLAY_PAUSE ? 0x0080 : (usage == AL_EMAIL ? 0x0200 : (usage == AL_LOCAL_BROWSER ? 0x8000 : (usage == AC_SEARCH ? 0x0400 : (usage == AC_HOME ? 0x0100 : 0)))))))))))) - #endif +#endif diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index f2ecf24651..12a6924fd0 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -45,7 +45,7 @@ #include "sendchar.h" #include "debug.h" #ifdef SLEEP_LED_ENABLE -#include "sleep_led.h" +# include "sleep_led.h" #endif #include "suspend.h" @@ -57,86 +57,80 @@ #include "rgblight_reconfig.h" #ifdef NKRO_ENABLE - #include "keycode_config.h" +# include "keycode_config.h" - extern keymap_config_t keymap_config; +extern keymap_config_t keymap_config; #endif - #ifdef AUDIO_ENABLE - #include <audio.h> +# include <audio.h> #endif #ifdef BLUETOOTH_ENABLE - #ifdef MODULE_ADAFRUIT_BLE - #include "adafruit_ble.h" - #else - #include "bluetooth.h" - #endif +# ifdef MODULE_ADAFRUIT_BLE +# include "adafruit_ble.h" +# else +# include "bluetooth.h" +# endif #endif #ifdef VIRTSER_ENABLE - #include "virtser.h" +# include "virtser.h" #endif #if (defined(RGB_MIDI) | defined(RGBLIGHT_ANIMATIONS)) & defined(RGBLIGHT_ENABLE) - #include "rgblight.h" +# include "rgblight.h" #endif #ifdef MIDI_ENABLE - #include "qmk_midi.h" +# include "qmk_midi.h" #endif #ifdef RAW_ENABLE - #include "raw_hid.h" +# include "raw_hid.h" #endif uint8_t keyboard_idle = 0; /* 0: Boot Protocol, 1: Report Protocol(default) */ -uint8_t keyboard_protocol = 1; +uint8_t keyboard_protocol = 1; static uint8_t keyboard_led_stats = 0; static report_keyboard_t keyboard_report_sent; /* Host driver */ static uint8_t keyboard_leds(void); -static void send_keyboard(report_keyboard_t *report); -static void send_mouse(report_mouse_t *report); -static void send_system(uint16_t data); -static void send_consumer(uint16_t data); -host_driver_t lufa_driver = { - keyboard_leds, - send_keyboard, - send_mouse, - send_system, - send_consumer, +static void send_keyboard(report_keyboard_t *report); +static void send_mouse(report_mouse_t *report); +static void send_system(uint16_t data); +static void send_consumer(uint16_t data); +host_driver_t lufa_driver = { + keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer, }; #ifdef VIRTSER_ENABLE -USB_ClassInfo_CDC_Device_t cdc_device = -{ - .Config = - { - .ControlInterfaceNumber = CCI_INTERFACE, - .DataINEndpoint = - { - .Address = CDC_IN_EPADDR, - .Size = CDC_EPSIZE, - .Banks = 1, - }, - .DataOUTEndpoint = - { - .Address = CDC_OUT_EPADDR, - .Size = CDC_EPSIZE, - .Banks = 1, - }, - .NotificationEndpoint = - { - .Address = CDC_NOTIFICATION_EPADDR, - .Size = CDC_NOTIFICATION_EPSIZE, - .Banks = 1, - }, - }, +USB_ClassInfo_CDC_Device_t cdc_device = { + .Config = + { + .ControlInterfaceNumber = CCI_INTERFACE, + .DataINEndpoint = + { + .Address = CDC_IN_EPADDR, + .Size = CDC_EPSIZE, + .Banks = 1, + }, + .DataOUTEndpoint = + { + .Address = CDC_OUT_EPADDR, + .Size = CDC_EPSIZE, + .Banks = 1, + }, + .NotificationEndpoint = + { + .Address = CDC_NOTIFICATION_EPADDR, + .Size = CDC_NOTIFICATION_EPSIZE, + .Banks = 1, + }, + }, }; #endif @@ -146,84 +140,73 @@ USB_ClassInfo_CDC_Device_t cdc_device = * * FIXME: Needs doc */ -void raw_hid_send( uint8_t *data, uint8_t length ) -{ - // TODO: implement variable size packet - if ( length != RAW_EPSIZE ) - { - return; - } - - if (USB_DeviceState != DEVICE_STATE_Configured) - { - return; - } - - // TODO: decide if we allow calls to raw_hid_send() in the middle - // of other endpoint usage. - uint8_t ep = Endpoint_GetCurrentEndpoint(); - - Endpoint_SelectEndpoint(RAW_IN_EPNUM); - - // Check to see if the host is ready to accept another packet - if (Endpoint_IsINReady()) - { - // Write data - Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL); - // Finalize the stream transfer to send the last packet - Endpoint_ClearIN(); - } - - Endpoint_SelectEndpoint(ep); +void raw_hid_send(uint8_t *data, uint8_t length) { + // TODO: implement variable size packet + if (length != RAW_EPSIZE) { + return; + } + + if (USB_DeviceState != DEVICE_STATE_Configured) { + return; + } + + // TODO: decide if we allow calls to raw_hid_send() in the middle + // of other endpoint usage. + uint8_t ep = Endpoint_GetCurrentEndpoint(); + + Endpoint_SelectEndpoint(RAW_IN_EPNUM); + + // Check to see if the host is ready to accept another packet + if (Endpoint_IsINReady()) { + // Write data + Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL); + // Finalize the stream transfer to send the last packet + Endpoint_ClearIN(); + } + + Endpoint_SelectEndpoint(ep); } /** \brief Raw HID Receive * * FIXME: Needs doc */ -__attribute__ ((weak)) -void raw_hid_receive( uint8_t *data, uint8_t length ) -{ - // Users should #include "raw_hid.h" in their own code - // and implement this function there. Leave this as weak linkage - // so users can opt to not handle data coming in. +__attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) { + // Users should #include "raw_hid.h" in their own code + // and implement this function there. Leave this as weak linkage + // so users can opt to not handle data coming in. } /** \brief Raw HID Task * * FIXME: Needs doc */ -static void raw_hid_task(void) -{ - // Create a temporary buffer to hold the read in data from the host - uint8_t data[RAW_EPSIZE]; - bool data_read = false; - - // Device must be connected and configured for the task to run - if (USB_DeviceState != DEVICE_STATE_Configured) - return; - - Endpoint_SelectEndpoint(RAW_OUT_EPNUM); - - // Check to see if a packet has been sent from the host - if (Endpoint_IsOUTReceived()) - { - // Check to see if the packet contains data - if (Endpoint_IsReadWriteAllowed()) - { - /* Read data */ - Endpoint_Read_Stream_LE(data, sizeof(data), NULL); - data_read = true; - } - - // Finalize the stream transfer to receive the last packet - Endpoint_ClearOUT(); - - if ( data_read ) - { - raw_hid_receive( data, sizeof(data) ); - } - } +static void raw_hid_task(void) { + // Create a temporary buffer to hold the read in data from the host + uint8_t data[RAW_EPSIZE]; + bool data_read = false; + + // Device must be connected and configured for the task to run + if (USB_DeviceState != DEVICE_STATE_Configured) return; + + Endpoint_SelectEndpoint(RAW_OUT_EPNUM); + + // Check to see if a packet has been sent from the host + if (Endpoint_IsOUTReceived()) { + // Check to see if the packet contains data + if (Endpoint_IsReadWriteAllowed()) { + /* Read data */ + Endpoint_Read_Stream_LE(data, sizeof(data), NULL); + data_read = true; + } + + // Finalize the stream transfer to receive the last packet + Endpoint_ClearOUT(); + + if (data_read) { + raw_hid_receive(data, sizeof(data)); + } + } } #endif @@ -235,15 +218,13 @@ static void raw_hid_task(void) * * FIXME: Needs doc */ -static void Console_Task(void) -{ +static void Console_Task(void) { /* Device must be connected and configured for the task to run */ - if (USB_DeviceState != DEVICE_STATE_Configured) - return; + if (USB_DeviceState != DEVICE_STATE_Configured) return; uint8_t ep = Endpoint_GetCurrentEndpoint(); -#if 0 +# if 0 // TODO: impl receivechar()/recvchar() Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM); @@ -266,7 +247,7 @@ static void Console_Task(void) /* Finalize the stream transfer to send the last packet */ Endpoint_ClearOUT(); } -#endif +# endif /* IN packet */ Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM); @@ -276,8 +257,7 @@ static void Console_Task(void) } // fill empty bank - while (Endpoint_IsReadWriteAllowed()) - Endpoint_Write_8(0); + while (Endpoint_IsReadWriteAllowed()) Endpoint_Write_8(0); // flash senchar packet if (Endpoint_IsINReady()) { @@ -288,7 +268,6 @@ static void Console_Task(void) } #endif - /******************************************************************************* * USB Events ******************************************************************************/ @@ -298,13 +277,12 @@ static void Console_Task(void) * 1) EVENT_USB_Device_Suspend * 2) EVENT_USB_Device_Reset * 3) EVENT_USB_Device_Wake -*/ + */ /** \brief Event USB Device Connect * * FIXME: Needs doc */ -void EVENT_USB_Device_Connect(void) -{ +void EVENT_USB_Device_Connect(void) { print("[C]"); /* For battery powered device */ if (!USB_IsInitialized) { @@ -318,35 +296,30 @@ void EVENT_USB_Device_Connect(void) * * FIXME: Needs doc */ -void EVENT_USB_Device_Disconnect(void) -{ +void EVENT_USB_Device_Disconnect(void) { print("[D]"); /* For battery powered device */ USB_IsInitialized = false; -/* TODO: This doesn't work. After several plug in/outs can not be enumerated. - if (USB_IsInitialized) { - USB_Disable(); // Disable all interrupts - USB_Controller_Enable(); - USB_INT_Enable(USB_INT_VBUSTI); - } -*/ + /* TODO: This doesn't work. After several plug in/outs can not be enumerated. + if (USB_IsInitialized) { + USB_Disable(); // Disable all interrupts + USB_Controller_Enable(); + USB_INT_Enable(USB_INT_VBUSTI); + } + */ } /** \brief Event USB Device Connect * * FIXME: Needs doc */ -void EVENT_USB_Device_Reset(void) -{ - print("[R]"); -} +void EVENT_USB_Device_Reset(void) { print("[R]"); } /** \brief Event USB Device Connect * * FIXME: Needs doc */ -void EVENT_USB_Device_Suspend() -{ +void EVENT_USB_Device_Suspend() { print("[S]"); #ifdef SLEEP_LED_ENABLE sleep_led_enable(); @@ -357,8 +330,7 @@ void EVENT_USB_Device_Suspend() * * FIXME: Needs doc */ -void EVENT_USB_Device_WakeUp() -{ +void EVENT_USB_Device_WakeUp() { print("[W]"); suspend_wakeup_init(); @@ -369,23 +341,19 @@ void EVENT_USB_Device_WakeUp() #endif } - - #ifdef CONSOLE_ENABLE static bool console_flush = false; -#define CONSOLE_FLUSH_SET(b) do { \ - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {\ - console_flush = b; \ - } \ -} while (0) +# define CONSOLE_FLUSH_SET(b) \ + do { \ + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { console_flush = b; } \ + } while (0) /** \brief Event USB Device Start Of Frame * * FIXME: Needs doc * called every 1ms */ -void EVENT_USB_Device_StartOfFrame(void) -{ +void EVENT_USB_Device_StartOfFrame(void) { static uint8_t count; if (++count % 50) return; count = 0; @@ -404,44 +372,37 @@ void EVENT_USB_Device_StartOfFrame(void) * ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4, * it is safe to use single bank for all endpoints. */ -void EVENT_USB_Device_ConfigurationChanged(void) -{ +void EVENT_USB_Device_ConfigurationChanged(void) { bool ConfigSuccess = true; /* Setup Keyboard HID Report Endpoints */ #ifndef KEYBOARD_SHARED_EP - ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE); #endif #if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP) /* Setup Mouse HID Report Endpoint */ - ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE); #endif #ifdef SHARED_EP_ENABLE /* Setup Shared HID Report Endpoint */ - ConfigSuccess &= ENDPOINT_CONFIG(SHARED_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - SHARED_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= ENDPOINT_CONFIG(SHARED_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, SHARED_EPSIZE, ENDPOINT_BANK_SINGLE); #endif #ifdef RAW_ENABLE /* Setup Raw HID Report Endpoints */ - ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - RAW_EPSIZE, ENDPOINT_BANK_SINGLE); - ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, - RAW_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= ENDPOINT_CONFIG(RAW_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, RAW_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= ENDPOINT_CONFIG(RAW_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, RAW_EPSIZE, ENDPOINT_BANK_SINGLE); #endif #ifdef CONSOLE_ENABLE /* Setup Console HID Report Endpoints */ - ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); -#if 0 + ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); +# if 0 ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); -#endif +# endif #endif #ifdef MIDI_ENABLE @@ -473,26 +434,23 @@ Other Device Required Optional Optional Optional Optional Opti * * This is fired before passing along unhandled control requests to the library for processing internally. */ -void EVENT_USB_Device_ControlRequest(void) -{ - uint8_t* ReportData = NULL; +void EVENT_USB_Device_ControlRequest(void) { + uint8_t *ReportData = NULL; uint8_t ReportSize = 0; /* Handle HID Class specific requests */ - switch (USB_ControlRequest.bRequest) - { + switch (USB_ControlRequest.bRequest) { case HID_REQ_GetReport: - if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) - { + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); // Interface switch (USB_ControlRequest.wIndex) { - case KEYBOARD_INTERFACE: - // TODO: test/check - ReportData = (uint8_t*)&keyboard_report_sent; - ReportSize = sizeof(keyboard_report_sent); - break; + case KEYBOARD_INTERFACE: + // TODO: test/check + ReportData = (uint8_t *)&keyboard_report_sent; + ReportSize = sizeof(keyboard_report_sent); + break; } /* Write the report data to the control endpoint */ @@ -502,47 +460,43 @@ void EVENT_USB_Device_ControlRequest(void) break; case HID_REQ_SetReport: - if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) - { - + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { // Interface switch (USB_ControlRequest.wIndex) { - case KEYBOARD_INTERFACE: + case KEYBOARD_INTERFACE: #if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP) - case SHARED_INTERFACE: + case SHARED_INTERFACE: #endif - Endpoint_ClearSETUP(); + Endpoint_ClearSETUP(); - while (!(Endpoint_IsOUTReceived())) { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return; - } + while (!(Endpoint_IsOUTReceived())) { + if (USB_DeviceState == DEVICE_STATE_Unattached) return; + } - if (Endpoint_BytesInEndpoint() == 2) { - uint8_t report_id = Endpoint_Read_8(); + if (Endpoint_BytesInEndpoint() == 2) { + uint8_t report_id = Endpoint_Read_8(); - if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) { - keyboard_led_stats = Endpoint_Read_8(); - } - } else { - keyboard_led_stats = Endpoint_Read_8(); - } + if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) { + keyboard_led_stats = Endpoint_Read_8(); + } + } else { + keyboard_led_stats = Endpoint_Read_8(); + } - Endpoint_ClearOUT(); - Endpoint_ClearStatusStage(); - break; + Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); + break; } - } break; case HID_REQ_GetProtocol: - if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) - { + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) { Endpoint_ClearSETUP(); - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + ; Endpoint_Write_8(keyboard_protocol); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); @@ -551,8 +505,7 @@ void EVENT_USB_Device_ControlRequest(void) break; case HID_REQ_SetProtocol: - if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) - { + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { if (USB_ControlRequest.wIndex == KEYBOARD_INTERFACE) { Endpoint_ClearSETUP(); Endpoint_ClearStatusStage(); @@ -564,8 +517,7 @@ void EVENT_USB_Device_ControlRequest(void) break; case HID_REQ_SetIdle: - if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) - { + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); Endpoint_ClearStatusStage(); @@ -574,10 +526,10 @@ void EVENT_USB_Device_ControlRequest(void) break; case HID_REQ_GetIdle: - if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) - { + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + ; Endpoint_Write_8(keyboard_idle); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); @@ -598,54 +550,50 @@ void EVENT_USB_Device_ControlRequest(void) * * FIXME: Needs doc */ -static uint8_t keyboard_leds(void) -{ - return keyboard_led_stats; -} +static uint8_t keyboard_leds(void) { return keyboard_led_stats; } /** \brief Send Keyboard * * FIXME: Needs doc */ -static void send_keyboard(report_keyboard_t *report) -{ +static void send_keyboard(report_keyboard_t *report) { uint8_t timeout = 255; - uint8_t where = where_to_send(); + uint8_t where = where_to_send(); #ifdef BLUETOOTH_ENABLE - if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { - #ifdef MODULE_ADAFRUIT_BLE - adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys)); - #elif MODULE_RN42 - bluefruit_serial_send(0xFD); - bluefruit_serial_send(0x09); - bluefruit_serial_send(0x01); - bluefruit_serial_send(report->mods); - bluefruit_serial_send(report->reserved); - for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { - bluefruit_serial_send(report->keys[i]); - } - #else - bluefruit_serial_send(0xFD); - bluefruit_serial_send(report->mods); - bluefruit_serial_send(report->reserved); - for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { - bluefruit_serial_send(report->keys[i]); - } - #endif - } + if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { +# ifdef MODULE_ADAFRUIT_BLE + adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys)); +# elif MODULE_RN42 + bluefruit_serial_send(0xFD); + bluefruit_serial_send(0x09); + bluefruit_serial_send(0x01); + bluefruit_serial_send(report->mods); + bluefruit_serial_send(report->reserved); + for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { + bluefruit_serial_send(report->keys[i]); + } +# else + bluefruit_serial_send(0xFD); + bluefruit_serial_send(report->mods); + bluefruit_serial_send(report->reserved); + for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { + bluefruit_serial_send(report->keys[i]); + } +# endif + } #endif if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) { - return; + return; } /* Select the Keyboard Report Endpoint */ - uint8_t ep = KEYBOARD_IN_EPNUM; + uint8_t ep = KEYBOARD_IN_EPNUM; uint8_t size = KEYBOARD_REPORT_SIZE; #ifdef NKRO_ENABLE if (keyboard_protocol && keymap_config.nkro) { - ep = SHARED_IN_EPNUM; + ep = SHARED_IN_EPNUM; size = sizeof(struct nkro_report); } #endif @@ -666,38 +614,37 @@ static void send_keyboard(report_keyboard_t *report) keyboard_report_sent = *report; } - + /** \brief Send Mouse * * FIXME: Needs doc */ -static void send_mouse(report_mouse_t *report) -{ +static void send_mouse(report_mouse_t *report) { #ifdef MOUSE_ENABLE uint8_t timeout = 255; - uint8_t where = where_to_send(); + uint8_t where = where_to_send(); -#ifdef BLUETOOTH_ENABLE - if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { - #ifdef MODULE_ADAFRUIT_BLE - // FIXME: mouse buttons - adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons); - #else - bluefruit_serial_send(0xFD); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x03); - bluefruit_serial_send(report->buttons); - bluefruit_serial_send(report->x); - bluefruit_serial_send(report->y); - bluefruit_serial_send(report->v); // should try sending the wheel v here - bluefruit_serial_send(report->h); // should try sending the wheel h here - bluefruit_serial_send(0x00); - #endif - } -#endif +# ifdef BLUETOOTH_ENABLE + if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { +# ifdef MODULE_ADAFRUIT_BLE + // FIXME: mouse buttons + adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons); +# else + bluefruit_serial_send(0xFD); + bluefruit_serial_send(0x00); + bluefruit_serial_send(0x03); + bluefruit_serial_send(report->buttons); + bluefruit_serial_send(report->x); + bluefruit_serial_send(report->y); + bluefruit_serial_send(report->v); // should try sending the wheel v here + bluefruit_serial_send(report->h); // should try sending the wheel h here + bluefruit_serial_send(0x00); +# endif + } +# endif if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) { - return; + return; } /* Select the Mouse Report Endpoint */ @@ -719,18 +666,13 @@ static void send_mouse(report_mouse_t *report) * * FIXME: Needs doc */ -static void send_system(uint16_t data) -{ +static void send_system(uint16_t data) { #ifdef EXTRAKEY_ENABLE uint8_t timeout = 255; - if (USB_DeviceState != DEVICE_STATE_Configured) - return; + if (USB_DeviceState != DEVICE_STATE_Configured) return; - report_extra_t r = { - .report_id = REPORT_ID_SYSTEM, - .usage = data - SYSTEM_POWER_DOWN + 1 - }; + report_extra_t r = {.report_id = REPORT_ID_SYSTEM, .usage = data - SYSTEM_POWER_DOWN + 1}; Endpoint_SelectEndpoint(SHARED_IN_EPNUM); /* Check if write ready for a polling interval around 10ms */ @@ -746,52 +688,48 @@ static void send_system(uint16_t data) * * FIXME: Needs doc */ -static void send_consumer(uint16_t data) -{ +static void send_consumer(uint16_t data) { #ifdef EXTRAKEY_ENABLE uint8_t timeout = 255; - uint8_t where = where_to_send(); + uint8_t where = where_to_send(); -#ifdef BLUETOOTH_ENABLE +# ifdef BLUETOOTH_ENABLE if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { - #ifdef MODULE_ADAFRUIT_BLE +# ifdef MODULE_ADAFRUIT_BLE adafruit_ble_send_consumer_key(data, 0); - #elif MODULE_RN42 +# elif MODULE_RN42 static uint16_t last_data = 0; if (data == last_data) return; - last_data = data; + last_data = data; uint16_t bitmap = CONSUMER2RN42(data); bluefruit_serial_send(0xFD); bluefruit_serial_send(0x03); bluefruit_serial_send(0x03); - bluefruit_serial_send(bitmap&0xFF); - bluefruit_serial_send((bitmap>>8)&0xFF); - #else + bluefruit_serial_send(bitmap & 0xFF); + bluefruit_serial_send((bitmap >> 8) & 0xFF); +# else static uint16_t last_data = 0; if (data == last_data) return; - last_data = data; + last_data = data; uint16_t bitmap = CONSUMER2BLUEFRUIT(data); bluefruit_serial_send(0xFD); bluefruit_serial_send(0x00); bluefruit_serial_send(0x02); - bluefruit_serial_send((bitmap>>8)&0xFF); - bluefruit_serial_send(bitmap&0xFF); + bluefruit_serial_send((bitmap >> 8) & 0xFF); + bluefruit_serial_send(bitmap & 0xFF); bluefruit_serial_send(0x00); bluefruit_serial_send(0x00); bluefruit_serial_send(0x00); bluefruit_serial_send(0x00); - #endif +# endif } -#endif +# endif if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) { - return; + return; } - report_extra_t r = { - .report_id = REPORT_ID_CONSUMER, - .usage = data - }; + report_extra_t r = {.report_id = REPORT_ID_CONSUMER, .usage = data}; Endpoint_SelectEndpoint(SHARED_IN_EPNUM); /* Check if write ready for a polling interval around 10ms */ @@ -803,18 +741,16 @@ static void send_consumer(uint16_t data) #endif } - /******************************************************************************* * sendchar ******************************************************************************/ #ifdef CONSOLE_ENABLE -#define SEND_TIMEOUT 5 +# define SEND_TIMEOUT 5 /** \brief Send Char * * FIXME: Needs doc */ -int8_t sendchar(uint8_t c) -{ +int8_t sendchar(uint8_t c) { // Not wait once timeouted. // Because sendchar() is called so many times, waiting each call causes big lag. static bool timeouted = false; @@ -823,8 +759,7 @@ int8_t sendchar(uint8_t c) // or char will be lost. These two function is mutually exclusive. CONSOLE_FLUSH_SET(false); - if (USB_DeviceState != DEVICE_STATE_Configured) - return -1; + if (USB_DeviceState != DEVICE_STATE_Configured) return -1; uint8_t ep = Endpoint_GetCurrentEndpoint(); Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM); @@ -857,7 +792,8 @@ int8_t sendchar(uint8_t c) // send when bank is full if (!Endpoint_IsReadWriteAllowed()) { - while (!(Endpoint_IsINReady())); + while (!(Endpoint_IsINReady())) + ; Endpoint_ClearIN(); } else { CONSOLE_FLUSH_SET(true); @@ -870,10 +806,7 @@ ERROR_EXIT: return -1; } #else -int8_t sendchar(uint8_t c) -{ - return 0; -} +int8_t sendchar(uint8_t c) { return 0; } #endif /******************************************************************************* @@ -881,33 +814,28 @@ int8_t sendchar(uint8_t c) ******************************************************************************/ #ifdef MIDI_ENABLE -USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface = -{ - .Config = - { - .StreamingInterfaceNumber = AS_INTERFACE, - .DataINEndpoint = - { - .Address = MIDI_STREAM_IN_EPADDR, - .Size = MIDI_STREAM_EPSIZE, - .Banks = 1, - }, - .DataOUTEndpoint = - { - .Address = MIDI_STREAM_OUT_EPADDR, - .Size = MIDI_STREAM_EPSIZE, - .Banks = 1, - }, - }, +USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface = { + .Config = + { + .StreamingInterfaceNumber = AS_INTERFACE, + .DataINEndpoint = + { + .Address = MIDI_STREAM_IN_EPADDR, + .Size = MIDI_STREAM_EPSIZE, + .Banks = 1, + }, + .DataOUTEndpoint = + { + .Address = MIDI_STREAM_OUT_EPADDR, + .Size = MIDI_STREAM_EPSIZE, + .Banks = 1, + }, + }, }; -void send_midi_packet(MIDI_EventPacket_t* event) { - MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event); -} +void send_midi_packet(MIDI_EventPacket_t *event) { MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event); } -bool recv_midi_packet(MIDI_EventPacket_t* const event) { - return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event); -} +bool recv_midi_packet(MIDI_EventPacket_t *const event) { return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event); } #endif @@ -920,66 +848,60 @@ bool recv_midi_packet(MIDI_EventPacket_t* const event) { * * FIXME: Needs doc */ -void virtser_init(void) -{ - cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR ; - CDC_Device_SendControlLineStateChange(&cdc_device); +void virtser_init(void) { + cdc_device.State.ControlLineStates.DeviceToHost = CDC_CONTROL_LINE_IN_DSR; + CDC_Device_SendControlLineStateChange(&cdc_device); } /** \brief Virtual Serial Receive * * FIXME: Needs doc */ -void virtser_recv(uint8_t c) __attribute__ ((weak)); -void virtser_recv(uint8_t c) -{ - // Ignore by default +void virtser_recv(uint8_t c) __attribute__((weak)); +void virtser_recv(uint8_t c) { + // Ignore by default } /** \brief Virtual Serial Task * * FIXME: Needs doc */ -void virtser_task(void) -{ - uint16_t count = CDC_Device_BytesReceived(&cdc_device); - uint8_t ch; - if (count) - { - ch = CDC_Device_ReceiveByte(&cdc_device); - virtser_recv(ch); - } +void virtser_task(void) { + uint16_t count = CDC_Device_BytesReceived(&cdc_device); + uint8_t ch; + if (count) { + ch = CDC_Device_ReceiveByte(&cdc_device); + virtser_recv(ch); + } } /** \brief Virtual Serial Send * * FIXME: Needs doc */ -void virtser_send(const uint8_t byte) -{ - uint8_t timeout = 255; - uint8_t ep = Endpoint_GetCurrentEndpoint(); +void virtser_send(const uint8_t byte) { + uint8_t timeout = 255; + uint8_t ep = Endpoint_GetCurrentEndpoint(); - if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) - { - /* IN packet */ - Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address); + if (cdc_device.State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) { + /* IN packet */ + Endpoint_SelectEndpoint(cdc_device.Config.DataINEndpoint.Address); - if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) { - Endpoint_SelectEndpoint(ep); - return; - } + if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) { + Endpoint_SelectEndpoint(ep); + return; + } - while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); + while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40); - Endpoint_Write_8(byte); - CDC_Device_Flush(&cdc_device); + Endpoint_Write_8(byte); + CDC_Device_Flush(&cdc_device); - if (Endpoint_IsINReady()) { - Endpoint_ClearIN(); - } + if (Endpoint_IsINReady()) { + Endpoint_ClearIN(); + } - Endpoint_SelectEndpoint(ep); - } + Endpoint_SelectEndpoint(ep); + } } #endif @@ -990,8 +912,7 @@ void virtser_send(const uint8_t byte) * * FIXME: Needs doc */ -static void setup_mcu(void) -{ +static void setup_mcu(void) { /* Disable watchdog if enabled by bootloader/fuses */ MCUSR &= ~(1 << WDRF); wdt_disable(); @@ -1007,8 +928,7 @@ static void setup_mcu(void) * * FIXME: Needs doc */ -static void setup_usb(void) -{ +static void setup_usb(void) { // Leonardo needs. Without this USB device is not recognized. USB_Disable(); @@ -1023,9 +943,8 @@ static void setup_usb(void) * * FIXME: Needs doc */ -int main(void) __attribute__ ((weak)); -int main(void) -{ +int main(void) __attribute__((weak)); +int main(void) { #ifdef MIDI_ENABLE setup_midi(); #endif @@ -1043,11 +962,11 @@ int main(void) #ifdef WAIT_FOR_USB while (USB_DeviceState != DEVICE_STATE_Configured) { - #if defined(INTERRUPT_CONTROL_ENDPOINT) - ; - #else - USB_USBTask(); - #endif +# if defined(INTERRUPT_CONTROL_ENDPOINT) + ; +# else + USB_USBTask(); +# endif } print("USB configured.\n"); #else @@ -1066,15 +985,15 @@ int main(void) print("Keyboard start.\n"); while (1) { - #if !defined(NO_USB_STARTUP_CHECK) +#if !defined(NO_USB_STARTUP_CHECK) while (USB_DeviceState == DEVICE_STATE_Suspended) { print("[s]"); suspend_power_down(); if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { - USB_Device_SendRemoteWakeup(); + USB_Device_SendRemoteWakeup(); } } - #endif +#endif keyboard_task(); @@ -1102,14 +1021,7 @@ int main(void) #if !defined(INTERRUPT_CONTROL_ENDPOINT) USB_USBTask(); #endif - } } -uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, - const uint16_t wIndex, - const void** const DescriptorAddress) -{ - return get_usb_descriptor(wValue, wIndex, DescriptorAddress); -} - +uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint16_t wIndex, const void **const DescriptorAddress) { return get_usb_descriptor(wValue, wIndex, DescriptorAddress); } diff --git a/tmk_core/protocol/lufa/lufa.h b/tmk_core/protocol/lufa/lufa.h index 7364cdf7ce..652e4e79b7 100644 --- a/tmk_core/protocol/lufa/lufa.h +++ b/tmk_core/protocol/lufa/lufa.h @@ -62,27 +62,27 @@ extern host_driver_t lufa_driver; typedef struct { uint8_t report_id; uint16_t usage; -} __attribute__ ((packed)) report_extra_t; +} __attribute__((packed)) report_extra_t; #ifdef API_ENABLE - #include "api.h" +# include "api.h" #endif #ifdef API_SYSEX_ENABLE - #include "api_sysex.h" - // Allocate space for encoding overhead. - //The header and terminator are not stored to save a few bytes of precious ram - #define MIDI_SYSEX_BUFFER (API_SYSEX_MAX_SIZE + API_SYSEX_MAX_SIZE / 7 + (API_SYSEX_MAX_SIZE % 7 ? 1 : 0)) +# include "api_sysex.h" +// Allocate space for encoding overhead. +// The header and terminator are not stored to save a few bytes of precious ram +# define MIDI_SYSEX_BUFFER (API_SYSEX_MAX_SIZE + API_SYSEX_MAX_SIZE / 7 + (API_SYSEX_MAX_SIZE % 7 ? 1 : 0)) #endif // #if LUFA_VERSION_INTEGER < 0x120730 // /* old API 120219 */ // #define ENDPOINT_CONFIG(epnum, eptype, epdir, epsize, epbank) Endpoint_ConfigureEndpoint(epnum, eptype, epdir, epsize, epbank) // #else - /* new API >= 120730 */ - #define ENDPOINT_BANK_SINGLE 1 - #define ENDPOINT_BANK_DOUBLE 2 - #define ENDPOINT_CONFIG(epnum, eptype, epdir, epsize, epbank) Endpoint_ConfigureEndpoint((epdir) | (epnum) , eptype, epsize, epbank) +/* new API >= 120730 */ +#define ENDPOINT_BANK_SINGLE 1 +#define ENDPOINT_BANK_DOUBLE 2 +#define ENDPOINT_CONFIG(epnum, eptype, epdir, epsize, epbank) Endpoint_ConfigureEndpoint((epdir) | (epnum), eptype, epsize, epbank) // #endif #endif diff --git a/tmk_core/protocol/lufa/outputselect.c b/tmk_core/protocol/lufa/outputselect.c index 42de806120..b115ea9691 100644 --- a/tmk_core/protocol/lufa/outputselect.c +++ b/tmk_core/protocol/lufa/outputselect.c @@ -15,7 +15,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "lufa.h" #include "outputselect.h" #ifdef MODULE_ADAFRUIT_BLE - #include "adafruit_ble.h" +# include "adafruit_ble.h" #endif uint8_t desired_output = OUTPUT_DEFAULT; @@ -33,9 +33,7 @@ void set_output(uint8_t output) { * * FIXME: Needs doc */ -__attribute__((weak)) -void set_output_user(uint8_t output) { -} +__attribute__((weak)) void set_output_user(uint8_t output) {} /** \brief Auto Detect Output * @@ -53,7 +51,7 @@ uint8_t auto_detect_output(void) { #endif #ifdef BLUETOOTH_ENABLE - return OUTPUT_BLUETOOTH; // should check if BT is connected here + return OUTPUT_BLUETOOTH; // should check if BT is connected here #endif return OUTPUT_NONE; @@ -69,4 +67,3 @@ uint8_t where_to_send(void) { } return desired_output; } - diff --git a/tmk_core/protocol/lufa/outputselect.h b/tmk_core/protocol/lufa/outputselect.h index 28cc3298e6..24fe4daa24 100644 --- a/tmk_core/protocol/lufa/outputselect.h +++ b/tmk_core/protocol/lufa/outputselect.h @@ -27,14 +27,14 @@ enum outputs { * backward compatibility for BLUETOOTH_ENABLE, send to BT and USB by default */ #ifndef OUTPUT_DEFAULT - #ifdef BLUETOOTH_ENABLE - #define OUTPUT_DEFAULT OUTPUT_USB_AND_BT - #else - #define OUTPUT_DEFAULT OUTPUT_AUTO - #endif +# ifdef BLUETOOTH_ENABLE +# define OUTPUT_DEFAULT OUTPUT_USB_AND_BT +# else +# define OUTPUT_DEFAULT OUTPUT_AUTO +# endif #endif -void set_output(uint8_t output); -void set_output_user(uint8_t output); +void set_output(uint8_t output); +void set_output_user(uint8_t output); uint8_t auto_detect_output(void); uint8_t where_to_send(void);
\ No newline at end of file |