AVR (at90usb1286) sleep y USB

4

Estoy usando un AVR at90usb1286 basado en Teensy ++ 2.0 para leer periódicamente datos de algunos sensores. En su forma final, mi proyecto actuará en base a las entradas del sensor. Por ahora, registro los resultados en el puerto USB.

Debido a que el intervalo de medición es relativamente largo, coloco el microcontrolador en modo de ahorro de energía entre las mediciones y utilizo el temporizador de vigilancia para despertar periódicamente. Esto funciona bien, pero después de reactivar la conexión USB ya no funciona y no he encontrado ninguna manera de recuperarla

Estoy usando PJRCs Debug Only USB library junto con su componente del lado del host hid_listen.exe .

Debido a su función de depuración, me gustaría que la solución afecte lo menos posible a la estructura del código.

He intentado tres estrategias hasta ahora:

  1. Ingresando el modo de ahorro de energía (SLEEP_MODE_PWR_SAVE) sin ninguna precaución especial. Recibo un error "Dispositivo USB no reconocido" de windows7 y no es posible una comunicación adicional.
  2. Ingresando un modo de suspensión que mantiene el USB activo (SLEEP_MODE_IDLE). En este modo, el USB sigue funcionando, pero la suspensión se interrumpe de forma bastante inmediata.
  3. Ingresando el modo de espera de ahorro de energía (SLEEP_MODE_PWR_SAVE) e intentando reiniciar el USB después llamando a usb_init() . Esto no parece tener ningún efecto.

Aquí hay una aplicación simplificada que muestra el problema, adaptada de esta lección 13

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/power.h>
#include <avr/sleep.h>

#include "usb_debug_only.h"
#include "print.h"

ISR(WDT_vect, ISR_NAKED){
    _WD_CONTROL_REG = _BV(WDIE); // must reset interrupt after trigger
    /* do other work inside the watchdog interrupt? */
    PIND = _BV(PD6); /* toggle the pin */
    reti();
}

int main(void){
    DDRD = _BV(PD6);
    PORTD = _BV(PD6);
    /* watchdog setup goo */
    wdt_enable(WDTO_1S);
    _WD_CONTROL_REG = _BV(WDIE); /* generate watchdog interrupts */
    usb_init();

    sei(); /* enable interrupts */

    while(1){
        set_sleep_mode(SLEEP_MODE_PWR_SAVE);
        sleep_mode();
        print("a");
        usb_debug_flush_output();
        /* Do stuff after the watchdog wakes us up */
    }
}

Preguntas

Teniendo en cuenta el hardware dado, ¿cuáles son las buenas estrategias para poner al controlador en estado de suspensión mientras se mantiene algún tipo de capacidad de salida de depuración?

No me preocupa el consumo de energía, ya que el USB estará inactivo en el modo de producción a batería. Sin embargo, deseo poder obtener algunos resultados de depuración mientras escribo el programa ...

    
pregunta drxzcl

1 respuesta

5

IIRC eléctricamente, solo tiene que alternar la resistencia de pull-up conectada a D + (o era D-), así que intentaría configurar y borrar manualmente (con un pequeño retardo entre ellos) el bit DETACH en el registro UDCON.

En las bibliotecas LUFA y V-USB no hubo problemas con la desconexión y la reconexión a USB del software. Supongo que USB_Init hizo esto solo en esos.

    
respondido por el jpc

Lea otras preguntas en las etiquetas