Skip to content

Commit

Permalink
Merge pull request #50 from mndza/new-led-scheme
Browse files Browse the repository at this point in the history
firmware: implement new LED scheme
  • Loading branch information
mossmann authored May 16, 2024
2 parents 58dfc04 + a7c86c6 commit 87b5f53
Show file tree
Hide file tree
Showing 24 changed files with 225 additions and 86 deletions.
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

0 comments on commit 87b5f53

Please sign in to comment.