diff options
Diffstat (limited to 'drivers')
22 files changed, 938 insertions, 1696 deletions
| diff --git a/drivers/bluetooth/adafruit_ble.cpp b/drivers/bluetooth/adafruit_ble.cpp new file mode 100644 index 0000000000..34a780e9a5 --- /dev/null +++ b/drivers/bluetooth/adafruit_ble.cpp @@ -0,0 +1,699 @@ +#include "adafruit_ble.h" + +#include <stdio.h> +#include <stdlib.h> +#include <alloca.h> +#include "debug.h" +#include "timer.h" +#include "action_util.h" +#include "ringbuffer.hpp" +#include <string.h> +#include "spi_master.h" +#include "wait.h" +#include "analog.h" +#include "progmem.h" + +// These are the pin assignments for the 32u4 boards. +// You may define them to something else in your config.h +// if yours is wired up differently. +#ifndef ADAFRUIT_BLE_RST_PIN +#    define ADAFRUIT_BLE_RST_PIN D4 +#endif + +#ifndef ADAFRUIT_BLE_CS_PIN +#    define ADAFRUIT_BLE_CS_PIN B4 +#endif + +#ifndef ADAFRUIT_BLE_IRQ_PIN +#    define ADAFRUIT_BLE_IRQ_PIN E6 +#endif + +#ifndef ADAFRUIT_BLE_SCK_DIVISOR +#    define ADAFRUIT_BLE_SCK_DIVISOR 2  // 4MHz SCK/8MHz CPU, calculated for Feather 32U4 BLE +#endif + +#define SAMPLE_BATTERY +#define ConnectionUpdateInterval 1000 /* milliseconds */ + +#ifndef BATTERY_LEVEL_PIN +#    define BATTERY_LEVEL_PIN B5 +#endif + +static struct { +    bool is_connected; +    bool initialized; +    bool configured; + +#define ProbedEvents 1 +#define UsingEvents 2 +    bool event_flags; + +#ifdef SAMPLE_BATTERY +    uint16_t last_battery_update; +    uint32_t vbat; +#endif +    uint16_t last_connection_update; +} state; + +// Commands are encoded using SDEP and sent via SPI +// https://github.com/adafruit/Adafruit_BluefruitLE_nRF51/blob/master/SDEP.md + +#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]; +} __attribute__((packed)); + +// The recv latency is relatively high, so when we're hammering keys quickly, +// we want to avoid waiting for the responses in the matrix loop.  We maintain +// a short queue for that.  Since there is quite a lot of space overhead for +// the AT command representation wrapped up in SDEP, we queue the minimal +// information here. + +enum queue_type { +    QTKeyReport,  // 1-byte modifier + 6-byte key report +    QTConsumer,   // 16-bit key code +#ifdef MOUSE_ENABLE +    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; +    }; +}; + +// Items that we wish to send +static RingBuffer<queue_item, 40> send_buf; +// Pending response; while pending, we can't send any more requests. +// This records the time at which we sent the command for which we +// are expecting a response. +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 +}; + +enum ble_cmd { +    BleInitialize = 0xBEEF, +    BleAtWrapper  = 0x0A00, +    BleUartTx     = 0x0A01, +    BleUartRx     = 0x0A02, +}; + +enum ble_system_event_bits { +    BleSystemConnected    = 0, +    BleSystemDisconnected = 1, +    BleSystemUartRx       = 8, +    BleSystemMidiRx       = 10, +}; + +#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); + +// Send a single SDEP packet +static bool sdep_send_pkt(const struct sdep_msg *msg, uint16_t timeout) { +    spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR); +    uint16_t timerStart = timer_read(); +    bool     success    = false; +    bool     ready      = false; + +    do { +        ready = spi_write(msg->type) != SdepSlaveNotReady; +        if (ready) { +            break; +        } + +        // Release it and let it initialize +        spi_stop(); +        wait_us(SdepBackOff); +        spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR); +    } while (timer_elapsed(timerStart) < timeout); + +    if (ready) { +        // Slave is ready; send the rest of the packet +        spi_transmit(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload)) + msg->len); +        success = true; +    } + +    spi_stop(); + +    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_assert(sizeof(*msg) == 20, "msg is correctly packed"); + +    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; + +    do { +        ready = readPin(ADAFRUIT_BLE_IRQ_PIN); +        if (ready) { +            break; +        } +        wait_us(1); +    } while (timer_elapsed(timerStart) < timeout); + +    if (ready) { +        spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR); + +        do { +            // Read the command type, waiting for the data to be ready +            msg->type = spi_read(); +            if (msg->type == SdepSlaveNotReady || msg->type == SdepSlaveOverflow) { +                // Release it and let it initialize +                spi_stop(); +                wait_us(SdepBackOff); +                spi_start(ADAFRUIT_BLE_CS_PIN, false, 0, ADAFRUIT_BLE_SCK_DIVISOR); +                continue; +            } + +            // Read the rest of the header +            spi_receive(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload))); + +            // and get the payload if there is any +            if (msg->len <= SdepMaxPayload) { +                spi_receive(msg->payload, msg->len); +            } +            success = true; +            break; +        } while (timer_elapsed(timerStart) < timeout); + +        spi_stop(); +    } +    return success; +} + +static void resp_buf_read_one(bool greedy) { +    uint16_t last_send; +    if (!resp_buf.peek(last_send)) { +        return; +    } + +    if (readPin(ADAFRUIT_BLE_IRQ_PIN)) { +        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)); +            } + +            if (greedy && resp_buf.peek(last_send) && readPin(ADAFRUIT_BLE_IRQ_PIN)) { +                goto again; +            } +        } + +    } 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); +    } +} + +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"); +        wait_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; +        } +        resp_buf_read_one(true); +    } +} + +static bool ble_init(void) { +    state.initialized  = false; +    state.configured   = false; +    state.is_connected = false; + +    setPinInput(ADAFRUIT_BLE_IRQ_PIN); + +    spi_init(); + +    // Perform a hardware reset +    setPinOutput(ADAFRUIT_BLE_RST_PIN); +    writePinHigh(ADAFRUIT_BLE_RST_PIN); +    writePinLow(ADAFRUIT_BLE_RST_PIN); +    wait_ms(10); +    writePinHigh(ADAFRUIT_BLE_RST_PIN); + +    wait_ms(1000);  // Give it a second to initialize + +    state.initialized = true; +    return state.initialized; +} + +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; +        } + +        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; +        } +    } + +    // 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; +    } + +    // Look back for start of preceeding line +    char *last_line = strrchr(resp, '\n'); +    if (last_line) { +        ++last_line; +    } else { +        last_line = resp; +    } + +    bool              success       = false; +    static const char kOK[] PROGMEM = "OK"; + +    success = !strcmp_P(last_line, kOK); + +    if (verbose || !success) { +        dprintf("result: %s\n", resp); +    } +    return success; +} + +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; +        } +        cmd += SdepMaxPayload; +    } + +    sdep_build_pkt(&msg, BleAtWrapper, (uint8_t *)cmd, end - cmd, false); +    if (!sdep_send_pkt(&msg, timeout)) { +        return false; +    } + +    if (resp == NULL) { +        uint16_t now = timer_read(); +        while (!resp_buf.enqueue(now)) { +            resp_buf_read_one(false); +        } +        uint16_t 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 read_response(resp, resplen, verbose); +} + +bool at_command_P(const char *cmd, char *resp, uint16_t resplen, bool verbose) { +    char *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_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(); +fail: +    return state.configured; +} + +static void set_connected(bool connected) { +    if (connected != state.is_connected) { +        if (connected) { +            dprint("BLE connected\n"); +        } else { +            dprint("BLE disconnected\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) && readPin(ADAFRUIT_BLE_IRQ_PIN)) { +        // 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; +        } + +        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 +    if (timer_elapsed(state.last_battery_update) > BatteryUpdateInterval && resp_buf.empty()) { +        state.last_battery_update = timer_read(); + +        state.vbat = analogReadPin(BATTERY_LEVEL_PIN); +    } +#endif +} + +static bool process_queue_item(struct queue_item *item, uint16_t timeout) { +    char cmdbuf[48]; +    char fmtbuf[64]; + +    // 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)); +    } +#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); + +        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); +#endif +        default: +            return true; +    } +} + +void 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; +        } + +        nkeys -= 6; +        keys += 6; +    } +} + +void adafruit_ble_send_consumer_key(uint16_t usage) { +    struct queue_item item; + +    item.queue_type = QTConsumer; +    item.consumer   = usage; + +    while (!send_buf.enqueue(item)) { +        send_buf_send_one(); +    } +} + +#ifdef MOUSE_ENABLE +void 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(); +    } +} +#endif + +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; +} + +// 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); +} diff --git a/drivers/bluetooth/adafruit_ble.h b/drivers/bluetooth/adafruit_ble.h new file mode 100644 index 0000000000..b43e0771d9 --- /dev/null +++ b/drivers/bluetooth/adafruit_ble.h @@ -0,0 +1,59 @@ +/* Bluetooth Low Energy Protocol for QMK. + * Author: Wez Furlong, 2016 + * Supports the Adafruit BLE board built around the nRF51822 chip. + */ + +#pragma once + +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + +#include "config_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Instruct the module to enable HID keyboard support and reset */ +extern bool adafruit_ble_enable_keyboard(void); + +/* Query to see if the BLE module is connected */ +extern bool adafruit_ble_query_is_connected(void); + +/* Returns true if we believe that the BLE module is connected. + * This uses our cached understanding that is maintained by + * calling ble_task() periodically. */ +extern bool adafruit_ble_is_connected(void); + +/* Call this periodically to process BLE-originated things */ +extern void adafruit_ble_task(void); + +/* Generates keypress events for a set of keys. + * The hid modifier mask specifies the state of the modifier keys for + * this set of keys. + * Also sends a key release indicator, so that the keys do not remain + * held down. */ +extern void adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys); + +/* Send a consumer usage. + * (milliseconds) */ +extern void adafruit_ble_send_consumer_key(uint16_t usage); + +#ifdef MOUSE_ENABLE +/* Send a mouse/wheel movement report. + * The parameters are signed and indicate positive or negative direction + * change. */ +extern void 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 */ +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 +} +#endif diff --git a/drivers/bluetooth/outputselect.c b/drivers/bluetooth/outputselect.c new file mode 100644 index 0000000000..f758c65280 --- /dev/null +++ b/drivers/bluetooth/outputselect.c @@ -0,0 +1,79 @@ +/* +Copyright 2017 Priyadi Iman Nurcahyo +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "outputselect.h" + +#if defined(PROTOCOL_LUFA) +#    include "lufa.h" +#endif + +#ifdef MODULE_ADAFRUIT_BLE +#    include "adafruit_ble.h" +#endif + +uint8_t desired_output = OUTPUT_DEFAULT; + +/** \brief Set Output + * + * FIXME: Needs doc + */ +void set_output(uint8_t output) { +    set_output_user(output); +    desired_output = output; +} + +/** \brief Set Output User + * + * FIXME: Needs doc + */ +__attribute__((weak)) void set_output_user(uint8_t output) {} + +static bool is_usb_configured(void) { +#if defined(PROTOCOL_LUFA) +    return USB_DeviceState == DEVICE_STATE_Configured; +#endif +} + +/** \brief Auto Detect Output + * + * FIXME: Needs doc + */ +uint8_t auto_detect_output(void) { +    if (is_usb_configured()) { +        return OUTPUT_USB; +    } + +#ifdef MODULE_ADAFRUIT_BLE +    if (adafruit_ble_is_connected()) { +        return OUTPUT_BLUETOOTH; +    } +#endif + +#ifdef BLUETOOTH_ENABLE +    return OUTPUT_BLUETOOTH;  // should check if BT is connected here +#endif + +    return OUTPUT_NONE; +} + +/** \brief Where To Send + * + * FIXME: Needs doc + */ +uint8_t where_to_send(void) { +    if (desired_output == OUTPUT_AUTO) { +        return auto_detect_output(); +    } +    return desired_output; +} diff --git a/drivers/bluetooth/outputselect.h b/drivers/bluetooth/outputselect.h new file mode 100644 index 0000000000..c4548e1122 --- /dev/null +++ b/drivers/bluetooth/outputselect.h @@ -0,0 +1,34 @@ +/* +Copyright 2017 Priyadi Iman Nurcahyo +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <stdint.h> + +enum outputs { +    OUTPUT_AUTO, + +    OUTPUT_NONE, +    OUTPUT_USB, +    OUTPUT_BLUETOOTH +}; + +#ifndef OUTPUT_DEFAULT +#    define OUTPUT_DEFAULT OUTPUT_AUTO +#endif + +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); diff --git a/drivers/bluetooth/ringbuffer.hpp b/drivers/bluetooth/ringbuffer.hpp new file mode 100644 index 0000000000..70a3c4881d --- /dev/null +++ b/drivers/bluetooth/ringbuffer.hpp @@ -0,0 +1,66 @@ +#pragma once +// A simple ringbuffer holding Size elements of type T +template <typename T, uint8_t Size> +class RingBuffer { + protected: +  T buf_[Size]; +  uint8_t head_{0}, tail_{0}; + public: +  inline uint8_t nextPosition(uint8_t position) { +    return (position + 1) % Size; +  } + +  inline uint8_t prevPosition(uint8_t position) { +    if (position == 0) { +      return Size - 1; +    } +    return position - 1; +  } + +  inline bool enqueue(const T &item) { +    static_assert(Size > 1, "RingBuffer size must be > 1"); +    uint8_t next = nextPosition(head_); +    if (next == tail_) { +      // Full +      return false; +    } + +    buf_[head_] = item; +    head_ = next; +    return true; +  } + +  inline bool get(T &dest, bool commit = true) { +    auto tail = tail_; +    if (tail == head_) { +      // No more data +      return false; +    } + +    dest = buf_[tail]; +    tail = nextPosition(tail); + +    if (commit) { +      tail_ = tail; +    } +    return true; +  } + +  inline bool empty() const { return head_ == tail_; } + +  inline uint8_t size() const { +    int diff = head_ - tail_; +    if (diff >= 0) { +      return diff; +    } +    return Size + diff; +  } + +  inline T& front() { +    return buf_[tail_]; +  } + +  inline bool peek(T &item) { +    return get(item, false); +  } +}; diff --git a/drivers/led/apa102.c b/drivers/led/apa102.c index 7396dc3c55..19e0bfc189 100644 --- a/drivers/led/apa102.c +++ b/drivers/led/apa102.c @@ -25,7 +25,7 @@  #        include "hal.h"  #        if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F3XX) || defined(STM32F4XX) || defined(STM32L0XX) -#            define APA102_NOPS (100 / (1000000000L / (STM32_SYSCLK / 4)))  // This calculates how many loops of 4 nops to run to delay 100 ns +#            define APA102_NOPS (100 / (1000000000L / (CPU_CLOCK / 4)))  // This calculates how many loops of 4 nops to run to delay 100 ns  #        else  #            error("APA102_NOPS configuration required")  #            define APA102_NOPS 0  // this just pleases the compile so the above error is easier to spot diff --git a/drivers/qwiic/micro_oled.c b/drivers/qwiic/micro_oled.c deleted file mode 100644 index 8dfff6968f..0000000000 --- a/drivers/qwiic/micro_oled.c +++ /dev/null @@ -1,482 +0,0 @@ -/* Jim Lindblom @ SparkFun Electronics - * October 26, 2014 - * https://github.com/sparkfun/Micro_OLED_Breakout/tree/master/Firmware/Arduino/libraries/SFE_MicroOLED - * - * Modified by: - * Emil Varughese @ Edwin Robotics Pvt. Ltd. - * July 27, 2015 - * https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/ - * - * This code was heavily based around the MicroView library, written by GeekAmmo - * (https://github.com/geekammo/MicroView-Arduino-Library). - * - * Adapted for QMK by: - * Jack Humbert <jack.humb@gmail.com> - * October 11, 2018 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#include "micro_oled.h" -#include "print.h" -#include <stdlib.h> -#include "util/font5x7.h" -#include "util/font8x16.h" -#include <string.h> - -#define TOTALFONTS 2 -const unsigned char* fonts_pointer[] = {font5x7, font8x16}; - -uint8_t  foreColor, drawMode, fontWidth, fontHeight, fontType, fontStartChar, fontTotalChar, cursorX, cursorY; -uint16_t fontMapWidth; - -#ifndef _BV -#    define _BV(x) (1 << (x)) -#endif - -#define swap(a, b)     \ -    {                  \ -        uint8_t t = a; \ -        a         = b; \ -        b         = t; \ -    } - -uint8_t        micro_oled_transfer_buffer[20]; -static uint8_t micro_oled_screen_current[LCDWIDTH * LCDHEIGHT / 8] = {0}; - -/* LCD Memory organised in 64 horizontal pixel and 6 rows of byte -   B  B .............B  ----- -   y  y .............y        \ -   t  t .............t         \ -   e  e .............e          \ -   0  1 .............63          \ -                                  \ -   D0 D0.............D0            \ -   D1 D1.............D1            / ROW 0 -   D2 D2.............D2           / -   D3 D3.............D3          / -   D4 D4.............D4         / -   D5 D5.............D5        / -   D6 D6.............D6       / -   D7 D7.............D7  ---- -  */ -#ifdef NO_LCD_SPLASH -// do not initialize with a splash screen -static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDHEIGHT / 8] = {0}; -#else -#    if LCDWIDTH == 64 -#        if LCDHEIGHT == 48 -static uint8_t micro_oled_screen_buffer[] = { -    // QMK Logo - generated at http://www.majer.ch/lcd/adf_bitmap.php -    // 64x48 image -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0xF8, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xF8, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x8C, 0x8C, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8C, 0x8C, 0x8C, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0xF1, 0xE3, 0xE7, 0xCF, 0xCF, 0xCF, 0xCF, 0x00, 0x00, 0xCF, 0xCF, 0xCF, 0xC7, 0xE7, 0xE3, 0xF1, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x31, 0x31, 0x31, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x1F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x1F, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -#        endif -#    elif LCDWIDTH == 128 -#        if LCDHEIGHT == 32 -static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDHEIGHT / 8] = { -    // 128x32 qmk image -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xFC, 0xFC, 0xE0, 0xFC, 0xFC, 0xE0, 0xF0, 0xFC, 0xE0, 0xE0, 0xFC, 0xE0, 0xE0, 0xFC, 0xFC, 0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0x10, 0x30, 0xE0, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xB2, 0xB2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, 0x03, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0xB2, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x02, 0x02, 0x03, 0x01, 0x00, 0x06, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x06, 0x00, 0x03, 0x1E, 0x18, 0x0F, 0x01, 0x0F, 0x18, 0x1E, 0x01, 0x00, 0x0F, 0x1F, 0x12, 0x02, 0x12, 0x13, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x1F, 0x12, 0x02, 0x12, 0x13, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x4D, 0x4D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xF9, 0xF3, 0xF3, 0xC0, 0x80, 0xF3, 0xF3, 0xF3, 0xF9, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, 0x4D, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0xC0, 0x00, 0x70, 0xC0, 0x00, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x1C, 0xF0, 0x00, 0x00, 0xFC, 0x0C, 0x38, 0xE0, 0x00, 0x00, 0xC0, 0x38, 0x0C, 0xFC, 0x00, 0x00, 0xFC, 0xFC, 0x60, 0x90, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x3F, 0x3F, 0x07, 0x3F, 0x3F, 0x07, 0x0F, 0x3F, 0x07, 0x07, 0x3F, 0x07, 0x07, 0x3F, 0x3F, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x06, 0x04, 0x04, 0x07, 0x01, 0x00, 0x00, 0x13, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x04, 0x04, 0x04, 0x04, 0x07, 0x0D, 0x08, 0x00, 0x07, 0x00, 0x00, 0x01, 0x07, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, 0x01, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -#        elif LCDHEIGHT == 64 -static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDHEIGHT / 8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0xFE, 0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7F, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0xFC, 0xFC, 0xF8, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDD, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xF0, 0xF3, 0xF3, 0xE7, 0xE7, 0x00, 0x00, 0xE7, 0xE7, 0xF3, 0xF3, 0xF0, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x1F, 0x3F, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x80, 0x03, 0x03, 0x00, 0x00, 0x01, 0x03, 0x00, 0x80, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x70, 0x88, 0x04, 0x04, 0x04, 0xF8, 0x00, 0x00, 0x3C, 0xE0, 0xC0, 0x38, 0x1C, 0xE0, 0x80, 0x70, 0x0C, 0x00, 0xF8, 0xAC, 0x24, 0x24, 0x3C, 0x30, 0x00, 0x00, 0xFC, 0x0C, 0x04, 0x00, 0xF8, 0xAC, 0x24, 0x24, 0x2C, 0x30, 0x00, 0x70, 0xDC, 0x04, 0x04, 0x88, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x8C, 0x04, 0x04, 0xF8, 0x00, 0x04, 0x3C, 0xE0, 0x80, 0xF0, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x83, 0x01, 0x01, 0x01, 0x81, 0xFE, 0x3C, 0x00, 0x00, 0xFF, 0x03, 0x0E, 0x70, 0xC0, 0xE0, 0x38, 0x06, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0x18, 0x38, 0x66, 0xC3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -                                                                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -// TODO: generate bitmap of QMK logo here -#        endif -#    else -// catchall for custom screen sizes -static uint8_t micro_oled_screen_buffer[LCDWIDTH * LCDHEIGHT / 8] = {0}; -#    endif -#endif - -void micro_oled_init(void) { -    i2c_init(); - -#ifdef __AVR__ -    i2c_start(I2C_ADDRESS_SA0_1, 100); -#else -    i2c_start(I2C_ADDRESS_SA0_1); -#endif - -    // Display Init sequence for 64x48 OLED module -    send_command(DISPLAYOFF);  // 0xAE - -    send_command(SETDISPLAYCLOCKDIV);  // 0xD5 -    send_command(0x80);                // the suggested ratio 0x80 - -    send_command(SETMULTIPLEX);  // 0xA8 -    send_command(LCDHEIGHT - 1); - -    send_command(SETDISPLAYOFFSET);  // 0xD3 -    send_command(0x00);              // no offset - -    send_command(SETSTARTLINE | 0x00);  // line #0 - -    send_command(CHARGEPUMP);  // enable charge pump -    send_command(0x14); - -    send_command(NORMALDISPLAY);       // 0xA6 -    send_command(DISPLAYALLONRESUME);  // 0xA4 - -    // display at regular orientation -    send_command(SEGREMAP | 0x1); -    send_command(COMSCANDEC); - -// rotate display 180 -#ifdef micro_oled_rotate_180 -    send_command(SEGREMAP); -    send_command(COMSCANINC); -#endif - -    send_command(MEMORYMODE); -    send_command(0x02);   //  0x02 = 10b, Page addressing mode - -    send_command(SETCOMPINS);  // 0xDA -    if (LCDHEIGHT > 32) { -        send_command(0x12); -    } else { -        send_command(0x02); -    } -    send_command(SETCONTRAST);  // 0x81 -    send_command(0x8F); - -    send_command(SETPRECHARGE);  // 0xd9 -    send_command(0xF1); - -    send_command(SETVCOMDESELECT);  // 0xDB -    send_command(0x40); - -    send_command(DISPLAYON);  //--turn on oled panel -    clear_screen();           // Erase hardware memory inside the OLED controller to avoid random data in memory. -    send_buffer(); -} - -void send_command(uint8_t command) { -    micro_oled_transfer_buffer[0] = I2C_COMMAND; -    micro_oled_transfer_buffer[1] = command; -    i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100); -} - -void send_data(uint8_t data) { -    micro_oled_transfer_buffer[0] = I2C_DATA; -    micro_oled_transfer_buffer[1] = data; -    i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100); -} - -/** \brief Set SSD1306 page address. -    Send page address command and address to the SSD1306 OLED controller. -*/ -void set_page_address(uint8_t address) { -    address = (0xB0 | address); -    send_command(address); -} - -/** \brief Set SSD1306 column address. -    Send column address command and address to the SSD1306 OLED controller. -*/ -void set_column_address(uint8_t address) { -    send_command((0x10 | (address >> 4)) + ((128 - LCDWIDTH) >> 8)); -    send_command(0x0F & address); -} - -/** \brief Clear SSD1306's memory. -    To clear GDRAM inside the LCD controller. -*/ -void clear_screen(void) { -    for (int i = 0; i < 8; i++) { -        set_page_address(i); -        set_column_address(0); -        for (int j = 0; j < 0x80; j++) { -            send_data(0); -        } -    } - -    memset(micro_oled_screen_current, 0, LCDWIDTH * LCDHEIGHT / 8); -} - -/** \brief Clear SSD1306's memory. -    To clear GDRAM inside the LCD controller. -*/ -void clear_buffer(void) { -    // 384 -    memset(micro_oled_screen_buffer, 0, LCDWIDTH * LCDHEIGHT / 8); -} - -/** \brief Invert display. -    The PIXEL_ON color of the display will turn to PIXEL_OFF and the PIXEL_OFF will turn to PIXEL_ON. -*/ -void invert_screen(bool invert) { -    if (invert) { -        send_command(INVERTDISPLAY); -    } else { -        send_command(NORMALDISPLAY); -    } -} - -/** \brief Set contrast. -    OLED contract value from 0 to 255. Note: Contrast level is not very obvious. -*/ -void set_contrast(uint8_t contrast) { -    send_command(SETCONTRAST);  // 0x81 -    send_command(contrast); -} - -/** \brief Transfer display buffer. -  Sends the updated buffer to the controller - the current status is checked before to save i2c exectution time -*/ -void send_buffer(void) { -    uint8_t i, j; - -    uint8_t page_addr = 0xFF; -    for (i = 0; i < LCDHEIGHT / 8; i++) { -        uint8_t col_addr = 0xFF; -        for (j = 0; j < LCDWIDTH; j++) { -            if (micro_oled_screen_buffer[i * LCDWIDTH + j] != micro_oled_screen_current[i * LCDWIDTH + j]) { -                if (page_addr != i) { -                    set_page_address(i); -                    page_addr = i; -                } -                if (col_addr != j) { -                    set_column_address(j); -                    col_addr = j + 1; -                } -                send_data(micro_oled_screen_buffer[i * LCDWIDTH + j]); -                micro_oled_screen_current[i * LCDWIDTH + j] = micro_oled_screen_buffer[i * LCDWIDTH + j]; -            } -        } -    } -} - -/** \brief Draw pixel with color and mode. -  Draw color pixel in the screen buffer's x,y position with NORM or XOR draw mode. -*/ -void draw_pixel(uint8_t x, uint8_t y, uint8_t color, uint8_t mode) { -    if ((x < 0) || (x >= LCDWIDTH) || (y < 0) || (y >= LCDHEIGHT)) return; - -    if (mode == XOR) { -        if (color == PIXEL_ON) micro_oled_screen_buffer[x + (y / 8) * LCDWIDTH] ^= _BV((y % 8)); -    } else { -        if (color == PIXEL_ON) -            micro_oled_screen_buffer[x + (y / 8) * LCDWIDTH] |= _BV((y % 8)); -        else -            micro_oled_screen_buffer[x + (y / 8) * LCDWIDTH] &= ~_BV((y % 8)); -    } -} - -/** \brief Draw line with color and mode. -Draw line using color and mode from x0,y0 to x1,y1 of the screen buffer. -*/ -void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color, uint8_t mode) { -    uint8_t steep = abs(y1 - y0) > abs(x1 - x0); -    if (steep) { -        swap(x0, y0); -        swap(x1, y1); -    } - -    if (x0 > x1) { -        swap(x0, x1); -        swap(y0, y1); -    } - -    uint8_t dx, dy; -    dx = x1 - x0; -    dy = abs(y1 - y0); - -    int8_t err = dx / 2; -    int8_t ystep; - -    if (y0 < y1) { -        ystep = 1; -    } else { -        ystep = -1; -    } - -    for (; x0 < x1; x0++) { -        if (steep) { -            draw_pixel(y0, x0, color, mode); -        } else { -            draw_pixel(x0, y0, color, mode); -        } -        err -= dy; -        if (err < 0) { -            y0 += ystep; -            err += dx; -        } -    } -} - -/** \brief Draw horizontal line with color and mode. -Draw horizontal line using color and mode from x,y to x+width,y of the screen buffer. -*/ -void draw_line_hori(uint8_t x, uint8_t y, uint8_t width, uint8_t color, uint8_t mode) { draw_line(x, y, x + width, y, color, mode); } - -/** \brief Draw vertical line. -Draw vertical line using current fore color and current draw mode from x,y to x,y+height of the screen buffer. -*/ -void draw_line_vert(uint8_t x, uint8_t y, uint8_t height, bool color, uint8_t mode) { draw_line(x, y, x, y + height, color, mode); } - -/** \brief Draw rectangle with color and mode. -Draw rectangle using color and mode from x,y to x+width,y+height of the screen buffer. -*/ -void draw_rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) { -    uint8_t tempHeight; - -    draw_line_hori(x, y, width, color, mode); -    draw_line_hori(x, y + height - 1, width, color, mode); - -    tempHeight = height - 2; - -    // skip drawing vertical lines to avoid overlapping of pixel that will -    // affect XOR plot if no pixel in between horizontal lines -    if (tempHeight < 1) return; - -    draw_line_vert(x, y + 1, tempHeight, color, mode); -    draw_line_vert(x + width - 1, y + 1, tempHeight, color, mode); -} - -/** \brief Draw rectangle with color and mode. -Draw rectangle using color and mode from x,y to x+width,y+height of the screen buffer. -*/ -void draw_rect_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) { -    uint8_t tempHeight; - -    draw_line_hori(x + 1, y, width - 2, color, mode); -    draw_line_hori(x + 1, y + height - 1, width - 2, color, mode); - -    tempHeight = height - 2; - -    // skip drawing vertical lines to avoid overlapping of pixel that will -    // affect XOR plot if no pixel in between horizontal lines -    if (tempHeight < 1) return; - -    draw_line_vert(x, y + 1, tempHeight, color, mode); -    draw_line_vert(x + width - 1, y + 1, tempHeight, color, mode); -} - -/** \brief Draw filled rectangle with color and mode. -Draw filled rectangle using color and mode from x,y to x+width,y+height of the screen buffer. -*/ -void draw_rect_filled(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) { -    // TODO - need to optimise the memory map draw so that this function will not call pixel one by one -    for (int i = x; i < x + width; i++) { -        draw_line_vert(i, y, height, color, mode); -    } -} - -/** \brief Draw filled rectangle with color and mode. -Draw filled rectangle using color and mode from x,y to x+width,y+height of the screen buffer. -*/ -void draw_rect_filled_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode) { -    // TODO - need to optimise the memory map draw so that this function will not call pixel one by one -    for (int i = x; i < x + width; i++) { -        if (i == x || i == (x + width - 1)) -            draw_line_vert(i, y + 1, height - 2, color, mode); -        else -            draw_line_vert(i, y, height, color, mode); -    } -} - -/** \brief Draw character with color and mode. -  Draw character c using color and draw mode at x,y. -*/ -void draw_char(uint8_t x, uint8_t y, uint8_t c, uint8_t color, uint8_t mode, uint8_t font) { -    // TODO - New routine to take font of any height, at the moment limited to font height in multiple of 8 pixels - -    uint8_t  rowsToDraw, row, tempC; -    uint8_t  i, j, temp; -    uint16_t charPerBitmapRow, charColPositionOnBitmap, charRowPositionOnBitmap, charBitmapStartPosition; - -    if ((font >= TOTALFONTS) || (font < 0)) return; - -    uint8_t  fontType      = font; -    uint8_t  fontWidth     = pgm_read_byte(fonts_pointer[fontType] + 0); -    uint8_t  fontHeight    = pgm_read_byte(fonts_pointer[fontType] + 1); -    uint8_t  fontStartChar = pgm_read_byte(fonts_pointer[fontType] + 2); -    uint8_t  fontTotalChar = pgm_read_byte(fonts_pointer[fontType] + 3); -    uint16_t fontMapWidth  = (pgm_read_byte(fonts_pointer[fontType] + 4) * 100) + pgm_read_byte(fonts_pointer[fontType] + 5);  // two bytes values into integer 16 - -    if ((c < fontStartChar) || (c > (fontStartChar + fontTotalChar - 1)))  // no bitmap for the required c -        return; - -    tempC = c - fontStartChar; - -    // each row (in datasheet is call page) is 8 bits high, 16 bit high character will have 2 rows to be drawn -    rowsToDraw = fontHeight / 8;  // 8 is LCD's page size, see SSD1306 datasheet -    if (rowsToDraw <= 1) rowsToDraw = 1; - -    // the following draw function can draw anywhere on the screen, but SLOW pixel by pixel draw -    if (rowsToDraw == 1) { -        for (i = 0; i < fontWidth + 1; i++) { -            if (i == fontWidth)  // this is done in a weird way because for 5x7 font, there is no margin, this code add a margin after col 5 -                temp = 0; -            else -                temp = pgm_read_byte(fonts_pointer[fontType] + FONTHEADERSIZE + (tempC * fontWidth) + i); - -            for (j = 0; j < 8; j++) {  // 8 is the LCD's page height (see datasheet for explanation) -                if (temp & 0x1) { -                    draw_pixel(x + i, y + j, color, mode); -                } else { -                    draw_pixel(x + i, y + j, !color, mode); -                } - -                temp >>= 1; -            } -        } -        return; -    } - -    // font height over 8 bit -    // take character "0" ASCII 48 as example -    charPerBitmapRow        = fontMapWidth / fontWidth;         // 256/8 =32 char per row -    charColPositionOnBitmap = tempC % charPerBitmapRow;         // =16 -    charRowPositionOnBitmap = (int)(tempC / charPerBitmapRow);  // =1 -    charBitmapStartPosition = (charRowPositionOnBitmap * fontMapWidth * (fontHeight / 8)) + (charColPositionOnBitmap * fontWidth); - -    // each row on LCD is 8 bit height (see datasheet for explanation) -    for (row = 0; row < rowsToDraw; row++) { -        for (i = 0; i < fontWidth; i++) { -            temp = pgm_read_byte(fonts_pointer[fontType] + FONTHEADERSIZE + (charBitmapStartPosition + i + (row * fontMapWidth))); -            for (j = 0; j < 8; j++) {  // 8 is the LCD's page height (see datasheet for explanation) -                if (temp & 0x1) { -                    draw_pixel(x + i, y + j + (row * 8), color, mode); -                } else { -                    draw_pixel(x + i, y + j + (row * 8), !color, mode); -                } -                temp >>= 1; -            } -        } -    } -} - -void draw_string(uint8_t x, uint8_t y, char* string, uint8_t color, uint8_t mode, uint8_t font) { -    if ((font >= TOTALFONTS) || (font < 0)) return; - -    uint8_t fontType  = font; -    uint8_t fontWidth = pgm_read_byte(fonts_pointer[fontType] + 0); - -    uint8_t cur_x = x; -    for (int i = 0; i < strlen(string); i++) { -        draw_char(cur_x, y, string[i], color, mode, font); -        cur_x += fontWidth + 1; -    } -} diff --git a/drivers/qwiic/micro_oled.h b/drivers/qwiic/micro_oled.h deleted file mode 100644 index 6f9106f581..0000000000 --- a/drivers/qwiic/micro_oled.h +++ /dev/null @@ -1,134 +0,0 @@ -/* Jim Lindblom @ SparkFun Electronics - * October 26, 2014 - * https://github.com/sparkfun/Micro_OLED_Breakout/tree/master/Firmware/Arduino/libraries/SFE_MicroOLED - * - * Modified by: - * Emil Varughese @ Edwin Robotics Pvt. Ltd. - * July 27, 2015 - * https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/ - * - * This code was heavily based around the MicroView library, written by GeekAmmo - * (https://github.com/geekammo/MicroView-Arduino-Library). - * - * Adapted for QMK by: - * Jack Humbert <jack.humb@gmail.com> - * October 11, 2018 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#pragma once - -#include "qwiic.h" - -void micro_oled_init(void); - -void send_command(uint8_t command); -void send_data(uint8_t data); -void set_page_address(uint8_t address); -void set_column_address(uint8_t address); -void clear_screen(void); -void clear_buffer(void); -void send_buffer(void); -void draw_pixel(uint8_t x, uint8_t y, uint8_t color, uint8_t mode); -void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color, uint8_t mode); -void draw_line_hori(uint8_t x, uint8_t y, uint8_t width, uint8_t color, uint8_t mode); -void draw_line_vert(uint8_t x, uint8_t y, uint8_t height, bool color, uint8_t mode); -void draw_rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode); -void draw_rect_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode); -void draw_rect_filled(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode); -void draw_rect_filled_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode); -void draw_char(uint8_t x, uint8_t y, uint8_t c, uint8_t color, uint8_t mode, uint8_t font); -void draw_string(uint8_t x, uint8_t y, char* string, uint8_t color, uint8_t mode, uint8_t font); - -#define I2C_ADDRESS_SA0_0 0b0111100 -#ifndef I2C_ADDRESS_SA0_1 -#    define I2C_ADDRESS_SA0_1 0b0111101 -#endif -#define I2C_COMMAND 0x00 -#define I2C_DATA 0x40 -#define PIXEL_OFF 0 -#define PIXEL_ON 1 - -#ifndef LCDWIDTH -#    define LCDWIDTH 64 -#endif -#ifndef LCDHEIGHT -#    define LCDHEIGHT 48 -#endif -#define FONTHEADERSIZE 6 - -#define NORM 0 -#define XOR 1 - -#define PAGE 0 -#define ALL 1 - -#define WIDGETSTYLE0 0 -#define WIDGETSTYLE1 1 -#define WIDGETSTYLE2 2 - -#define SETCONTRAST 0x81 -#define DISPLAYALLONRESUME 0xA4 -#define DISPLAYALLON 0xA5 -#define NORMALDISPLAY 0xA6 -#define INVERTDISPLAY 0xA7 -#define DISPLAYOFF 0xAE -#define DISPLAYON 0xAF -#define SETDISPLAYOFFSET 0xD3 -#define SETCOMPINS 0xDA -#define SETVCOMDESELECT 0xDB -#define SETDISPLAYCLOCKDIV 0xD5 -#define SETPRECHARGE 0xD9 -#define SETMULTIPLEX 0xA8 -#define SETLOWCOLUMN 0x00 -#define SETHIGHCOLUMN 0x10 -#define SETSTARTLINE 0x40 -#define MEMORYMODE 0x20 -#define COMSCANINC 0xC0 -#define COMSCANDEC 0xC8 -#define SEGREMAP 0xA0 -#define CHARGEPUMP 0x8D -#define EXTERNALVCC 0x01 -#define SWITCHCAPVCC 0x02 - -// Scroll -#define ACTIVATESCROLL 0x2F -#define DEACTIVATESCROLL 0x2E -#define SETVERTICALSCROLLAREA 0xA3 -#define RIGHTHORIZONTALSCROLL 0x26 -#define LEFT_HORIZONTALSCROLL 0x27 -#define VERTICALRIGHTHORIZONTALSCROLL 0x29 -#define VERTICALLEFTHORIZONTALSCROLL 0x2A - -typedef enum CMD { -    CMD_CLEAR,         // 0 -    CMD_INVERT,        // 1 -    CMD_CONTRAST,      // 2 -    CMD_DISPLAY,       // 3 -    CMD_SETCURSOR,     // 4 -    CMD_PIXEL,         // 5 -    CMD_LINE,          // 6 -    CMD_LINEH,         // 7 -    CMD_LINEV,         // 8 -    CMD_RECT,          // 9 -    CMD_RECTFILL,      // 10 -    CMD_CIRCLE,        // 11 -    CMD_CIRCLEFILL,    // 12 -    CMD_DRAWCHAR,      // 13 -    CMD_DRAWBITMAP,    // 14 -    CMD_GETLCDWIDTH,   // 15 -    CMD_GETLCDHEIGHT,  // 16 -    CMD_SETCOLOR,      // 17 -    CMD_SETDRAWMODE    // 18 -} commCommand_t; diff --git a/drivers/qwiic/qwiic.c b/drivers/qwiic/qwiic.c deleted file mode 100644 index 316d6539cb..0000000000 --- a/drivers/qwiic/qwiic.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright 2018 Jack Humbert <jack.humb@gmail.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#include "qwiic.h" - -void qwiic_init(void) { -#ifdef QWIIC_JOYSTIIC_ENABLE -    joystiic_init(); -#endif -#ifdef QWIIC_MICRO_OLED_ENABLE -    micro_oled_init(); -#endif -} - -void qwiic_task(void) { -#ifdef QWIIC_JOYSTIIC_ENABLE -    joystiic_task(); -#endif -} diff --git a/drivers/qwiic/qwiic.h b/drivers/qwiic/qwiic.h deleted file mode 100644 index 8c3d1c8d63..0000000000 --- a/drivers/qwiic/qwiic.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2018 Jack Humbert <jack.humb@gmail.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#pragma once - -#include "i2c_master.h" - -#ifdef QWIIC_JOYSTIIC_ENABLE -#    include "joystiic.h" -#endif -#ifdef QWIIC_MICRO_OLED_ENABLE -#    include "micro_oled.h" -#endif - -void qwiic_init(void); -void qwiic_task(void); diff --git a/drivers/qwiic/qwiic.mk b/drivers/qwiic/qwiic.mk deleted file mode 100644 index 164bd72108..0000000000 --- a/drivers/qwiic/qwiic.mk +++ /dev/null @@ -1,17 +0,0 @@ -ifeq ($(strip $(QWIIC_ENABLE)),yes) -  COMMON_VPATH += $(DRIVER_PATH)/qwiic -  OPT_DEFS += -DQWIIC_ENABLE -  SRC += qwiic.c -  QUANTUM_LIB_SRC += i2c_master.c - -ifneq ($(filter JOYSTIIC, $(QWIIC_DRIVERS)),) -  OPT_DEFS += -DQWIIC_JOYSTIIC_ENABLE -  SRC += joystiic.c -endif - -ifneq ($(filter MICRO_OLED, $(QWIIC_DRIVERS)),) -  OPT_DEFS += -DQWIIC_MICRO_OLED_ENABLE -  SRC += micro_oled.c -endif - -endif diff --git a/drivers/qwiic/util/font5x7.h b/drivers/qwiic/util/font5x7.h deleted file mode 100644 index a641945aae..0000000000 --- a/drivers/qwiic/util/font5x7.h +++ /dev/null @@ -1,39 +0,0 @@ -/****************************************************************************** -font5x7.h -Definition for small font - -This file was imported from the MicroView library, written by GeekAmmo -(https://github.com/geekammo/MicroView-Arduino-Library), and released under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. - -Modified by: -Emil Varughese @ Edwin Robotics Pvt. Ltd. -July 27, 2015 -https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/ - -******************************************************************************/ -#pragma once - -#include "progmem.h" - -// Standard ASCII 5x7 font -static const unsigned char font5x7[] PROGMEM = { -    // first row defines - FONTWIDTH, FONTHEIGHT, ASCII START CHAR, TOTAL CHARACTERS, FONT MAP WIDTH HIGH, FONT MAP WIDTH LOW (2,56 meaning 256) -    5,    8,    0,    255,  12,   75,   0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, 0x18, 0x3C, 0x18, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x18, 0x24, 0x18, 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x26, 0x29, 0x79, 0x29, 0x26, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, 0x66, 0x89, 0x95, 0x6A, 0x60, 0x60, 0x60, 0x60, 0x60, 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x08, 0x04, 0x7E, 0x04, 0x08, 0x10, 0x20, 0x7E, 0x20, 0x10, 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x30, 0x38, 0x3E, 0x38, 0x30, -    0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x23, 0x13, 0x08, 0x64, 0x62, 0x36, 0x49, 0x56, 0x20, 0x50, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x80, 0x70, 0x30, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x60, 0x60, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x72, 0x49, 0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x27, 0x45, 0x45, 0x45, 0x39, 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x41, 0x21, 0x11, 0x09, 0x07, 0x36, 0x49, 0x49, 0x49, 0x36, 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x41, 0x22, 0x14, 0x08, 0x02, -    0x01, 0x59, 0x09, 0x06, 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x3E, 0x41, 0x41, 0x51, 0x73, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x26, 0x49, 0x49, 0x49, 0x32, 0x03, 0x01, 0x7F, 0x01, 0x03, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x63, 0x14, 0x08, 0x14, 0x63, 0x03, 0x04, 0x78, 0x04, 0x03, 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x41, 0x41, 0x41, 0x7F, 0x04, 0x02, 0x01, 0x02, 0x04, 0x40, 0x40, -    0x40, 0x40, 0x40, 0x00, 0x03, 0x07, 0x08, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40, 0x7F, 0x28, 0x44, 0x44, 0x38, 0x38, 0x44, 0x44, 0x44, 0x28, 0x38, 0x44, 0x44, 0x28, 0x7F, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x08, 0x7E, 0x09, 0x02, 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7D, 0x40, 0x00, 0x20, 0x40, 0x40, 0x3D, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x7C, 0x08, 0x04, 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, 0xFC, 0x18, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x18, 0xFC, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x48, 0x54, 0x54, 0x54, 0x24, 0x04, 0x04, 0x3F, 0x44, 0x24, 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x44, 0x28, 0x10, 0x28, 0x44, 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x3C, 0x26, 0x23, -    0x26, 0x3C, 0x1E, 0xA1, 0xA1, 0x61, 0x12, 0x3A, 0x40, 0x40, 0x20, 0x7A, 0x38, 0x54, 0x54, 0x55, 0x59, 0x21, 0x55, 0x55, 0x79, 0x41, 0x21, 0x54, 0x54, 0x78, 0x41, 0x21, 0x55, 0x54, 0x78, 0x40, 0x20, 0x54, 0x55, 0x79, 0x40, 0x0C, 0x1E, 0x52, 0x72, 0x12, 0x39, 0x55, 0x55, 0x55, 0x59, 0x39, 0x54, 0x54, 0x54, 0x59, 0x39, 0x55, 0x54, 0x54, 0x58, 0x00, 0x00, 0x45, 0x7C, 0x41, 0x00, 0x02, 0x45, 0x7D, 0x42, 0x00, 0x01, 0x45, 0x7C, 0x40, 0xF0, 0x29, 0x24, 0x29, 0xF0, 0xF0, 0x28, 0x25, 0x28, 0xF0, 0x7C, 0x54, 0x55, 0x45, 0x00, 0x20, 0x54, 0x54, 0x7C, 0x54, 0x7C, 0x0A, 0x09, 0x7F, 0x49, 0x32, 0x49, 0x49, 0x49, 0x32, 0x32, 0x48, 0x48, 0x48, 0x32, 0x32, 0x4A, 0x48, 0x48, 0x30, 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x3A, 0x42, 0x40, 0x20, 0x78, 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0x39, 0x44, 0x44, 0x44, 0x39, 0x3D, 0x40, 0x40, 0x40, 0x3D, 0x3C, 0x24, 0xFF, 0x24, 0x24, 0x48, 0x7E, 0x49, 0x43, 0x66, 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 0xFF, 0x09, 0x29, 0xF6, 0x20, 0xC0, 0x88, 0x7E, 0x09, -    0x03, 0x20, 0x54, 0x54, 0x79, 0x41, 0x00, 0x00, 0x44, 0x7D, 0x41, 0x30, 0x48, 0x48, 0x4A, 0x32, 0x38, 0x40, 0x40, 0x22, 0x7A, 0x00, 0x7A, 0x0A, 0x0A, 0x72, 0x7D, 0x0D, 0x19, 0x31, 0x7D, 0x26, 0x29, 0x29, 0x2F, 0x28, 0x26, 0x29, 0x29, 0x29, 0x26, 0x30, 0x48, 0x4D, 0x40, 0x20, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 0x2F, 0x10, 0x28, 0x34, 0xFA, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x08, 0x14, 0x2A, 0x14, 0x22, 0x22, 0x14, 0x2A, 0x14, 0x08, 0xAA, 0x00, 0x55, 0x00, 0xAA, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x14, 0x14, 0x14, 0xFF, 0x00, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x14, 0x14, 0x17, 0x10, 0x1F, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0x1F, 0x00, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, -    0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xFF, 0x14, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0x10, 0x17, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, 0x14, 0xF4, 0x04, 0xF4, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x17, 0x14, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0xF4, 0x14, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x14, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x00, 0x00, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0xFF, 0x10, 0xFF, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x38, 0x44, 0x44, 0x38, 0x44, 0x7C, -    0x2A, 0x2A, 0x3E, 0x14, 0x7E, 0x02, 0x02, 0x06, 0x06, 0x02, 0x7E, 0x02, 0x7E, 0x02, 0x63, 0x55, 0x49, 0x41, 0x63, 0x38, 0x44, 0x44, 0x3C, 0x04, 0x40, 0x7E, 0x20, 0x1E, 0x20, 0x06, 0x02, 0x7E, 0x02, 0x02, 0x99, 0xA5, 0xE7, 0xA5, 0x99, 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 0x4C, 0x72, 0x01, 0x72, 0x4C, 0x30, 0x4A, 0x4D, 0x4D, 0x30, 0x30, 0x48, 0x78, 0x48, 0x30, 0xBC, 0x62, 0x5A, 0x46, 0x3D, 0x3E, 0x49, 0x49, 0x49, 0x00, 0x7E, 0x01, 0x01, 0x01, 0x7E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x44, 0x44, 0x5F, 0x44, 0x44, 0x40, 0x51, 0x4A, 0x44, 0x40, 0x40, 0x44, 0x4A, 0x51, 0x40, 0x00, 0x00, 0xFF, 0x01, 0x03, 0xE0, 0x80, 0xFF, 0x00, 0x00, 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x36, 0x12, 0x36, 0x24, 0x36, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x40, 0xFF, 0x01, 0x01, 0x00, 0x1F, 0x01, 0x01, 0x1E, 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/drivers/qwiic/util/font8x16.h b/drivers/qwiic/util/font8x16.h deleted file mode 100644 index 4d3c237866..0000000000 --- a/drivers/qwiic/util/font8x16.h +++ /dev/null @@ -1,39 +0,0 @@ -/****************************************************************************** -font8x16.h -Definition for medium font - -This file was imported from the MicroView library, written by GeekAmmo -(https://github.com/geekammo/MicroView-Arduino-Library), and released under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. - -Modified by: -Emil Varughese @ Edwin Robotics Pvt. Ltd. -July 27, 2015 -https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/ -******************************************************************************/ -#pragma once - -#include "progmem.h" - -static const unsigned char font8x16[] PROGMEM = { -    // first row defines - FONTWIDTH, FONTHEIGHT, ASCII START CHAR, TOTAL CHARACTERS, FONT MAP WIDTH HIGH, FONT MAP WIDTH LOW (2,56 meaning 256) -    8,    16,   32,   96,   2,    56,   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xBE, 0x90, 0xD0, 0xBE, 0x90, 0x00, 0x00, 0x1C, 0x62, 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x0C, 0x12, 0x92, 0x4C, 0xB0, 0x88, 0x06, 0x00, 0x80, 0x7C, 0x62, 0xB2, 0x1C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x24, 0x18, 0x7E, 0x18, 0x24, 0x00, 0x00, 0x80, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x06, 0x00, 0x00, 0xF8, 0x04, 0xC2, 0x32, 0x0C, 0xF8, 0x00, 0x00, 0x00, 0x04, 0x04, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x42, 0x22, -    0x1C, 0x00, 0x00, 0x00, 0x02, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, 0xC0, 0xA0, 0x98, 0x84, 0xFE, 0x80, 0x80, 0x00, 0x00, 0x1E, 0x12, 0x12, 0x22, 0xC2, 0x00, 0x00, 0xF8, 0x44, 0x22, 0x22, 0x22, 0xC0, 0x00, 0x00, 0x00, 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, 0x00, 0x8C, 0x52, 0x22, 0x52, 0x8C, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x26, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x02, 0x82, 0x42, 0x22, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x0F, 0x04, 0x03, 0x00, 0x00, 0x04, 0x02, 0x01, 0x03, 0x04, 0x04, 0x03, 0x00, -    0x03, 0x04, 0x04, 0x04, 0x05, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x08, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x04, 0x04, -    0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x04, 0x72, 0x8A, 0xFA, 0x84, 0x78, 0x00, 0x00, 0xC0, 0x38, 0x06, 0x38, 0xC0, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x22, 0xE2, 0x00, 0x00, 0xFE, 0x20, 0x20, 0x20, 0x20, 0xFE, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0xFE, 0x40, 0xB0, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0xFE, 0x0C, 0x70, 0x80, 0x70, 0x0C, 0xFE, 0x00, 0xFE, 0x0C, 0x30, 0xC0, 0x00, 0xFE, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0xFE, 0x42, 0x42, 0x42, 0x22, 0x1C, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x42, 0x42, 0xA2, 0x1C, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x42, 0x42, 0x80, 0x00, 0x00, 0x02, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x02, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x06, 0x38, 0xC0, 0x00, 0xC0, 0x38, 0x06, 0x00, 0x3E, 0xC0, 0xF0, 0x0E, 0xF0, 0xC0, 0x3E, 0x00, 0x00, 0x06, 0x98, 0x60, 0x98, 0x06, 0x00, 0x00, 0x00, 0x06, 0x18, 0xE0, 0x18, 0x06, 0x00, 0x00, 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x06, 0x18, 0x60, 0x80, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x40, 0x30, 0x0C, 0x0C, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -    0x02, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0C, 0x12, 0x11, 0x10, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, -    0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xFE, 0x00, 0x00, 0x00, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x00, 0x00, 0x00, 0x20, 0xFC, 0x22, 0x22, 0x22, 0x02, -    0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x80, 0x40, 0x20, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0xF0, 0x20, 0x10, 0xF0, 0x00, 0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0x10, 0x70, 0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x20, 0x00, 0x00, 0x00, 0x20, 0x20, 0xFC, 0x20, 0x20, 0x20, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x80, 0x70, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0x30, 0xC0, 0x00, 0xF0, 0x00, 0x00, 0x30, 0xC0, 0xC0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x80, 0x70, 0x00, 0x00, 0x00, 0x10, -    0x10, 0x90, 0x50, 0x30, 0x00, 0x00, 0x00, 0x80, 0x80, 0x7E, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x7E, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x24, 0x24, 0x22, 0x1F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, -    0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x3F, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x3F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x03, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x01, 0x06, 0x01, 0x00, 0x00, 0x06, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x20, 0x20, 0x31, 0x0E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/drivers/ugfx/gdisp/is31fl3731c/board_is31fl3731c_template.h b/drivers/ugfx/gdisp/is31fl3731c/board_is31fl3731c_template.h deleted file mode 100644 index 0755ddf6c4..0000000000 --- a/drivers/ugfx/gdisp/is31fl3731c/board_is31fl3731c_template.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -Copyright 2016 Fred Sundvik <fsundvik@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _GDISP_LLD_BOARD_H -#define _GDISP_LLD_BOARD_H - -static const I2CConfig i2ccfg = { -    400000  // clock speed (Hz); 400kHz max for IS31 -}; - -static const uint8_t led_mask[] = { -    0xFF, 0x00, /* C1-1 -> C1-16 */ -    0xFF, 0x00, /* C2-1 -> C2-16 */ -    0xFF, 0x00, /* C3-1 -> C3-16 */ -    0xFF, 0x00, /* C4-1 -> C4-16 */ -    0x3F, 0x00, /* C5-1 -> C5-16 */ -    0x00, 0x00, /* C6-1 -> C6-16 */ -    0x00, 0x00, /* C7-1 -> C7-16 */ -    0x00, 0x00, /* C8-1 -> C8-16 */ -    0x00, 0x00, /* C9-1 -> C9-16 */ -}; - -// The address of the LED -#define LA(c, r) (c + r * 16) -// Need to be an address that is not mapped, but inside the range of the controller matrix -#define NA LA(8, 8) - -// The numbers in the comments are the led numbers DXX on the PCB -// The mapping is taken from the schematic of left hand side -static const uint8_t led_mapping[GDISP_SCREEN_HEIGHT][GDISP_SCREEN_WIDTH] = { -    //   45        44        43        42        41        40        39 -    {LA(1, 1), LA(1, 0), LA(0, 4), LA(0, 3), LA(0, 2), LA(0, 1), LA(0, 0)}, -    //   52        51        50        49        48        47        46 -    {LA(2, 3), LA(2, 2), LA(2, 1), LA(2, 0), LA(1, 4), LA(1, 3), LA(1, 2)}, -    //   58        57        56        55        54        53        N/A -    {LA(3, 4), LA(3, 3), LA(3, 2), LA(3, 1), LA(3, 0), LA(2, 4), NA}, -    //   67        66        65        64        63        62        61 -    {LA(5, 3), LA(5, 2), LA(5, 1), LA(5, 0), LA(4, 4), LA(4, 3), LA(4, 2)}, -    //   76        75        74        73        72        60        59 -    {LA(7, 3), LA(7, 2), LA(7, 1), LA(7, 0), LA(6, 3), LA(4, 1), LA(4, 0)}, -    //   N/A       N/A       N/A       N/A       N/A       N/A       68 -    {NA, NA, NA, NA, NA, NA, LA(5, 4)}, -    //   N/A       N/A       N/A       N/A       71        70        69 -    {NA, NA, NA, NA, LA(6, 2), LA(6, 1), LA(6, 0)}, -}; - -#define IS31_ADDR_DEFAULT 0x74  // AD connected to GND -#define IS31_TIMEOUT 5000 - -static GFXINLINE void init_board(GDisplay* g) { -    (void)g; -    /* I2C pins */ -    palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2);  // PTB0/I2C0/SCL -    palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATIVE_2);  // PTB1/I2C0/SDA -    palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL); -    palClearPad(GPIOB, 16); -    /* start I2C */ -    i2cStart(&I2CD1, &i2ccfg); -    // try high drive (from kiibohd) -    I2CD1.i2c->C2 |= I2Cx_C2_HDRS; -    // try glitch fixing (from kiibohd) -    I2CD1.i2c->FLT = 4; -} - -static GFXINLINE void post_init_board(GDisplay* g) { (void)g; } - -static GFXINLINE const uint8_t* get_led_mask(GDisplay* g) { -    (void)g; -    return led_mask; -} - -static GFXINLINE uint8_t get_led_address(GDisplay* g, uint16_t x, uint16_t y) { -    (void)g; -    return led_mapping[y][x]; -} - -static GFXINLINE void set_hardware_shutdown(GDisplay* g, bool shutdown) { -    (void)g; -    if (!shutdown) { -        palSetPad(GPIOB, 16); -    } else { -        palClearPad(GPIOB, 16); -    } -} - -static GFXINLINE void write_data(GDisplay* g, uint8_t* data, uint16_t length) { -    (void)g; -    i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, data, length, 0, 0, US2ST(IS31_TIMEOUT)); -} - -#endif /* _GDISP_LLD_BOARD_H */ diff --git a/drivers/ugfx/gdisp/is31fl3731c/driver.mk b/drivers/ugfx/gdisp/is31fl3731c/driver.mk deleted file mode 100644 index a53131bf33..0000000000 --- a/drivers/ugfx/gdisp/is31fl3731c/driver.mk +++ /dev/null @@ -1,3 +0,0 @@ -GFXINC += drivers/ugfx/gdisp/is31fl3731c -GFXSRC += drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c -GDISP_DRIVER_LIST += GDISPVMT_IS31FL3731C_QMK diff --git a/drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c b/drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c deleted file mode 100644 index 7188244022..0000000000 --- a/drivers/ugfx/gdisp/is31fl3731c/gdisp_is31fl3731c.c +++ /dev/null @@ -1,302 +0,0 @@ -/* -Copyright 2016 Fred Sundvik <fsundvik@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "gfx.h" - -#if GFX_USE_GDISP - -#    define GDISP_DRIVER_VMT GDISPVMT_IS31FL3731C_QMK -#    define GDISP_SCREEN_HEIGHT LED_HEIGHT -#    define GDISP_SCREEN_WIDTH LED_WIDTH - -#    include "gdisp_lld_config.h" -#    include "src/gdisp/gdisp_driver.h" - -#    include "board_is31fl3731c.h" - -// Can't include led_tables from here -extern const uint8_t CIE1931_CURVE[]; - -/*===========================================================================*/ -/* Driver local definitions.                                                 */ -/*===========================================================================*/ - -#    ifndef GDISP_INITIAL_CONTRAST -#        define GDISP_INITIAL_CONTRAST 0 -#    endif -#    ifndef GDISP_INITIAL_BACKLIGHT -#        define GDISP_INITIAL_BACKLIGHT 0 -#    endif - -#    define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) - -#    define IS31_ADDR_DEFAULT 0x74 - -#    define IS31_REG_CONFIG 0x00 -// bits in reg -#    define IS31_REG_CONFIG_PICTUREMODE 0x00 -#    define IS31_REG_CONFIG_AUTOPLAYMODE 0x08 -#    define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18 -// D2:D0 bits are starting frame for autoplay mode - -#    define IS31_REG_PICTDISP 0x01  // D2:D0 frame select for picture mode - -#    define IS31_REG_AUTOPLAYCTRL1 0x02 -// D6:D4 number of loops (000=infty) -// D2:D0 number of frames to be used - -#    define IS31_REG_AUTOPLAYCTRL2 0x03  // D5:D0 delay time (*11ms) - -#    define IS31_REG_DISPLAYOPT 0x05 -#    define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20  // same intensity for all frames -#    define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8 -// D2:D0 bits blink period time (*0.27s) - -#    define IS31_REG_AUDIOSYNC 0x06 -#    define IS31_REG_AUDIOSYNC_ENABLE 0x1 - -#    define IS31_REG_FRAMESTATE 0x07 - -#    define IS31_REG_BREATHCTRL1 0x08 -// D6:D4 fade out time (26ms*2^i) -// D2:D0 fade in time (26ms*2^i) - -#    define IS31_REG_BREATHCTRL2 0x09 -#    define IS31_REG_BREATHCTRL2_ENABLE 0x10 -// D2:D0 extinguish time (3.5ms*2^i) - -#    define IS31_REG_SHUTDOWN 0x0A -#    define IS31_REG_SHUTDOWN_OFF 0x0 -#    define IS31_REG_SHUTDOWN_ON 0x1 - -#    define IS31_REG_AGCCTRL 0x0B -#    define IS31_REG_ADCRATE 0x0C - -#    define IS31_COMMANDREGISTER 0xFD -#    define IS31_FUNCTIONREG 0x0B  // helpfully called 'page nine' -#    define IS31_FUNCTIONREG_SIZE 0xD - -#    define IS31_FRAME_SIZE 0xB4 - -#    define IS31_PWM_REG 0x24 -#    define IS31_PWM_SIZE 0x90 - -#    define IS31_LED_MASK_SIZE 0x12 - -#    define IS31 - -/*===========================================================================*/ -/* Driver local functions.                                                   */ -/*===========================================================================*/ - -typedef struct { -    uint8_t write_buffer_offset; -    uint8_t write_buffer[IS31_FRAME_SIZE]; -    uint8_t frame_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH]; -    uint8_t page; -} __attribute__((__packed__)) PrivData; - -// Some common routines and macros -#    define PRIV(g) ((PrivData *)g->priv) - -/*===========================================================================*/ -/* Driver exported functions.                                                */ -/*===========================================================================*/ - -static GFXINLINE void write_page(GDisplay *g, uint8_t page) { -    uint8_t tx[2] __attribute__((aligned(2))); -    tx[0] = IS31_COMMANDREGISTER; -    tx[1] = page; -    write_data(g, tx, 2); -} - -static GFXINLINE void write_register(GDisplay *g, uint8_t page, uint8_t reg, uint8_t data) { -    uint8_t tx[2] __attribute__((aligned(2))); -    tx[0] = reg; -    tx[1] = data; -    write_page(g, page); -    write_data(g, tx, 2); -} - -static GFXINLINE void write_ram(GDisplay *g, uint8_t page, uint16_t offset, uint16_t length) { -    PRIV(g)->write_buffer_offset = offset; -    write_page(g, page); -    write_data(g, (uint8_t *)PRIV(g), length + 1); -} - -LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { -    // The private area is the display surface. -    g->priv = gfxAlloc(sizeof(PrivData)); -    __builtin_memset(PRIV(g), 0, sizeof(PrivData)); -    PRIV(g)->page = 0; - -    // Initialise the board interface -    init_board(g); -    gfxSleepMilliseconds(10); - -    // zero function page, all registers (assuming full_page is all zeroes) -    write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE); -    set_hardware_shutdown(g, false); -    gfxSleepMilliseconds(10); -    // software shutdown -    write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); -    gfxSleepMilliseconds(10); -    // zero function page, all registers -    write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE); -    gfxSleepMilliseconds(10); - -    // zero all LED registers on all 8 pages, and enable the mask -    __builtin_memcpy(PRIV(g)->write_buffer, get_led_mask(g), IS31_LED_MASK_SIZE); -    for (uint8_t i = 0; i < 8; i++) { -        write_ram(g, i, 0, IS31_FRAME_SIZE); -        gfxSleepMilliseconds(1); -    } - -    // software shutdown disable (i.e. turn stuff on) -    write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); -    gfxSleepMilliseconds(10); - -    // Finish Init -    post_init_board(g); - -    /* Initialise the GDISP structure */ -    g->g.Width       = GDISP_SCREEN_WIDTH; -    g->g.Height      = GDISP_SCREEN_HEIGHT; -    g->g.Orientation = GDISP_ROTATE_0; -    g->g.Powermode   = powerOff; -    g->g.Backlight   = GDISP_INITIAL_BACKLIGHT; -    g->g.Contrast    = GDISP_INITIAL_CONTRAST; -    return TRUE; -} - -#    if GDISP_HARDWARE_FLUSH -LLDSPEC void gdisp_lld_flush(GDisplay *g) { -    // Don't flush if we don't need it. -    if (!(g->flags & GDISP_FLG_NEEDFLUSH)) return; - -    PRIV(g)->page++; -    PRIV(g)->page %= 2; -    // TODO: some smarter algorithm for this -    // We should run only one physical page at a time -    // This way we don't need to send so much data, and -    // we could use slightly less memory -    uint8_t *src = PRIV(g)->frame_buffer; -    for (int y = 0; y < GDISP_SCREEN_HEIGHT; y++) { -        for (int x = 0; x < GDISP_SCREEN_WIDTH; x++) { -            uint8_t val                                     = (uint16_t)*src * g->g.Backlight / 100; -            PRIV(g)->write_buffer[get_led_address(g, x, y)] = CIE1931_CURVE[val]; -            ++src; -        } -    } -    write_ram(g, PRIV(g)->page, IS31_PWM_REG, IS31_PWM_SIZE); -    gfxSleepMilliseconds(1); -    write_register(g, IS31_FUNCTIONREG, IS31_REG_PICTDISP, PRIV(g)->page); - -    g->flags &= ~GDISP_FLG_NEEDFLUSH; -} -#    endif - -#    if GDISP_HARDWARE_DRAWPIXEL -LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { -    coord_t x, y; - -    switch (g->g.Orientation) { -        default: -        case GDISP_ROTATE_0: -            x = g->p.x; -            y = g->p.y; -            break; -        case GDISP_ROTATE_180: -            x = GDISP_SCREEN_WIDTH - 1 - g->p.x; -            y = g->p.y; -            break; -    } -    PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x] = gdispColor2Native(g->p.color); -    g->flags |= GDISP_FLG_NEEDFLUSH; -} -#    endif - -#    if GDISP_HARDWARE_PIXELREAD -LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { -    coord_t x, y; - -    switch (g->g.Orientation) { -        default: -        case GDISP_ROTATE_0: -            x = g->p.x; -            y = g->p.y; -            break; -        case GDISP_ROTATE_180: -            x = GDISP_SCREEN_WIDTH - 1 - g->p.x; -            y = g->p.y; -            break; -    } -    return gdispNative2Color(PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x]); -} -#    endif - -#    if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL -LLDSPEC void gdisp_lld_control(GDisplay *g) { -    switch (g->p.x) { -        case GDISP_CONTROL_POWER: -            if (g->g.Powermode == (powermode_t)g->p.ptr) return; -            switch ((powermode_t)g->p.ptr) { -                case powerOff: -                case powerSleep: -                case powerDeepSleep: -                    write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF); -                    break; -                case powerOn: -                    write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON); -                    break; -                default: -                    return; -            } -            g->g.Powermode = (powermode_t)g->p.ptr; -            return; - -        case GDISP_CONTROL_ORIENTATION: -            if (g->g.Orientation == (orientation_t)g->p.ptr) return; -            switch ((orientation_t)g->p.ptr) { -                /* Rotation is handled by the drawing routines */ -                case GDISP_ROTATE_0: -                case GDISP_ROTATE_180: -                    g->g.Height = GDISP_SCREEN_HEIGHT; -                    g->g.Width  = GDISP_SCREEN_WIDTH; -                    break; -                case GDISP_ROTATE_90: -                case GDISP_ROTATE_270: -                    g->g.Height = GDISP_SCREEN_WIDTH; -                    g->g.Width  = GDISP_SCREEN_HEIGHT; -                    break; -                default: -                    return; -            } -            g->g.Orientation = (orientation_t)g->p.ptr; -            return; - -        case GDISP_CONTROL_BACKLIGHT: -            if (g->g.Backlight == (unsigned)g->p.ptr) return; -            unsigned val   = (unsigned)g->p.ptr; -            g->g.Backlight = val > 100 ? 100 : val; -            g->flags |= GDISP_FLG_NEEDFLUSH; -            return; -    } -} -#    endif  // GDISP_NEED_CONTROL - -#endif  // GFX_USE_GDISP diff --git a/drivers/ugfx/gdisp/is31fl3731c/gdisp_lld_config.h b/drivers/ugfx/gdisp/is31fl3731c/gdisp_lld_config.h deleted file mode 100644 index 403c6b0409..0000000000 --- a/drivers/ugfx/gdisp/is31fl3731c/gdisp_lld_config.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2016 Fred Sundvik <fsundvik@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _GDISP_LLD_CONFIG_H -#define _GDISP_LLD_CONFIG_H - -#if GFX_USE_GDISP - -/*===========================================================================*/ -/* Driver hardware support.                                                  */ -/*===========================================================================*/ - -#    define GDISP_HARDWARE_FLUSH GFXON  // This controller requires flushing -#    define GDISP_HARDWARE_DRAWPIXEL GFXON -#    define GDISP_HARDWARE_PIXELREAD GFXON -#    define GDISP_HARDWARE_CONTROL GFXON - -#    define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_GRAY256 - -#endif /* GFX_USE_GDISP */ - -#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/drivers/ugfx/gdisp/st7565/board_st7565_template.h b/drivers/ugfx/gdisp/st7565/board_st7565_template.h deleted file mode 100644 index 875ed9e65c..0000000000 --- a/drivers/ugfx/gdisp/st7565/board_st7565_template.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - *              http://ugfx.org/license.html - */ - -#ifndef _GDISP_LLD_BOARD_H -#define _GDISP_LLD_BOARD_H - -#include "quantum.h" - -#define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 -#define ST7565_COM_SCAN ST7565_COM_SCAN_DEC -#define ST7565_PAGE_ORDER 0, 1, 2, 3 -/* - * Custom page order for several LCD boards, e.g. HEM12864-99 - * #define ST7565_PAGE_ORDER       4,5,6,7,0,1,2,3 - */ - -#define ST7565_A0_PIN C7 -#define ST7565_RST_PIN C8 -#define ST7565_MOSI_PIN C6 -#define ST7565_SCLK_PIN C5 -#define ST7565_SS_PIN C4 - -// DSPI Clock and Transfer Attributes -// Frame Size: 8 bits -// MSB First -// CLK Low by default -static const SPIConfig spi1config = { -    // Operation complete callback or @p NULL. -    .end_cb = NULL, -    // The chip select line port - when not using pcs. -    .ssport = PAL_PORT(ST7565_SS_PIN), -    // brief The chip select line pad number - when not using pcs. -    .sspad = PAL_PAD(ST7565_SS_PIN), -    // SPI initialization data. -    .tar0 = SPIx_CTARn_FMSZ(7)     // Frame size = 8 bytes -            | SPIx_CTARn_ASC(1)    // After SCK Delay Scaler (min 50 ns) = 55.56ns -            | SPIx_CTARn_DT(0)     // Delay After Transfer Scaler (no minimum)= 27.78ns -            | SPIx_CTARn_CSSCK(0)  // PCS to SCK Delay Scaler (min 20 ns) = 27.78ns -            | SPIx_CTARn_PBR(0)    // Baud Rate Prescaler = 2 -            | SPIx_CTARn_BR(0)     // Baud rate (min 50ns) = 55.56ns -}; - -static GFXINLINE void acquire_bus(GDisplay *g) { -    (void)g; -    // Only the LCD is using the SPI bus, so no need to acquire -    // spiAcquireBus(&SPID1); -    spiSelect(&SPID1); -} - -static GFXINLINE void release_bus(GDisplay *g) { -    (void)g; -    // Only the LCD is using the SPI bus, so no need to release -    // spiReleaseBus(&SPID1); -    spiUnselect(&SPID1); -} - -static GFXINLINE void init_board(GDisplay *g) { -    (void)g; -    setPinOutput(ST7565_A0_PIN); -    writePinHigh(ST7565_A0_PIN); -    setPinOutput(ST7565_RST_PIN); -    writePinHigh(ST7565_RST_PIN); -    setPinOutput(ST7565_SS_PIN); - -    palSetPadMode(PAL_PORT(ST7565_MOSI_PIN), PAL_PAD(ST7565_MOSI_PIN), PAL_MODE_ALTERNATIVE_2); -    palSetPadMode(PAL_PORT(ST7565_SCLK_PIN), PAL_PAD(ST7565_SCLK_PIN), PAL_MODE_ALTERNATIVE_2); - -    spiInit(); -    spiStart(&SPID1, &spi1config); -    release_bus(g); -} - -static GFXINLINE void post_init_board(GDisplay *g) { (void)g; } - -static GFXINLINE void setpin_reset(GDisplay *g, bool_t state) { -    (void)g; -    writePin(ST7565_RST_PIN, !state); -} - -static GFXINLINE void write_cmd(GDisplay *g, gU8 cmd) { -    (void)g; -    writePinLow(ST7565_A0_PIN); -    spiSend(&SPID1, 1, &cmd); -} - -static GFXINLINE void write_data(GDisplay *g, gU8 *data, gU16 length) { -    (void)g; -    writePinHigh(ST7565_A0_PIN); -    spiSend(&SPID1, length, data); -} - -#endif /* _GDISP_LLD_BOARD_H */ diff --git a/drivers/ugfx/gdisp/st7565/driver.mk b/drivers/ugfx/gdisp/st7565/driver.mk deleted file mode 100644 index 799a986b0a..0000000000 --- a/drivers/ugfx/gdisp/st7565/driver.mk +++ /dev/null @@ -1,3 +0,0 @@ -GFXINC += drivers/ugfx/gdisp/st7565 -GFXSRC += drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c -GDISP_DRIVER_LIST += GDISPVMT_ST7565_QMK diff --git a/drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c b/drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c deleted file mode 100644 index f586f97e38..0000000000 --- a/drivers/ugfx/gdisp/st7565/gdisp_lld_ST7565.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - *              http://ugfx.org/license.html - */ - -#include "gfx.h" - -#if GFX_USE_GDISP - -#    define GDISP_DRIVER_VMT GDISPVMT_ST7565_QMK -#    include "gdisp_lld_config.h" -#    include "src/gdisp/gdisp_driver.h" - -#    include "board_st7565.h" - -/*===========================================================================*/ -/* Driver local definitions.                                                 */ -/*===========================================================================*/ - -#    ifndef GDISP_SCREEN_HEIGHT -#        define GDISP_SCREEN_HEIGHT LCD_HEIGHT -#    endif -#    ifndef GDISP_SCREEN_WIDTH -#        define GDISP_SCREEN_WIDTH LCD_WIDTH -#    endif -#    ifndef GDISP_INITIAL_CONTRAST -#        define GDISP_INITIAL_CONTRAST 35 -#    endif -#    ifndef GDISP_INITIAL_BACKLIGHT -#        define GDISP_INITIAL_BACKLIGHT 100 -#    endif - -#    define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) - -#    include "st7565.h" - -/*===========================================================================*/ -/* Driver config defaults for backward compatibility.                        */ -/*===========================================================================*/ -#    ifndef ST7565_LCD_BIAS -#        define ST7565_LCD_BIAS ST7565_LCD_BIAS_7 -#    endif -#    ifndef ST7565_ADC -#        define ST7565_ADC ST7565_ADC_NORMAL -#    endif -#    ifndef ST7565_COM_SCAN -#        define ST7565_COM_SCAN ST7565_COM_SCAN_INC -#    endif -#    ifndef ST7565_PAGE_ORDER -#        define ST7565_PAGE_ORDER 0, 1, 2, 3, 4, 5, 6, 7 -#    endif - -/*===========================================================================*/ -/* Driver local functions.                                                   */ -/*===========================================================================*/ - -// Some common routines and macros -#    define RAM(g) ((gU8 *)g->priv) -#    define write_cmd2(g, cmd1, cmd2) \ -        {                             \ -            write_cmd(g, cmd1);       \ -            write_cmd(g, cmd2);       \ -        } -#    define write_cmd3(g, cmd1, cmd2, cmd3) \ -        {                                   \ -            write_cmd(g, cmd1);             \ -            write_cmd(g, cmd2);             \ -            write_cmd(g, cmd3);             \ -        } - -// Some common routines and macros -#    define delay(us) gfxSleepMicroseconds(us) -#    define delay_ms(ms) gfxSleepMilliseconds(ms) - -#    define xyaddr(x, y) ((x) + ((y) >> 3) * GDISP_SCREEN_WIDTH) -#    define xybit(y) (1 << ((y)&7)) - -/*===========================================================================*/ -/* Driver exported functions.                                                */ -/*===========================================================================*/ - -/* - * As this controller can't update on a pixel boundary we need to maintain the - * the entire display surface in memory so that we can do the necessary bit - * operations. Fortunately it is a small display in monochrome. - * 64 * 128 / 8 = 1024 bytes. - */ - -LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { -    // The private area is the display surface. -    g->priv = gfxAlloc(GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8); -    if (!g->priv) { -        return gFalse; -    } - -    // Initialise the board interface -    init_board(g); - -    // Hardware reset -    setpin_reset(g, TRUE); -    gfxSleepMilliseconds(20); -    setpin_reset(g, FALSE); -    gfxSleepMilliseconds(20); -    acquire_bus(g); - -    write_cmd(g, ST7565_LCD_BIAS); -    write_cmd(g, ST7565_ADC); -    write_cmd(g, ST7565_COM_SCAN); - -    write_cmd(g, ST7565_START_LINE | 0); - -    write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST * 64 / 101); -    write_cmd(g, ST7565_RESISTOR_RATIO | 0x1); - -    // turn on voltage converter (VC=1, VR=0, VF=0) -    write_cmd(g, ST7565_POWER_CONTROL | 0x04); -    delay_ms(50); - -    // turn on voltage regulator (VC=1, VR=1, VF=0) -    write_cmd(g, ST7565_POWER_CONTROL | 0x06); -    delay_ms(50); - -    // turn on voltage follower (VC=1, VR=1, VF=1) -    write_cmd(g, ST7565_POWER_CONTROL | 0x07); -    delay_ms(50); - -    write_cmd(g, ST7565_DISPLAY_ON); -    write_cmd(g, ST7565_ALLON_NORMAL); -    write_cmd(g, ST7565_INVERT_DISPLAY);  // Disable Inversion of display. - -    write_cmd(g, ST7565_RMW); - -    // Finish Init -    post_init_board(g); - -    // Release the bus -    release_bus(g); - -    /* Initialise the GDISP structure */ -    g->g.Width       = GDISP_SCREEN_WIDTH; -    g->g.Height      = GDISP_SCREEN_HEIGHT; -    g->g.Orientation = GDISP_ROTATE_0; -    g->g.Powermode   = powerOff; -    g->g.Backlight   = GDISP_INITIAL_BACKLIGHT; -    g->g.Contrast    = GDISP_INITIAL_CONTRAST; -    return TRUE; -} - -#    if GDISP_HARDWARE_FLUSH -LLDSPEC void gdisp_lld_flush(GDisplay *g) { -    unsigned p; - -    // Don't flush if we don't need it. -    if (!(g->flags & GDISP_FLG_NEEDFLUSH)) return; - -    acquire_bus(g); -    gU8 pagemap[] = {ST7565_PAGE_ORDER}; -    for (p = 0; p < sizeof(pagemap); p++) { -        write_cmd(g, ST7565_PAGE | pagemap[p]); -        write_cmd(g, ST7565_COLUMN_MSB | 0); -        write_cmd(g, ST7565_COLUMN_LSB | 0); -        write_cmd(g, ST7565_RMW); -        write_data(g, RAM(g) + (p * GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH); -    } -    release_bus(g); - -    g->flags &= ~GDISP_FLG_NEEDFLUSH; -} -#    endif - -#    if GDISP_HARDWARE_DRAWPIXEL -LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) { -    coord_t x, y; - -    switch (g->g.Orientation) { -        default: -        case GDISP_ROTATE_0: -            x = g->p.x; -            y = g->p.y; -            break; -        case GDISP_ROTATE_90: -            x = g->p.y; -            y = GDISP_SCREEN_HEIGHT - 1 - g->p.x; -            break; -        case GDISP_ROTATE_180: -            x = GDISP_SCREEN_WIDTH - 1 - g->p.x; -            y = GDISP_SCREEN_HEIGHT - 1 - g->p.y; -            break; -        case GDISP_ROTATE_270: -            x = GDISP_SCREEN_HEIGHT - 1 - g->p.y; -            y = g->p.x; -            break; -    } -    if (gdispColor2Native(g->p.color) != Black) -        RAM(g)[xyaddr(x, y)] |= xybit(y); -    else -        RAM(g)[xyaddr(x, y)] &= ~xybit(y); -    g->flags |= GDISP_FLG_NEEDFLUSH; -} -#    endif - -#    if GDISP_HARDWARE_PIXELREAD -LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) { -    coord_t x, y; - -    switch (g->g.Orientation) { -        default: -        case GDISP_ROTATE_0: -            x = g->p.x; -            y = g->p.y; -            break; -        case GDISP_ROTATE_90: -            x = g->p.y; -            y = GDISP_SCREEN_HEIGHT - 1 - g->p.x; -            break; -        case GDISP_ROTATE_180: -            x = GDISP_SCREEN_WIDTH - 1 - g->p.x; -            y = GDISP_SCREEN_HEIGHT - 1 - g->p.y; -            break; -        case GDISP_ROTATE_270: -            x = GDISP_SCREEN_HEIGHT - 1 - g->p.y; -            y = g->p.x; -            break; -    } -    return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black; -} -#    endif - -#    if GDISP_HARDWARE_BITFILLS -LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { -    uint8_t *buffer     = (uint8_t *)g->p.ptr; -    int      linelength = g->p.cx; -    for (int i = 0; i < g->p.cy; i++) { -        unsigned dstx   = g->p.x; -        unsigned dsty   = g->p.y + i; -        unsigned srcx   = g->p.x1; -        unsigned srcy   = g->p.y1 + i; -        unsigned srcbit = srcy * g->p.x2 + srcx; -        for (int j = 0; j < linelength; j++) { -            uint8_t  src    = buffer[srcbit / 8]; -            uint8_t  bit    = 7 - (srcbit % 8); -            uint8_t  bitset = (src >> bit) & 1; -            uint8_t *dst    = &(RAM(g)[xyaddr(dstx, dsty)]); -            if (bitset) { -                *dst |= xybit(dsty); -            } else { -                *dst &= ~xybit(dsty); -            } -            dstx++; -            srcbit++; -        } -    } -    g->flags |= GDISP_FLG_NEEDFLUSH; -} -#    endif - -#    if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL -LLDSPEC void gdisp_lld_control(GDisplay *g) { -    switch (g->p.x) { -        case GDISP_CONTROL_POWER: -            if (g->g.Powermode == (powermode_t)g->p.ptr) return; -            switch ((powermode_t)g->p.ptr) { -                case powerOff: -                case powerSleep: -                case powerDeepSleep: -                    acquire_bus(g); -                    write_cmd(g, ST7565_DISPLAY_OFF); -                    release_bus(g); -                    break; -                case powerOn: -                    acquire_bus(g); -                    write_cmd(g, ST7565_DISPLAY_ON); -                    release_bus(g); -                    break; -                default: -                    return; -            } -            g->g.Powermode = (powermode_t)g->p.ptr; -            return; - -        case GDISP_CONTROL_ORIENTATION: -            if (g->g.Orientation == (orientation_t)g->p.ptr) return; -            switch ((orientation_t)g->p.ptr) { -                /* Rotation is handled by the drawing routines */ -                case GDISP_ROTATE_0: -                case GDISP_ROTATE_180: -                    g->g.Height = GDISP_SCREEN_HEIGHT; -                    g->g.Width  = GDISP_SCREEN_WIDTH; -                    break; -                case GDISP_ROTATE_90: -                case GDISP_ROTATE_270: -                    g->g.Height = GDISP_SCREEN_WIDTH; -                    g->g.Width  = GDISP_SCREEN_HEIGHT; -                    break; -                default: -                    return; -            } -            g->g.Orientation = (orientation_t)g->p.ptr; -            return; - -        case GDISP_CONTROL_CONTRAST: -            if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; -            acquire_bus(g); -            write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr) << 6) / 101) & 0x3F); -            release_bus(g); -            g->g.Contrast = (unsigned)g->p.ptr; -            return; -    } -} -#    endif  // GDISP_NEED_CONTROL - -#endif  // GFX_USE_GDISP diff --git a/drivers/ugfx/gdisp/st7565/gdisp_lld_config.h b/drivers/ugfx/gdisp/st7565/gdisp_lld_config.h deleted file mode 100644 index 6052058ec2..0000000000 --- a/drivers/ugfx/gdisp/st7565/gdisp_lld_config.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - *              http://ugfx.org/license.html - */ - -#ifndef _GDISP_LLD_CONFIG_H -#define _GDISP_LLD_CONFIG_H - -#if GFX_USE_GDISP - -/*===========================================================================*/ -/* Driver hardware support.                                                  */ -/*===========================================================================*/ - -#    define GDISP_HARDWARE_FLUSH GFXON  // This controller requires flushing -#    define GDISP_HARDWARE_DRAWPIXEL GFXON -#    define GDISP_HARDWARE_PIXELREAD GFXON -#    define GDISP_HARDWARE_CONTROL GFXON -#    define GDISP_HARDWARE_BITFILLS GFXON - -#    define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO - -#endif /* GFX_USE_GDISP */ - -#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/drivers/ugfx/gdisp/st7565/st7565.h b/drivers/ugfx/gdisp/st7565/st7565.h deleted file mode 100644 index 3c77a88569..0000000000 --- a/drivers/ugfx/gdisp/st7565/st7565.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - *              http://ugfx.org/license.html - */ - -#ifndef _ST7565_H -#define _ST7565_H - -#define ST7565_CONTRAST 0x81 -#define ST7565_ALLON_NORMAL 0xA4 -#define ST7565_ALLON 0xA5 -#define ST7565_POSITIVE_DISPLAY 0xA6 -#define ST7565_INVERT_DISPLAY 0xA7 -#define ST7565_DISPLAY_OFF 0xAE -#define ST7565_DISPLAY_ON 0xAF - -#define ST7565_LCD_BIAS_7 0xA3 -#define ST7565_LCD_BIAS_9 0xA2 - -#define ST7565_ADC_NORMAL 0xA0 -#define ST7565_ADC_REVERSE 0xA1 - -#define ST7565_COM_SCAN_INC 0xC0 -#define ST7565_COM_SCAN_DEC 0xC8 - -#define ST7565_START_LINE 0x40 -#define ST7565_PAGE 0xB0 -#define ST7565_COLUMN_MSB 0x10 -#define ST7565_COLUMN_LSB 0x00 -#define ST7565_RMW 0xE0 - -#define ST7565_RESISTOR_RATIO 0x20 -#define ST7565_POWER_CONTROL 0x28 - -#define ST7565_RESET 0xE2 - -#endif /* _ST7565_H */ | 
