2016-05-16 5 views
0

Ein Problem mit dem Atmel SAMB11 auf einem erklärten Pro-Devboard. Ich habe ein ziemlich einfaches Beispiel von Atmel geladen, wo ein 32KHz Timer initialisiert wird, um den μC aus dem Schlaf zu wecken und eine LED einzuschalten. Problem ist, der Controller schläft überhaupt nicht. Es aktiviert nur die LED sofort und wartet nicht auf einen Interrupt.Cortex M0 geht nicht in den Schlafmodus

#include <asf.h> 

// Callback Func to enable LED 
static void aon_sleep_timer_callback(void) 
{ 
    gpio_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE); 
} 
//Configure LED 
static void configure_gpio_pins(void) 
{ 
    struct gpio_config config_gpio_pin; 
    gpio_get_config_defaults(&config_gpio_pin); 
    config_gpio_pin.direction = GPIO_PIN_DIR_OUTPUT; 
    gpio_pin_set_config(LED_0_PIN, &config_gpio_pin); 
    gpio_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE); 
} 
// Configure Timer with 10sec to overflow 
static void configure_aon_sleep_timer(void) 
{ 
    struct aon_sleep_timer_config config_aon_sleep_timer; 
    aon_sleep_timer_get_config_defaults(&config_aon_sleep_timer); 
    config_aon_sleep_timer.counter = 320000; // Wait about 10sec 
    aon_sleep_timer_init(&config_aon_sleep_timer); 
} 
// Configure Callback and enable Interrupt 
static void configure_aon_sleep_timer_callback(void) 
{ 
    aon_sleep_timer_register_callback(aon_sleep_timer_callback); 
    NVIC_EnableIRQ(AON_SLEEP_TIMER_IRQn); 
} 

int main(void) 
{ 
    // Setup Clock, LED and Timer 
    system_clock_config(CLOCK_RESOURCE_XO_26_MHZ, CLOCK_FREQ_26_MHZ); 
    configure_gpio_pins(); 
    configure_aon_sleep_timer(); 
    configure_aon_sleep_timer_callback(); 

    // wait for timer to be active 
    while(!aon_sleep_timer_sleep_timer_active()); 
    // Go to sleep 
    asm volatile ("wfi"); 
    asm volatile ("nop"); 
    // Enable LED immediately if sleep doesn't work 
    gpio_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE); 
    while (true) {} 
} 

Code scheint selbsterklärend, aber der WFI-Befehl funktioniert hier nicht. Jeder kann helfen?

+1

Was macht 'aon_sleep_timer_sleep_timer_active()' - fragt es nur ein Statusregister ab?Es wäre praktisch, zwei verschiedene LEDs zu verwenden, damit Sie erkennen können, ob Sie den Interrupt sofort oder aufgrund eines anderen Ereignisses durchbrechen. – Notlikethat

Antwort

0

Der WFI-Aufruf funktioniert, er empfängt fast unmittelbar nach dem Aufruf einen Interrupt, der dazu führt, dass der WFI-Aufruf aufhört zu blockieren, und dann wird die Ausführung in der nächsten Zeile fortgesetzt.

Sie könnten alles unter // Go to sleep sicher entfernen, wodurch die Hauptfunktion zurückkehren würde. Der AON-Timer würde immer noch seinen Rückruf ausführen. Es gibt jedoch einige mögliche Nachteile dieses Ansatzes:

  • Das würde SAMB11 nicht in einen niedrigeren Leistungsmodus wechseln.
  • Dies entfernt Ihre While-Schleife am Ende des Main. In seinem aktuellen Status wird die while-Schleife nicht benötigt, aber Sie möchten möglicherweise später Code hinzufügen.
  • Hier ist ein Beispiel, das den AON konfiguriert, den SAMB11 so konfiguriert, dass er Low-Power-Modi verwendet, und dann Schleifen, die auf Plattform- und/oder BLE-Ereignisse warten. Momentan gibt es keine Ereignisse für den Empfang der Schleife. Wenn Sie möchten, dass die Schleife Ereignisse empfängt, können Sie den AON-Rückruf ändern, um ein Ereignis mit der Funktion at_ble_event_user_defined_post zu posten oder main() ändern, um das BLE-Modul vor dem Eintritt in die Schleife zu konfigurieren.

    Verwenden Sie den ASF-Assistenten, um eines der BLE-Module zu Ihrem Projekt hinzuzufügen, um dieses Beispiel zu kompilieren.

    #include <asf.h> 
    #include "platform.h" 
    
    // Configure LED 
    static void configure_gpio_pins(void) 
    { 
        struct gpio_config config_gpio_pin; 
        gpio_get_config_defaults(&config_gpio_pin); 
        config_gpio_pin.direction = GPIO_PIN_DIR_OUTPUT; 
        gpio_pin_set_config(LED_0_PIN, &config_gpio_pin); 
        gpio_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE); 
    } 
    
    // Callback Func to toggle LED 
    static bool led_is_on = false; 
    static void aon_sleep_timer_callback(void) 
    { 
        configure_gpio_pins(); 
        if(led_is_on) { 
         gpio_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE); 
         led_is_on = false; 
        } else { 
         gpio_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE); 
         led_is_on = true; 
        } 
    } 
    
    // Configure Timer to fire periodically 
    static void configure_aon_sleep_timer(void) 
    { 
        struct aon_sleep_timer_config config_aon_sleep_timer; 
        aon_sleep_timer_get_config_defaults(&config_aon_sleep_timer); 
        config_aon_sleep_timer.counter = 32000; // Wait about 1 sec 
        config_aon_sleep_timer.mode = AON_SLEEP_TIMER_RELOAD_MODE; 
        aon_sleep_timer_init(&config_aon_sleep_timer); 
    } 
    // Configure Callback and enable Interrupt 
    static void configure_aon_sleep_timer_callback(void) 
    { 
        aon_sleep_timer_register_callback(aon_sleep_timer_callback); 
        NVIC_EnableIRQ(AON_SLEEP_TIMER0_IRQn); 
    } 
    
    int main(void) 
    { 
        // Setup Clock 
        system_clock_config(CLOCK_RESOURCE_XO_26_MHZ, CLOCK_FREQ_26_MHZ); 
    
        plf_drv_status plf_status; 
        if((plf_status = platform_driver_init()) == STATUS_SUCCESS) { 
    
         // Setup LED and Timer 
         configure_gpio_pins(); 
         configure_aon_sleep_timer(); 
         configure_aon_sleep_timer_callback(); 
    
         // wait for timer to be active 
         while(!aon_sleep_timer_sleep_timer_active()); 
    
         // Go to sleep 
         release_sleep_lock(); 
         while(true) { 
          // Replace platform_event_wait with at_ble_event_get if you would like to read the received event. 
          plf_status = platform_event_wait(0); 
         } 
        } 
    } 
    

    WFI In Bezug auf das folgende Beispiel zeigt, wie die meisten der Interrupts deaktivieren und verwenden WFI main() zu blockieren. Die LED wird jedes Mal umschalten, wenn ein Interrupt empfangen wird. Ich empfehle nicht, dies zu verwenden, da ich nicht sicher bin, warum diese Interrupts anfänglich aktiviert sind. Dies soll nur zeigen, wie WFI auf einem SAMB11 blockieren kann.

    #include <asf.h> 
    #include "platform.h" 
    
    // Configure LED 
    static void configure_gpio_pins(void) 
    { 
        struct gpio_config config_gpio_pin; 
        gpio_get_config_defaults(&config_gpio_pin); 
        config_gpio_pin.direction = GPIO_PIN_DIR_OUTPUT; 
        gpio_pin_set_config(LED_0_PIN, &config_gpio_pin); 
        gpio_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE); 
    } 
    
    // Callback Func to toggle LED 
    static bool led_is_on = false; 
    static void toggle_led(void) 
    { 
        configure_gpio_pins(); 
        if(led_is_on) { 
         gpio_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE); 
         led_is_on = false; 
        } else { 
         gpio_pin_set_output_level(LED_0_PIN, LED_0_ACTIVE); 
         led_is_on = true; 
        } 
    } 
    
    int main(void) 
    { 
        // Setup Clock 
        system_clock_config(CLOCK_RESOURCE_XO_26_MHZ, CLOCK_FREQ_26_MHZ); 
    
        // Clear all interrupts. 
        NVIC->ICER[0] = 0xFFFFFFFF; 
    
        // During testing, interrupts were received about once per second; stopped receiving interrupts (LED stopped flashing) after about 2 minutes. 
        int loop_count = 0; 
        while(true) { 
         __WFI(); 
         toggle_led(); 
        } 
    } 
    
    0

    Nur um die Antwort von Prestige Worldwide hinzuzufügen.

    Sicherstellen, dass AO_GPIO0/1/2 niedrig sind (Pulldown empfohlen), und es tritt kein AON-Sleep-Timer-Interrupt auf, da dies den SAMB11 von ULP aufweckt.

    Beachten Sie auch, dass der ULP-Modus beim Ausführen einer Debugsitzung über SWD nicht wie erwartet funktioniert.

    Ich hatte alle Arten von seltsamen Verhalten beim Ausführen der Debug und Schlaf/Aufwachen, aber überhaupt keine Probleme, wenn Sie den gleichen Code ausführen, während nicht zu debuggen. Beachten Sie, dass dies mit Atmel ICE erfolgte. Die Xplored-Karte enthält EDBG, und dieser Debugger scheint mit ULP in Ordnung zu sein.

    Der Lebenslauf Callback hat nie für mich gefeuert, vielleicht ein Fehler in der ASF. Aber ich brauche es nicht, da ich alle GPIO/Geräte nach dem Warten der Plattform einrichten kann.

    +0

    Dies liefert keine Antwort auf die Frage. Sobald Sie genügend [Reputation] (http://stackoverflow.com/help/whats-reputation) haben, können Sie [jeden Beitrag kommentieren] (http://stackoverflow.com/help/privileges/comment); stattdessen [geben Sie Antworten, die keine Klärung durch den Fragesteller erfordern] (http://meta.stackexchange.com/questions/214173/why-doe-i-need-50-reputation-to-comment-what-can- i-do-stattdessen). - [Aus Review] (/ review/low-quality-posts/13200186) – Inian

    +0

    Ich habe 3 Gründe angegeben, warum 'Cortex M0 nicht in den Schlafmodus wechselt', was der Autor überprüfen muss, um zu sehen, ob er das Problem löst . Wie ist das keine Antwort? –

    Verwandte Themen