tessel/t2-firmware

Set hardware button to power reset

Closed this issue · 8 comments

As discussed in #107 (comment), the Tessel hardware button is now reserved as a reset.

There is a check for the button being pressed during power up as reference for how to check the value of the button (

bool button_pressed() {
)

In firmware/main.c there are examples of how to power cycle the OpenWRT system-on-chip (SOC) ->

t2-firmware/firmware/main.c

Lines 157 to 163 in 1c7c86e

// On powerup, force a clean reset of the MT7620
pin_low(PIN_SOC_RST);
pin_out(PIN_SOC_RST);
// turn off 3.3V to SoC
pin_low(PIN_SOC_PWR);
pin_out(PIN_SOC_PWR);

See the "Compiling" section of the README for information about updating a Tessel with the new firmware -> https://github.com/tessel/t2-firmware#compiling

I'd like to propose an additional functionality. If the button is held (eg, on during startup) that it is exposed to the OS in some way. I think this could be used for a wifi/ap setup functionality or an app level config reset. In fact... #189 lays out my thinking.

I'd like to propose an additional functionality. If the button is held (eg, on during startup) that it is exposed to

No, that's already in use for dfu mode

Patching void EIC_Handler() might be the most efficient way to do this. The only thing we have to deal with is registering/set-up....thats where I had a question.

So after setting up the pin/port and mux (pin_mux_eic) do we need to do anything about EIC->INTENCLR or EIC->INTENSET??

The datasheet mentions the fields but I dont see any code that sets them:

Each interrupt source has an associated interrupt flag. The interrupt flag in the Interrupt Flag Status and
Clear register (INTFLAG) is set when an interrupt condition occurs (NMIFLAG for NMI). Each interrupt,
except NMI, can be individually enabled by setting the corresponding bit in the Interrupt Enable Set
register (INTENSET=1), and disabled by setting the corresponding bit in the Interrupt Enable Clear
register (INTENCLR=1).

Patching void EIC_Handler() might be the most efficient way to do this. The only thing we have to deal with is registering/set-up....thats where I had a question.

👍

So after setting up the pin/port and mux (pin_mux_eic) do we need to do anything about EIC->INTENCLR or EIC->INTENSET??

Yes, we do! As part of the SAMD21 parser (from data coming in from the OpenWRT SPI connection) state machine, INTENSET gets set to the enabled bits for that port. Then, once the port is disabled (via the JavaScript execution completing or an explicit call to disable the port or whatever), INTENCLR is set.

With the button, you can probably just enable the interrupts in the main func and don't need to worry about clearing the enable because you should always be able to reset the chip.

Thanks for the links. That's exactly what I was looking for. For some reason github search found every occurrence of EIC except that one 😑

Only resetting the SoC (PIN_SOC_RST) results odd issues such as:

implementation

  • led[3] will maintain its state until SoC can reboot and take over.
var tessel = require('tessel');
tessel.led[3].on();
setInterval(function () {
  tessel.led[3].toggle();
}, 100);
  • Here I am running a script that prints Blink! to the console (using t2 run). After a reset, the SoC reboots (top right window) but the CLI is never notified (bottom right).

image

One option is to reset SAMD21 resulting in a clean state for both SoC and SAMD21

Im still looking into this, somethings I want to consider:

  • GPIO/Modules. Things can be attached to tessel, how should a reset effect them.
  • Flash. Its powered by SOC but shared w/ SAMD21

Ideally it should behave like pulling USB cable and not a coordinated shutdown procedure

Turns out the the SAMD21 POR routine provides with a safe way to reset the board. Instead of resetting the SoC, we can send a CPU reset on the SAMD21 and treat it similarly

See #211

This can be closed
cc @johnnyman727