add blocking delay for msp430 with max 25mhz
This commit is contained in:
@@ -544,14 +544,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) {
|
|||||||
* - Software should ensure that a small delay is included before accessing the SRAM contents. This delay
|
* - Software should ensure that a small delay is included before accessing the SRAM contents. This delay
|
||||||
* should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode
|
* should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode
|
||||||
* - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code
|
* - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code
|
||||||
* also takes time, so we'll wait 40 cycles (count = 20).
|
* also takes time, so we'll wait 60 cycles (count = 20).
|
||||||
* - Since Low Speed mode is not supported/popular, we will ignore it for now.
|
* - Since Low Speed mode is not supported/popular, we will ignore it for now.
|
||||||
*
|
*
|
||||||
* Note: this errata also seems to apply to G0, U5, H5 etc.
|
* Note: this errata also seems to apply to G0, U5, H5 etc.
|
||||||
*/
|
*/
|
||||||
volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver
|
volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver
|
||||||
while (cycle_count > 0U) {
|
while (cycle_count > 0U) {
|
||||||
cycle_count--; // each count take 2 cycle (1 cycle for sub, 1 cycle for compare/jump)
|
cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -154,14 +154,11 @@ void dcd_init (uint8_t rhport)
|
|||||||
|
|
||||||
USBVECINT = 0;
|
USBVECINT = 0;
|
||||||
|
|
||||||
if(USBPWRCTL & USBBGVBV) // Bus power detected?
|
if(USBPWRCTL & USBBGVBV) {// Bus power detected?
|
||||||
{
|
|
||||||
USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt.
|
USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt.
|
||||||
USBIE |= RSTRIE; // Enable reset and wait for it before continuing.
|
USBIE |= RSTRIE; // Enable reset and wait for it before continuing.
|
||||||
USBCNF |= PUR_EN; // Enable pullup.
|
USBCNF |= PUR_EN; // Enable pullup.
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt.
|
USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt.
|
||||||
USBCNF &= ~USB_EN; // Disable USB module until bus power is detected.
|
USBCNF &= ~USB_EN; // Disable USB module until bus power is detected.
|
||||||
}
|
}
|
||||||
@@ -639,8 +636,7 @@ static void handle_setup_packet(void)
|
|||||||
_setup_packet[i] = setup_buf[i];
|
_setup_packet[i] = setup_buf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force NAKs until tinyusb can handle the SETUP packet and prepare
|
// Force NAKs until tinyusb can handle the SETUP packet and prepare for a new xfer.
|
||||||
// for a new xfer.
|
|
||||||
USBIEPCNT_0 |= NAK;
|
USBIEPCNT_0 |= NAK;
|
||||||
USBOEPCNT_0 |= NAK;
|
USBOEPCNT_0 |= NAK;
|
||||||
|
|
||||||
@@ -660,16 +656,28 @@ static void handle_setup_packet(void)
|
|||||||
dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true);
|
dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_bus_power_event(void *param)
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
{
|
TU_ATTR_ALWAYS_INLINE static inline void tu_delay(uint32_t ms) {
|
||||||
|
// msp430 can run up to 25Mhz -> 40ns per cycle. 1 ms = 25000 cycles
|
||||||
|
// each loop need 4 cycle: 1 sub, 1 cmp, 1 jump, 1 nop
|
||||||
|
volatile uint32_t cycles = (25000 * ms) >> 2;
|
||||||
|
while (cycles > 0) {
|
||||||
|
cycles--;
|
||||||
|
asm("nop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define tu_delay(ms) osal_task_delay(ms)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void handle_bus_power_event(void *param) {
|
||||||
(void) param;
|
(void) param;
|
||||||
|
|
||||||
osal_task_delay(5); // Bus power settling delay.
|
tu_delay(5); // Bus power settling delay.
|
||||||
|
|
||||||
USBKEYPID = USBKEY;
|
USBKEYPID = USBKEY;
|
||||||
|
|
||||||
if(USBPWRCTL & USBBGVBV) // Event caused by application of bus power.
|
if(USBPWRCTL & USBBGVBV) { // Event caused by application of bus power.
|
||||||
{
|
|
||||||
USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt.
|
USBPWRCTL |= VBOFFIE; // Enable bus-power-removed interrupt.
|
||||||
USBPLLDIVB = USBPLLDIVB; // For some reason the PLL will *NOT* lock unless the divider
|
USBPLLDIVB = USBPLLDIVB; // For some reason the PLL will *NOT* lock unless the divider
|
||||||
// register is re-written. The assumption here is that this
|
// register is re-written. The assumption here is that this
|
||||||
@@ -678,21 +686,17 @@ static void handle_bus_power_event(void *param)
|
|||||||
USBPLLCTL |= (UPLLEN | UPFDEN); // Enable the PLL.
|
USBPLLCTL |= (UPLLEN | UPFDEN); // Enable the PLL.
|
||||||
|
|
||||||
uint16_t attempts = 0;
|
uint16_t attempts = 0;
|
||||||
|
do { // Poll the PLL, checking for a successful lock.
|
||||||
do // Poll the PLL, checking for a successful lock.
|
|
||||||
{
|
|
||||||
USBPLLIR = 0;
|
USBPLLIR = 0;
|
||||||
osal_task_delay(1);
|
tu_delay(1);
|
||||||
attempts++;
|
attempts++;
|
||||||
} while ((attempts < 10) && (USBPLLIR != 0));
|
} while ((attempts < 10) && (USBPLLIR != 0));
|
||||||
|
|
||||||
if(!USBPLLIR) // A successful lock is indicated by all PLL-related interrupt
|
// A successful lock is indicated by all PLL-related interrupt flags being cleared.
|
||||||
{ // flags being cleared.
|
if(!USBPLLIR) {
|
||||||
dcd_init(0); // Re-initialize the USB module.
|
dcd_init(0); // Re-initialize the USB module.
|
||||||
}
|
}
|
||||||
}
|
} else { // Event caused by removal of bus power.
|
||||||
else // Event caused by removal of bus power.
|
|
||||||
{
|
|
||||||
USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt.
|
USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt.
|
||||||
USBPLLCTL &= ~(UPLLEN | UPFDEN); // Disable the PLL.
|
USBPLLCTL &= ~(UPLLEN | UPFDEN); // Disable the PLL.
|
||||||
USBCNF = 0; // Disable the USB module.
|
USBCNF = 0; // Disable the USB module.
|
||||||
@@ -741,13 +745,12 @@ void dcd_int_handler(uint8_t rhport)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBVECINT_PWR_VBUSOn:
|
case USBVECINT_PWR_VBUSOn:
|
||||||
case USBVECINT_PWR_VBUSOff:
|
case USBVECINT_PWR_VBUSOff: {
|
||||||
USBKEYPID = USBKEY;
|
USBKEYPID = USBKEY;
|
||||||
// Prevent (possibly) unstable power from generating spurious interrupts.
|
// Prevent (possibly) unstable power from generating spurious interrupts.
|
||||||
USBPWRCTL &= ~(VBONIE | VBOFFIE);
|
USBPWRCTL &= ~(VBONIE | VBOFFIE);
|
||||||
USBKEYPID = 0;
|
USBKEYPID = 0;
|
||||||
|
|
||||||
{
|
|
||||||
dcd_event_t event;
|
dcd_event_t event;
|
||||||
|
|
||||||
event.rhport = 0;
|
event.rhport = 0;
|
||||||
|
Reference in New Issue
Block a user