Skip to content

Commit

Permalink
Change LED blinking to non blocking
Browse files Browse the repository at this point in the history
The LED blinking for initialization and USB enumeration now
no longer blocks and the USB devices should enumerate sooner.

Also placed as much of the code as possible into SRAM using
a linker script adopted from ZuluSCSI.
  • Loading branch information
morio committed Nov 30, 2023
1 parent d5c6c6b commit f8a8f7a
Show file tree
Hide file tree
Showing 8 changed files with 379 additions and 49 deletions.
49 changes: 49 additions & 0 deletions src/firmware/lib/QuokkADB/include/blink.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//---------------------------------------------------------------------------
//
// QuokkADB ADB keyboard and mouse adapter
//
// Copyright (C) 2023 Rabbit Hole Computing LLC
//
// This file is part of QuokkADB.
//
// This file 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 file 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 file. If not, see <https://www.gnu.org/licenses/>.
//
// Portions of this code were originally released under a Modified BSD
// License. See LICENSE in the root of this repository for more info.
//
//----------------------------------------------------------------------------
#pragma once

#include <scqueue.h>
#define BLINK_QUEUE_LENGTH 5

struct blink_event_t
{
uint8_t times;
uint32_t delay_ms;
};

class BlinkLed
{
public:
bool blink(uint8_t times, uint32_t delay_ms = 75);
void led_on(bool force = false);
void led_off(bool force = false);
void poll();
protected:
simple_circular_queue::SCQueue<blink_event_t*, BLINK_QUEUE_LENGTH> blink_queue;
bool blinking = false;
};

extern BlinkLed blink_led;
12 changes: 1 addition & 11 deletions src/firmware/lib/QuokkADB/include/quokkadb_gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,4 @@

void adb_gpio_init(void);
void uart_gpio_init(void);
void led_gpio_init(void);
void led_blink(uint8_t times);


inline void led_on(void) {
LED_ON();
}

inline void led_off(void) {
LED_OFF();
}
void led_gpio_init(void);
117 changes: 117 additions & 0 deletions src/firmware/lib/QuokkADB/src/blink.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//---------------------------------------------------------------------------
//
// QuokkADB ADB keyboard and mouse adapter
//
// Copyright (C) 2023 Rabbit Hole Computing LLC
//
// This file is part of QuokkADB.
//
// This file 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 file 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 file. If not, see <https://www.gnu.org/licenses/>.
//
// Portions of this code were originally released under a Modified BSD
// License. See LICENSE in the root of this repository for more info.
//
//----------------------------------------------------------------------------
#include "blink.h"
#include "quokkadb_gpio.h"
#include "adb_platform.h"

BlinkLed blink_led;

bool BlinkLed::blink(uint8_t times, uint32_t delay_ms)
{
blink_event_t* event = new blink_event_t;
event->times = times;
event->delay_ms = delay_ms;
return blink_queue.enqueue(event);
}

void BlinkLed::led_on(bool force)
{
if (force || !blinking)
{
LED_ON();
}
}

void BlinkLed::led_off(bool force)
{
if (force || !blinking)
{
LED_OFF();
}
}

void BlinkLed::poll()
{
static blink_event_t *current_event = nullptr;
static bool on_phase = true;
static uint8_t blinked = 0;
static bool last_delay = false;
static uint32_t start_delay;

if (!blinking && !blink_queue.isEmpty())
{
current_event = blink_queue.dequeue();
start_delay = millis();
LED_ON();
on_phase = true;
blinking = true;
blinked = 0;
last_delay = false;
}

if (blinking)
{
if ((uint32_t)(millis() - start_delay) > current_event->delay_ms)
{
if (last_delay)
{
if (on_phase)
{
// end of blink routine
last_delay = false;
delete current_event;
blinking = false;
}
else
{
// one more delay so there is an extra delay before starting a new blink sequence
start_delay = millis();
on_phase = true;
}

}
else if (on_phase)
{
on_phase = false;
LED_OFF();
start_delay = millis();
if (blinked + 1 >= current_event->times)
{
last_delay = true;
}
}
else
{
blinked++;
on_phase = true;
LED_ON();
start_delay = millis();
}
}
}


}
25 changes: 15 additions & 10 deletions src/firmware/lib/QuokkADB/src/quokkadb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#include "adbmouseparser.h"
#include "flashsettings.h"
#include "platform_config.h"

#include "blink.h"

// Globals
extern uint8_t mousepending;
Expand All @@ -68,16 +68,20 @@ ADBKbdRptParser KeyboardPrs;
ADBMouseRptParser MousePrs(KeyboardPrs);
FlashSettings setting_storage;

/*------------ Pre Core0 and Core1 setup ------------*/
void initVariant()
{
led_gpio_init();
uart_gpio_init();
Serial1.begin();
}

/*------------ Core0 setup ------------*/
void setup()
{
set_sys_clock_khz(125000, true);

led_gpio_init();
led_blink(1);
uart_gpio_init();
blink_led.blink(1);
adb_gpio_init();
Serial1.begin();
setting_storage.init();
Logmsg.println(PLATFORM_FW_VER_STRING);
srand(time_us_32());
Expand Down Expand Up @@ -108,11 +112,11 @@ void loop()
}
}

led_off();
blink_led.led_off();
cmd = adb.ReceiveCommand(mousesrq | kbdsrq);
if(setting_storage.settings()->led_on)
{
led_on();
blink_led.led_on();
}
adb.ProcessCommand(cmd);

Expand All @@ -131,14 +135,15 @@ void loop()
void setup1()
{
tuh_init(0);
led_blink(1);
sleep_us(500);
}

/*------------ Core1 main loop ------------*/
void loop1()
{
tuh_task(); // tinyusb host task

blink_led.poll();

KeyboardPrs.ChangeUSBKeyboardLEDs();

if (true == usb_reset)
Expand Down
25 changes: 0 additions & 25 deletions src/firmware/lib/QuokkADB/src/quokkadb_gpio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,8 @@


#include "quokkadb_gpio.h"
#include "pico/mutex.h"
#include "hardware/gpio.h"
#include <pico/stdio_uart.h>
#include <pico/printf.h>

mutex_t led_mutex;



extern bool global_debug;
void adb_gpio_init(void) {
Expand All @@ -48,35 +42,16 @@ void adb_gpio_init(void) {

}



void led_gpio_init(void) {
gpio_init(LED_GPIO);
gpio_set_function(LED_GPIO, GPIO_FUNC_SIO);
gpio_set_dir(LED_GPIO, GPIO_OUT);
LED_OFF();
mutex_init(&led_mutex);

}

void uart_gpio_init(void) {

uart_init(UART_PORT, UART_TX_BAUD);
gpio_set_function(UART_TX_GPIO, GPIO_FUNC_UART);
}



// Blink the led n times
void led_blink(uint8_t times) {
mutex_enter_blocking(&led_mutex);
for (uint8_t i = 0; i < times; i++) {
LED_ON();
sleep_ms(75);
LED_OFF();
sleep_ms(75);
}
sleep_ms(75);
mutex_exit(&led_mutex);
}

Loading

0 comments on commit f8a8f7a

Please sign in to comment.