Page 1 of 1

How to safely power off from REPL?

Posted: Wed Oct 08, 2014 11:17 pm
by mosi
Hi,
I would like to aggressively power off the board with the USER button.

The plan:
- pressing USR button resets the board
- press&hold for 2 seconds powers off the board
When a pin is activated, external IC cuts-off the main power to processor.

The issue:
SDcard is still plugged in and the OS complains about "Eject the USB flash disc first before removing device".
also,
my Mac crashes in the process 1 in 6 times (probably due to USB drivers or SD card?)

Question:
- How to remove SD card from being used as mass storage?
See pyb.usb_mode('CDC+HID') which does not work in this context.
- How to prepare the micropython and the processor for being shut down aggressively from within an IRQ ?
- is there a better timing method for Switch() callback?
- how could I call more complicated functions for LED PWM pulsing from within the Switch() callback IRQ routine?

Thank you!

Code: Select all

import pyb

####### Init Timers ###############
micros = pyb.Timer(2, prescaler=83, period=0x3fffffff)
micros.counter(0)

### power-off pin, when high, the main power is cut to processor
POWER_OFF = Pin.cpu.B1.init(pyb.Pin.OUT_PP, pull=pyb.Pin.PULL_DOWN, af=-1)

sw         = pyb.Switch()

# BTN_callback
def BTN_callback():
  timeout=2000000 #microseconds
  pyb.LED(1).toggle()
  pyb.LED(2).toggle()
  pyb.LED(3).toggle()
  micros.counter(0)
  while (sw() and (micros.counter()<timeout) ):
    pyb.LED(3).toggle()
    pyb.LED(1).toggle()
  if (micros.counter()>=timeout):
    print('Switching OFF:\n')
    pyb.sync()
    pyb.usb_mode('CDC+HID')
    pyb.sync()
    PIN_OFF.high()  ## this is where the power is lost
  else:
    print("Reset here::")
  pyb.LED(1).on()
  pyb.LED(2).off()
  pyb.LED(3).off()

sw.callback(BTN_callback)


Re: How to safely power off from REPL?

Posted: Thu Oct 09, 2014 12:12 am
by dhylands
To prevent the "you must eject the sdcard" you need to not enable mass storage in the first place (there is no way for the pyboard to initiate the eject - your mac has to do that).

You can prevent mass storage from being used by putting the pyb.usb_mode('CDC+HID') in your boot.py file. Any later than that and mass storage is already started and thus its too late.

You also don't need to tie up a timer anymore for your microsecond timer. You can use pyb.micros() and pyb.elapsed_micros() I don't see elapsed_micros on the doc page, but if you have recent firmware it exists.

Code: Select all

start_time = pyb.micros()
while pyb.elapsed_micros(start_time) < some_value:
    do_something()
I'm not sure that all of your function will work from interrupt context. Like pyb.sync(). It will depend on the relative priority of the USB interupts versus the switch interrupt.

It looks like the Yellow LED can be connected to channel 1 of timer 2.

Also note that the switch callback is a raw callback. You should probably put some debounce logic in there. You can get multiple edges when you press and release the button.