Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

firmware: implement new LED scheme #50

Merged
merged 1 commit into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions firmware/src/boards/cynthion_d11/fpga.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "apollo_board.h"
#include "jtag.h"
#include "fpga.h"


/*
Expand Down Expand Up @@ -68,4 +69,7 @@ void trigger_fpga_reconfiguration(void)

gpio_set_pin_level(FPGA_PROGRAM, true);
gpio_set_pin_direction(FPGA_PROGRAM, GPIO_DIRECTION_IN);

// Update internal state.
fpga_online = true;
}
27 changes: 24 additions & 3 deletions firmware/src/boards/cynthion_d11/fpga_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/

#include <stdbool.h>
#include "fpga_adv.h"
#include "usb_switch.h"
#include "apollo_board.h"
Expand All @@ -23,6 +24,9 @@
#define TIMEOUT 100UL
static uint32_t last_phy_adv = 0;

// Allow deferred switching of the USB port.
static bool defer_hand_off = false;

// Create a reference to our SERCOM object.
typedef Sercom sercom_t;
static sercom_t *sercom = SERCOM1;
Expand Down Expand Up @@ -107,9 +111,12 @@ void fpga_adv_init(void)
void fpga_adv_task(void)
{
#ifdef BOARD_HAS_USB_SWITCH
// Take over USB after timeout
if (board_millis() - last_phy_adv >= TIMEOUT) {
// Take over USB after timeout
if (fpga_requesting_port() == false) {
take_over_usb();
} else if (defer_hand_off) {
hand_off_usb();
defer_hand_off = false;
}
#endif
}
Expand All @@ -120,12 +127,26 @@ void fpga_adv_task(void)
void honor_fpga_adv(void)
{
#ifdef BOARD_HAS_USB_SWITCH
if (board_millis() - last_phy_adv < TIMEOUT) {
if (fpga_requesting_port()) {
hand_off_usb();
} else {
defer_hand_off = true;
}
#endif
}

/**
* True if we received an advertisement message within the last time window.
*/
bool fpga_requesting_port(void)
{
#ifdef BOARD_HAS_USB_SWITCH
return board_millis() - last_phy_adv < TIMEOUT;
#else
return false;
#endif
}


#ifdef BOARD_HAS_USB_SWITCH
/**
Expand Down
54 changes: 33 additions & 21 deletions firmware/src/boards/cynthion_d11/led.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@


#include "led.h"
#include "fpga.h"
#include "fpga_adv.h"
#include "usb_switch.h"


/** Store the current LED blink pattern. */
static blink_pattern_t blink_pattern = BLINK_IDLE;
static led_pattern_t led_pattern = LED_IDLE;


/**
Expand Down Expand Up @@ -116,16 +119,16 @@ static void display_led_number(uint8_t number)


/**
* Sets the active LED blink pattern.
* Sets the active LED pattern.
*/
void led_set_blink_pattern(blink_pattern_t pattern)
void led_set_pattern(led_pattern_t pattern)
{
blink_pattern = pattern;
led_pattern = pattern;
leds_off();
// Values of 0 to 31 should be set immediately as static patterns.
if (blink_pattern < 32) {
if (led_pattern < 32) {
for (int i = 0; i < 5; i++) {
if (blink_pattern & (1 << i)) {
if (led_pattern & (1 << i)) {
display_led_number(i);
}
}
Expand All @@ -134,36 +137,45 @@ void led_set_blink_pattern(blink_pattern_t pattern)


/**
* Task that handles blinking the heartbeat LED.
* Task that handles LED updates.
*/
void heartbeat_task(void)
void led_task(void)
{
static uint32_t start_ms = 0;
static uint8_t active_led = 0;
static bool count_up = true;

// Values of 0 to 31 define static patterns only.
if (blink_pattern < 32) {
if (led_pattern < 32) {
return;
}

// Blink every interval ms
if ( board_millis() - start_ms < blink_pattern) return; // not enough time
start_ms += blink_pattern;
// When the device is idle, use the following scheme for LEDs:
// - LED A: power indication (always on in Apollo)
// - LED B: FPGA allowed online (indicates PROGRAM toggle)
// - LED C: FPGA has requested CONTROL port
// - LED D: USB switched to FPGA
// - LED E: flashing patterns (e.g. fault indication)
if (led_pattern == LED_IDLE) {
led_set(LED_A, true);
led_set(LED_B, fpga_is_online());
led_set(LED_C, fpga_requesting_port());
led_set(LED_D, fpga_controls_usb_port());
led_set(LED_E, false);
return;
}

switch (blink_pattern) {
// Blink every interval ms
if ( board_millis() - start_ms < led_pattern) return; // not enough time
start_ms += led_pattern;

// Standard blink pattern for when the device is idle.
// Indicates that the device's JTAG lines are un-pulled.
case BLINK_IDLE:
led_toggle(LED_E);
break;
switch (led_pattern) {

// Blink patterns for when the device is being used for JTAG
// operation. When these are on, the uC is driving the JTAG lines,
// so the JTAG header probably shouldn't used to drive the lines.
case BLINK_JTAG_CONNECTED:
case BLINK_JTAG_UPLOADING:
case LED_JTAG_CONNECTED:
case LED_JTAG_UPLOADING:

// Sweep back and forth.
if (active_led == 0xFF) {
Expand All @@ -182,7 +194,7 @@ void heartbeat_task(void)

// Blink patterns for when the device is being used for SPI flash access.
// When these are displayed,
case BLINK_FLASH_CONNECTED:
case LED_FLASH_CONNECTED:

if (active_led == 5) {
active_led = 0;
Expand Down
4 changes: 4 additions & 0 deletions firmware/src/boards/cynthion_d21/fpga.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <hal/include/hal_gpio.h>

#include "jtag.h"
#include "fpga.h"

// List of pins used for FPGA interfacing.
enum {
Expand Down Expand Up @@ -73,4 +74,7 @@ void trigger_fpga_reconfiguration(void)

gpio_set_pin_level(PIN_PROG, true);
gpio_set_pin_direction(PIN_PROG, GPIO_DIRECTION_IN);

// Update internal state.
fpga_online = true;
}
9 changes: 9 additions & 0 deletions firmware/src/boards/cynthion_d21/fpga_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Copyright (c) 2023 Great Scott Gadgets <[email protected]>
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdbool.h>

/**
* Initialize FPGA_ADV receive-only serial port
Expand All @@ -27,3 +28,11 @@ void fpga_adv_task(void)
void honor_fpga_adv(void)
{
}

/**
* True if we received an advertisement message within the last time window.
*/
bool fpga_requesting_port(void)
{
return false;
}
32 changes: 16 additions & 16 deletions firmware/src/boards/cynthion_d21/led.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


/** Store the current LED blink pattern. */
static blink_pattern_t blink_pattern = BLINK_IDLE;
static led_pattern_t led_pattern = LED_IDLE;


/**
Expand Down Expand Up @@ -103,16 +103,16 @@ static void display_led_number(uint8_t number)


/**
* Sets the active LED blink pattern.
* Sets the active LED pattern.
*/
void led_set_blink_pattern(blink_pattern_t pattern)
void led_set_pattern(led_pattern_t pattern)
{
blink_pattern = pattern;
led_pattern = pattern;
leds_off();
// Values of 0 to 31 should be set immediately as static patterns.
if (blink_pattern < 32) {
if (led_pattern < 32) {
for (int i = 0; i < 5; i++) {
if (blink_pattern & (1 << i)) {
if (led_pattern & (1 << i)) {
display_led_number(i);
}
}
Expand All @@ -121,36 +121,36 @@ void led_set_blink_pattern(blink_pattern_t pattern)


/**
* Task that handles blinking the heartbeat LED.
* Task that handles LED updates.
*/
void heartbeat_task(void)
void led_task(void)
{
static uint32_t start_ms = 0;
static uint8_t active_led = 0;
static bool count_up = true;

// Values of 0 to 31 define static patterns only.
if (blink_pattern < 32) {
if (led_pattern < 32) {
return;
}

// Blink every interval ms
if ( board_millis() - start_ms < blink_pattern) return; // not enough time
start_ms += blink_pattern;
if ( board_millis() - start_ms < led_pattern) return; // not enough time
start_ms += led_pattern;

switch (blink_pattern) {
switch (led_pattern) {

// Standard blink pattern for when the device is idle.
// Indicates that the device's JTAG lines are un-pulled.
case BLINK_IDLE:
case LED_IDLE:
led_toggle(LED_E);
break;

// Blink patterns for when the device is being used for JTAG
// operation. When these are on, the uC is driving the JTAG lines,
// so the JTAG header probably shouldn't used to drive the lines.
case BLINK_JTAG_CONNECTED:
case BLINK_JTAG_UPLOADING:
case LED_JTAG_CONNECTED:
case LED_JTAG_UPLOADING:

// Sweep back and forth.
if (active_led == 0xFF) {
Expand All @@ -169,7 +169,7 @@ void heartbeat_task(void)

// Blink patterns for when the device is being used for SPI flash access.
// When these are displayed,
case BLINK_FLASH_CONNECTED:
case LED_FLASH_CONNECTED:

if (active_led == 5) {
active_led = 0;
Expand Down
9 changes: 9 additions & 0 deletions firmware/src/boards/daisho/fpga_adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Copyright (c) 2023 Great Scott Gadgets <[email protected]>
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdbool.h>

/**
* Initialize FPGA_ADV receive-only serial port
Expand All @@ -27,3 +28,11 @@ void fpga_adv_task(void)
void honor_fpga_adv(void)
{
}

/**
* True if we received an advertisement message within the last time window.
*/
bool fpga_requesting_port(void)
{
return false;
}
16 changes: 8 additions & 8 deletions firmware/src/boards/daisho/led.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@


/** Store the current LED blink pattern. */
static blink_pattern_t blink_pattern = BLINK_IDLE;
static led_pattern_t led_pattern = LED_IDLE;


/**
* Sets the active LED blink pattern.
* Sets the active LED pattern.
*/
void led_set_blink_pattern(blink_pattern_t pattern)
void led_set_pattern(led_pattern_t pattern)
{
blink_pattern = pattern;
led_pattern = pattern;
leds_off();
}

Expand Down Expand Up @@ -91,18 +91,18 @@ void leds_off(void)


/**
* Task that handles blinking the heartbeat LED.
* Task that handles LED updates.
*/
void heartbeat_task(void)
void led_task(void)
{
static uint32_t start_ms = 0;

// Blink every interval ms
if ( board_millis() - start_ms < blink_pattern) {
if ( board_millis() - start_ms < led_pattern) {
return; // not enough time
}

start_ms += blink_pattern;
start_ms += led_pattern;
led_toggle(LED_STATUS);

}
4 changes: 4 additions & 0 deletions firmware/src/boards/qtpy/fpga.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "apollo_board.h"
#include "jtag.h"
#include "fpga.h"

// List of pins used for FPGA interfacing.

Expand Down Expand Up @@ -80,4 +81,7 @@ void trigger_fpga_reconfiguration(void)

gpio_set_pin_level(PIN_PROG, true);
gpio_set_pin_direction(PIN_PROG, GPIO_DIRECTION_IN);

// Update internal state.
fpga_online = true;
}
Loading
Loading