Fix for occasional timeout on writes...

...Downstream was not always changing state correctly after closely
spaced interrupts.

Also improve flash-write-lockout function to avoid dependency on
optimisation level.
USG_1.0
Robert Fisk 8 years ago
parent 6b67970f6b
commit 85f965eaa0

@ -46,6 +46,8 @@ extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
extern DMA_HandleTypeDef hdma_spi1_rx; extern DMA_HandleTypeDef hdma_spi1_rx;
extern DMA_HandleTypeDef hdma_spi1_tx; extern DMA_HandleTypeDef hdma_spi1_tx;
extern volatile uint8_t UsbInterruptHasHappened;
uint8_t BusFaultAllowed = 0; uint8_t BusFaultAllowed = 0;
@ -83,9 +85,8 @@ void DMA2_Stream3_IRQHandler(void)
void OTG_FS_IRQHandler(void) void OTG_FS_IRQHandler(void)
{ {
//INT_ACTIVE_ON;
HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS); HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
//INT_ACTIVE_OFF; UsbInterruptHasHappened = 1;
} }
@ -93,6 +94,11 @@ void OTG_FS_IRQHandler(void)
//The deliberate flash lockout will cause a bus fault that we need to process. //The deliberate flash lockout will cause a bus fault that we need to process.
void EnableOneBusFault(void) void EnableOneBusFault(void)
{ {
//It should not be enabled already!
if (BusFaultAllowed)
{
while (1);
}
SCB->SHCSR = SCB_SHCSR_BUSFAULTENA_Msk; SCB->SHCSR = SCB_SHCSR_BUSFAULTENA_Msk;
BusFaultAllowed = 1; BusFaultAllowed = 1;
} }
@ -104,7 +110,7 @@ void BusFault_Handler(void)
BusFaultAllowed = 0; BusFaultAllowed = 0;
return; return;
} }
while(1); while (1);
} }

@ -44,16 +44,17 @@
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void); static void SystemClock_Config(void);
static void GPIO_Init(void); static void GPIO_Init(void);
void DisableFlashWrites(void); static void DisableFlashWrites(void);
void CheckFirmwareMatchesHardware(void); static void CheckFirmwareMatchesHardware(void);
volatile uint8_t UsbInterruptHasHappened = 0;
uint8_t IterationCount = 0;
int main(void) int main(void)
{ {
uint32_t iterationCount = 0;
//First things first! //First things first!
DisableFlashWrites(); DisableFlashWrites();
CheckFirmwareMatchesHardware(); CheckFirmwareMatchesHardware();
@ -77,12 +78,17 @@ int main(void)
Downstream_SPIProcess(); Downstream_SPIProcess();
Downstream_PacketProcessor_CheckNotifyDisconnectReply(); Downstream_PacketProcessor_CheckNotifyDisconnectReply();
//Count number of main loops since last USB interrupt
if (UsbInterruptHasHappened)
{
UsbInterruptHasHappened = 0;
IterationCount = 0;
}
//Some USB host state transitions take 3 iterations to fully apply. //Some USB host state transitions take 3 iterations to fully apply.
//We'll be generous and give it 5 before sleeping. //We'll be generous and give it 5 before sleeping.
iterationCount++; if (IterationCount++ > 4)
if (iterationCount > 4)
{ {
iterationCount = 0;
__WFI(); //sleep time! __WFI(); //sleep time!
} }
} }
@ -97,10 +103,11 @@ void DisableFlashWrites(void)
FLASH->KEYR = 999; FLASH->KEYR = 999;
//Confirm that flash cannot be unlocked //Confirm that flash cannot be unlocked
//This unlock attempt will also cause a bus fault. //This unlock attempt will also cause two bus faults.
EnableOneBusFault();
if ((FLASH->CR & FLASH_CR_LOCK) == 0) while(1); if ((FLASH->CR & FLASH_CR_LOCK) == 0) while(1);
EnableOneBusFault();
FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY1;
EnableOneBusFault();
FLASH->KEYR = FLASH_KEY2; FLASH->KEYR = FLASH_KEY2;
if ((FLASH->CR & FLASH_CR_LOCK) == 0) while(1); if ((FLASH->CR & FLASH_CR_LOCK) == 0) while(1);
} }

@ -76,16 +76,12 @@ void OTG_FS_IRQHandler(void)
void DMA2_Stream2_IRQHandler(void) void DMA2_Stream2_IRQHandler(void)
{ {
// INT_ACTIVE_ON;
HAL_DMA_IRQHandler(&spiRxDmaHandle); HAL_DMA_IRQHandler(&spiRxDmaHandle);
// INT_ACTIVE_OFF;
} }
void DMA2_Stream3_IRQHandler(void) void DMA2_Stream3_IRQHandler(void)
{ {
// INT_ACTIVE_ON;
HAL_DMA_IRQHandler(&spiTxDmaHandle); HAL_DMA_IRQHandler(&spiTxDmaHandle);
// INT_ACTIVE_OFF;
} }
void EXTI3_IRQHandler(void) void EXTI3_IRQHandler(void)
@ -101,6 +97,11 @@ void EXTI3_IRQHandler(void)
//The deliberate flash lockout will cause a bus fault that we need to process. //The deliberate flash lockout will cause a bus fault that we need to process.
void EnableOneBusFault(void) void EnableOneBusFault(void)
{ {
//It should not be enabled already!
if (BusFaultAllowed)
{
while (1);
}
SCB->SHCSR = SCB_SHCSR_BUSFAULTENA_Msk; SCB->SHCSR = SCB_SHCSR_BUSFAULTENA_Msk;
BusFaultAllowed = 1; BusFaultAllowed = 1;
} }
@ -112,7 +113,7 @@ void BusFault_Handler(void)
BusFaultAllowed = 0; BusFaultAllowed = 0;
return; return;
} }
while(1); while (1);
} }

@ -44,15 +44,11 @@
#include "interrupts.h" #include "interrupts.h"
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void); static void SystemClock_Config(void);
void GPIO_Init(void); static void GPIO_Init(void);
void DisableFlashWrites(void); static void DisableFlashWrites(void);
void CheckFirmwareMatchesHardware(void); static void CheckFirmwareMatchesHardware(void);
@ -92,10 +88,11 @@ void DisableFlashWrites(void)
FLASH->KEYR = 999; FLASH->KEYR = 999;
//Confirm that flash cannot be unlocked //Confirm that flash cannot be unlocked
//This unlock attempt will also cause a bus fault. //This unlock attempt will also cause two bus faults.
EnableOneBusFault();
if ((FLASH->CR & FLASH_CR_LOCK) == 0) while(1); if ((FLASH->CR & FLASH_CR_LOCK) == 0) while(1);
EnableOneBusFault();
FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY1;
EnableOneBusFault();
FLASH->KEYR = FLASH_KEY2; FLASH->KEYR = FLASH_KEY2;
if ((FLASH->CR & FLASH_CR_LOCK) == 0) while(1); if ((FLASH->CR & FLASH_CR_LOCK) == 0) while(1);
} }

Loading…
Cancel
Save