123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- #include "all-headers.h"
- #define LED_DELAY 1000
- static void configureFaultRegisters (BOOT_MODE) {
- // ACTLR register (reset value: 0)
- // Bit 1: Disables write buffer use during default memory map accesses. This causes all bus faults to be
- // precise, but decreases the performance of the processor because stores to memory must complete before
- // the next instruction can be executed.
- // Bit 0: Disables interruption of multi-cycle instructions. This increases the interrupt latency of the processor
- // because load/store and multiply/divide operations complete before interrupt stacking occurs.
- // SCB_ACTLR = (1 << 1) ;
- // SHCSR register
- // SHCSR |=
- // (1 << 16) | // Memory Management Fault exception enable bit, set to 1 to enable; set to 0 to disable
- // (1 << 17) | // BusFault exception enable bit, set to 1 to enable; set to 0 to disable
- // (1 << 18) ; // UsageFault exception enable bit, set to 1 to enable; set to 0 to disable
- // SCB_CCR register
- SCB_CCR |=
- (1 << 4) | // Enable UsageFault when the processor executes an SDIV or UDIV instruction with a divisor of 0
- (1 << 3) ; // Enable UsageFault when a memory access to unaligned addresses are performed
- }
- MACRO_BOOT_ROUTINE (configureFaultRegisters) ;
- static void endlessLoop (FAULT_MODE) {
- pinMode (L0_LED, DigitalMode::OUTPUT) ;
- pinMode (L1_LED, DigitalMode::OUTPUT) ;
- pinMode (L2_LED, DigitalMode::OUTPUT) ;
- pinMode (L3_LED, DigitalMode::OUTPUT) ;
- pinMode (L4_LED, DigitalMode::OUTPUT) ;
- digitalWrite (L0_LED, true) ;
- digitalWrite (L1_LED, true) ;
- while (1) {
- digitalToggle (L0_LED) ;
- digitalToggle (L1_LED) ;
- digitalToggle (L3_LED) ;
- digitalToggle (L4_LED) ;
- busyWaitDuring_faultMode (MODE_ LED_DELAY);
- }
- }
- #define MMFSR (* ((volatile uint8_t *) 0xE000ED28))
- #define MMFAR (* ((volatile uint32_t *) 0xE000ED34))
- #define BFSR (* ((volatile uint8_t *) 0xE000ED29))
- #define BFAR (* ((volatile uint32_t *) 0xE000ED38))
- #define UFSR (* ((volatile uint16_t *) 0xE000ED2A))
- #define AFSR (* ((volatile uint32_t *) 0xE000ED3C))
- static void handleFault (FAULT_MODE_ const char * inTitle, const uint32_t inLinkRegisterValue) {
- // Init Systick (LCD display requires an 1 ms timer)
- configureSystick_faultMode (MODE) ;
- pinMode (L0_LED, DigitalMode::OUTPUT) ;
- pinMode (L1_LED, DigitalMode::OUTPUT) ;
- pinMode (L2_LED, DigitalMode::OUTPUT) ;
- pinMode (L3_LED, DigitalMode::OUTPUT) ;
- pinMode (L4_LED, DigitalMode::OUTPUT) ;
- digitalWrite (L0_LED, true) ;
- digitalWrite (L1_LED, true) ;
- uint32_t displayedPage = 0 ;
- uint32_t displayCounter = 0 ;
- bool encoderA = false ;
- bool display = true ;
- pinMode (ENCODER_A, DigitalMode::INPUT_PULLUP) ;
- pinMode (ENCODER_B, DigitalMode::INPUT_PULLUP) ;
- while (1) {
- // Wait
- busyWaitDuring_faultMode (MODE_ 1);
- // Handle encoder
- const bool currentEncoderA = digitalRead (ENCODER_A) ;
- if (encoderA && !currentEncoderA) {
- display = true ;
- if (digitalRead (ENCODER_B)) {
- displayedPage = (displayedPage + 1) % 4 ;
- }else{
- displayedPage = (displayedPage + 3) % 4 ;
- }
- }
- encoderA = currentEncoderA ;
- // Display
- if (displayCounter > 0) {
- displayCounter -= 1 ;
- }else{
- displayCounter = LED_DELAY;
- digitalToggle (L0_LED) ;
- digitalToggle (L1_LED) ;
- digitalToggle (L3_LED) ;
- digitalToggle (L4_LED) ;
- if (display) {
- display = false ;
- initScreen_faultMode (MODE) ;
- printString_faultMode (MODE_ inTitle) ;
- gotoLineColumn_faultMode (MODE_ 0, 19) ;
- printUnsigned_faultMode (MODE_ displayedPage) ;
- gotoLineColumn_faultMode (MODE_ 1, 0) ;
- switch (displayedPage) {
- case 0 :
- printString_faultMode (MODE_ "SHCSR: 0x") ;
- printHex8_faultMode (MODE_ SCB_SHCSR) ;
- gotoLineColumn_faultMode (MODE_ 2, 0) ;
- printString_faultMode (MODE_ "MMFSR: 0x") ;
- printHex2_faultMode (MODE_ MMFSR) ;
- gotoLineColumn_faultMode (MODE_ 3, 0) ;
- printString_faultMode (MODE_ "MMFAR: 0x") ;
- printHex8_faultMode (MODE_ MMFAR) ;
- break ;
- case 1 :
- printString_faultMode (MODE_ "BFSR: 0x") ;
- printHex2_faultMode (MODE_ BFSR) ;
- gotoLineColumn_faultMode (MODE_ 2, 0) ;
- printString_faultMode (MODE_ "BFAR: 0x") ;
- printHex8_faultMode (MODE_ BFAR) ;
- gotoLineColumn_faultMode (MODE_ 3, 0) ;
- printString_faultMode (MODE_ "CCR: 0x") ;
- printHex8_faultMode (MODE_ SCB_CCR) ;
- break ;
- case 2 :
- printString_faultMode (MODE_ "AFSR: 0x") ;
- printHex8_faultMode (MODE_ AFSR) ;
- gotoLineColumn_faultMode (MODE_ 2, 0) ;
- printString_faultMode (MODE_ "UFSR: 0x") ;
- printHex4_faultMode (MODE_ UFSR) ;
- break ;
- case 3 :
- printString_faultMode (MODE_ "LR: 0x") ;
- printHex8_faultMode (MODE_ inLinkRegisterValue) ;
- gotoLineColumn_faultMode (MODE_ 2, 0) ;
- if ((inLinkRegisterValue & (1 << 2)) != 0) { // Fault occurs in user mode
- uint32_t psp ;
- asm ("mrs %[result], psp" : [result] "=r" (psp) ) ;
- printString_faultMode (MODE_ "PSP: 0x") ;
- printHex8_faultMode (MODE_ psp) ;
- uint32_t * framePtr = (uint32_t *) psp ;
- const uint32_t pc = framePtr [6] ;
- gotoLineColumn_faultMode (MODE_ 3, 0) ;
- printString_faultMode (MODE_ "PC: 0x") ;
- printHex8_faultMode (MODE_ pc) ;
- }else{ // Fault occurs in system mode
- uint32_t msp ;
- asm ("mrs %[result], msp" : [result] "=r" (msp) ) ;
- printString_faultMode (MODE_ "MSP: 0x") ;
- printHex8_faultMode (MODE_ msp) ;
- uint32_t * framePtr = (uint32_t *) msp ;
- const uint32_t pc = framePtr [6] ;
- gotoLineColumn_faultMode (MODE_ 3, 0) ;
- printString_faultMode (MODE_ "PC: 0x") ;
- printHex8_faultMode (MODE_ pc) ;
- }
- break ;
- }
- }
- }
- }
- }
- void HardFault_handler (FAULT_MODE) {
- // Init display
- uint32_t linkRegisterValue ;
- asm ("mov %[result], lr" : [result] "=r" (linkRegisterValue) ) ;
- handleFault (MODE_ "HardFault", linkRegisterValue) ;
- }
- void MemManage_handler (FAULT_MODE) {
- // Init display
- uint32_t linkRegisterValue ;
- asm ("mov %[result], lr" : [result] "=r" (linkRegisterValue) ) ;
- handleFault (MODE_ "MemManage", linkRegisterValue) ;
- }
- void BusFault_handler (FAULT_MODE) {
- // Init display
- uint32_t linkRegisterValue ;
- asm ("mov %[result], lr" : [result] "=r" (linkRegisterValue) ) ;
- handleFault (MODE_ "BusFault", linkRegisterValue) ;
- }
- void UsageFault_handler (FAULT_MODE) {
- // Init display
- uint32_t linkRegisterValue ;
- asm ("mov %[result], lr" : [result] "=r" (linkRegisterValue) ) ;
- handleFault (MODE_ "UsageFault", linkRegisterValue) ;
- }
- // UNUSED INTERRUPT
- void unusedInterrupt (FAULT_MODE_ const uint32_t inInterruptIndex) asm ("unused.interrupt") ;
- void unusedInterrupt (FAULT_MODE_ const uint32_t inInterruptIndex) {
- // Init Systick (LCD display requires an 1 ms timer)
- configureSystick_faultMode (MODE) ;
- // Init display
- initScreen_faultMode (MODE) ;
- // Title
- printString_faultMode (MODE_ "Unhandled interrupt") ;
- gotoLineColumn_faultMode (MODE_ 1, 0) ;
- printUnsigned_faultMode (MODE_ inInterruptIndex) ;
- // Endless loop
- endlessLoop (MODE) ;
- }
- // ASSERTION
- void section_assertionFailure (FAULT_MODE_
- const uint32_t inMessageValue,
- const char * inFileName,
- const int inLine) {
- // Init Systick (LCD display requires an 1 ms timer)
- configureSystick_faultMode (MODE) ;
- // Init display
- initScreen_faultMode (MODE) ;
- // Title
- printString_faultMode (MODE_ "Assertion Failure") ;
- // Associated value
- gotoLineColumn_faultMode (MODE_ 1, 0) ;
- printString_faultMode (MODE_ "Value: ") ;
- printUnsigned_faultMode (MODE_ inMessageValue) ;
- // File
- int32_t idx = (int32_t) strlen (inFileName) ;
- bool loop = true ;
- while ((idx > 0) && loop) {
- idx -= 1 ;
- loop = inFileName [idx] != '/' ;
- }
- gotoLineColumn_faultMode (MODE_ 2, 0) ;
- printString_faultMode (MODE_ & inFileName [idx + 1]) ;
- // Line
- gotoLineColumn_faultMode (MODE_ 3, 0) ;
- printString_faultMode (MODE_ "Line: ") ;
- printUnsigned_faultMode (MODE_ (uint32_t) inLine) ;
- // Endless loop
- endlessLoop (MODE) ;
- }
- void assertion (const bool inAssertion,
- const uint32_t inMessageValue,
- const char * inFileName,
- const int inLine) {
- if (!inAssertion) {
- assertionFailure (inMessageValue, inFileName, inLine) ;
- }
- }
- void assertNonNullPointer (const void * inPointer,
- const char * inFileName,
- const int inLine) {
- if (nullptr == inPointer) {
- assertionFailure (0, inFileName, inLine) ;
- }
- }
|