diff --git a/bootrom/Makefile b/bootrom/Makefile index d8792c44e..2135aab6d 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -11,6 +11,7 @@ ARMSRC = THUMBSRC = cmd.c \ usb_cdc.c \ bootrom.c + ASMSRC = ram-reset.s flash-reset.s ## There is a strange bug with the linker: Sometimes it will not emit the glue to call diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 7796a304a..424258390 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -193,7 +193,8 @@ static void flash_mode(int externally_entered) { byte_t rx[sizeof(UsbCommand)]; usb_enable(); - //for (volatile size_t i=0; i<0x100000; i++) {}; + + for (volatile size_t i=0; i<0x100000; i++) {}; for(;;) { WDT_HIT(); diff --git a/common/usb_cdc.c b/common/usb_cdc.c index 6dbb246a2..17642625a 100644 --- a/common/usb_cdc.c +++ b/common/usb_cdc.c @@ -33,7 +33,6 @@ */ #include "usb_cdc.h" - /* AT91SAM7S256 USB Device Port • Embedded 328-byte dual-port RAM for endpoints @@ -442,6 +441,29 @@ uint8_t btConfiguration = 0; uint8_t btConnection = 0; uint8_t btReceiveBank = AT91C_UDP_RX_DATA_BK0; +static void SpinDelay(int ms) { + int us = ms * 1000; + int ticks = (48 * us) >> 10; + + // Borrow a PWM unit for my real-time clock + AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); + + // 48 MHz / 1024 gives 46.875 kHz + AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); + AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; + AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; + + uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + + for(;;) { + uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + if (now == (uint16_t)(start + ticks)) + return; + + WDT_HIT(); + } +} + //*---------------------------------------------------------------------------- //* \fn usb_disable //* \brief This function deactivates the USB device @@ -480,8 +502,9 @@ void usb_enable() { // Disconnect and reconnect USB controller for 100ms usb_disable(); + SpinDelay(100); // Wait for a short while - for (volatile size_t i=0; i<0x100000; i++) {}; + //for (volatile size_t i=0; i<0x100000; i++) {}; // Reconnect USB reconnect AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU; @@ -550,7 +573,7 @@ bool usb_check() { else if (isr & AT91C_UDP_EPINT0) { pUdp->UDP_ICR = AT91C_UDP_EPINT0; AT91F_CDC_Enumerate(); - pUdp->UDP_ICR |= AT91C_UDP_EPINT0; + //pUdp->UDP_ICR |= AT91C_UDP_EPINT0; } else if (isr & AT91C_UDP_EPINT3 ) { pUdp->UDP_ICR = AT91C_UDP_EPINT3;