Hallo zusammen,
ich bin mit meinem Problem am Wissens- und Recherche-Ende, deshalb muss
ich einen eigenen Thread dafür erstellen.
Folgender Stand:
Ich habe den Atmel DFU Bootloader am XMega256A3U erfolgreich zum laufen
gebracht. Ich kann über Flip neue Software flashen, danach aus einem
USB-Terminal einen Reset-Befehl eingeben, um in den Bootloader zu
springen und dann mit Flip wieder neue Software flashen.
Das Problem:
Ich habe die ganze Clock-Initialisierung der Applikation inkl.
sysclk_enable_usb und sysclk_disable_usb durch eigenen Code getauscht.
Statt der ASF-Geschichte mit der 48 MHz Clock, die über ein USB-SoF
getrimmt wird, läuft der uC jetzt mit 32 MHz clock, die mit dem internen
32 kHz Oszi getrimmt wird.
Seitdem kann ich zwar das -erste- Mal mit Flip software flashen (ohne
Applikation drauf), und meine Applikation scheint bei einem Boot-Befehl
auch in den Bootloader zu springen (zumindest ist die Applikation tilt).
Allerdings kann Flip danach jetzt keine USB-Verbindung mehr aufbauen,
d.h. ein Update meiner Software ist unmöglich geworden.
Was ich nicht verstehe: Meine Änderungen am Applikations-Code sollten
doch nicht die USB-Initialisierung des Bootloader beeinträchtigen, oder?
Die Fuses:
FF 00 BE F6 E3
(BOD 2,4V - Bootloader Reset)
Hier sind die Codes:
So gehts in den Bootloader (das hat bisher funktioniert!):
1 | void(* jump_to_bootloader)(void) = (void (*)(void))(BOOT_SECTION_START/2 + 0x1FC/2);
|
2 |
|
3 | // ... dann später:
|
4 | udc_detach();
|
5 | udc_stop();
|
6 |
|
7 | EIND = BOOT_SECTION_START>>17;
|
8 | jump_to_bootloader();
|
Die Init-Routine für meine Clock:
32 MHz Oszi mit internem 32 kHz kalibriert. Der 32 MHz Oszi ist dann
Referenz für die PLL, mit der USB auf 48 MHz getrieben wird. Die
Applikation funktioniert soweit einwandfrei.
1 | void init_clock(void)
|
2 | {
|
3 | OSC.CTRL |= OSC_RC32MEN_bm; // enable the internal 32 MHz oscillator
|
4 | OSC.CTRL |= OSC_RC32KEN_bm; // enable the internal 32 kHz oscillator (RC oscillator for synchronisation purposes)
|
5 |
|
6 | //OSC.CTRL |= OSC_RC2MEN_bm;
|
7 |
|
8 | while(!(OSC.STATUS & OSC_RC32MRDY_bm)); // wait for 32 MHz oscillator to stabilise (ready)
|
9 | while(!(OSC.STATUS & OSC_RC32KRDY_bm)); // wait for 32 kHz oscillator to stabilise (ready)
|
10 |
|
11 | CCP = CCP_IOREG_gc; // protect I/O register
|
12 | CLK.CTRL = CLK_SCLKSEL_RC32M_gc; // Use 32 MHz oscillator as system clock
|
13 |
|
14 |
|
15 | OSC.DFLLCTRL |= OSC_RC2MCREF_RC32K_gc; // Interal 32 kHz oscillator as reference for 32 MHz clock source
|
16 | OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; // Internal 32 kHz oscillator as reference for 32 MHz clock source
|
17 |
|
18 | // Setting this bit enables the DFLL and auto-calibration of the internal oscillator.
|
19 | // The reference clock must be enabled and stable before the DFLL is enabled.
|
20 | DFLLRC32M.CTRL |= DFLL_ENABLE_bm;
|
21 | }
|
1 | void sysclk_enable_usb(uint8_t frequency)
|
2 | {
|
3 | uint8_t prescaler;
|
4 | /*
|
5 | * Enable or disable prescaler depending on if the USB frequency is 6
|
6 | * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling.
|
7 | */
|
8 | if (frequency == 6) {
|
9 | prescaler = CLK_USBPSDIV_8_gc;
|
10 | }
|
11 | else {
|
12 | prescaler = 0;
|
13 | }
|
14 |
|
15 | // PLL for USB
|
16 | OSC.PLLCTRL = OSC_PLLSRC_RC32M_gc; // PLL source = 32 MHz oscillator/4 (always /4 by hardware)
|
17 | OSC.PLLCTRL |= OSC_PLLFAC2_bm | OSC_PLLFAC1_bm; // PLL multiply by 6 --> 32 MHz / 4 x 6 = 48 MHz for full speed USB
|
18 |
|
19 | OSC.CTRL |= OSC_PLLEN_bm; // Enable PLL
|
20 | while(!(OSC.STATUS & OSC_PLLRDY_bm)); // wait for PLL to stabilise (ready)
|
21 |
|
22 | CCP = CCP_IOREG_gc;
|
23 | CLK.USBCTRL = (CLK_USBSRC_PLL_gc | CLK_USBSEN_bm | prescaler); // USB clock source: PLL, clock enable, prescaler
|
24 | // Using 32 MHz oscillator with 48 MHz calibration values only works with USB connected (USB Start of Frame, SOF).
|
25 | // Device MUST be accurate for 1 Mb UART baud without USB, so 32 MHz have to be calibrated via 32 kHz clock
|
26 | *((uint8_t *)&PR.PRGEN) &= ~PR_USB_bm;
|
27 | }
|
28 |
|
29 |
|
30 | /**
|
31 | * \brief Disable clock for the USB module
|
32 | */
|
33 | void sysclk_disable_usb(void)
|
34 | {
|
35 | *((uint8_t *)&PR.PRGEN) |= PR_USB_bm;
|
36 | CCP = CCP_IOREG_gc;
|
37 | CLK.USBCTRL = 0;
|
38 | }
|