diff --git a/software/common/validation/dma350_tests.c b/software/common/validation/dma350_tests.c index 686f0365c4824836f9afbeec35f4044cc0f2c7d4..a8a849e6a734a189f7e2fc7436c68d0a606794c6 100644 --- a/software/common/validation/dma350_tests.c +++ b/software/common/validation/dma350_tests.c @@ -46,6 +46,8 @@ __asm unsigned int address_test_read(unsigned int addr); unsigned int address_test_read(unsigned int addr); #endif +void HardFault_Handler_c(unsigned int * hardfault_args, unsigned lr_value); + //typedef unsigned long int uintptr_t; // Array for command with a Header + 5 modified registers uint32_t LinkCmd[6]; @@ -56,8 +58,12 @@ volatile int dma_done_irq_occurred; volatile int dma_done_irq_expected; volatile int dma_error_irq_occurred; volatile int dma_error_irq_expected; +volatile int hardfault_occurred; +volatile int hardfault_expected; +volatile int temp_data; + -void delay(void); +void delay(uint32_t t); void SystemInitialization(void); int main(void) { @@ -67,6 +73,8 @@ int main(void) { uint32_t trig_in_num; uint32_t trig_out_num; unsigned int actual_addr; + hardfault_occurred = 0; + hardfault_expected = 0; // Call Function for the testbench Specific Initialization // Note: Change to the system specific function for initialization SystemInitialization(); @@ -286,6 +294,40 @@ int main(void) { printf("Number of DMA trigger inputs: %d \n", trig_in_num); printf("Number of DMA trigger outputs: %d \n", trig_out_num); + printf("---STARTING 1D Command Tests With interrupts---\n"); + printf("Test BURST with 1D basic commands from COPY_ADDR_SRC to COPY_ADDR_DST...\n"); + for (uint32_t ch=0; ch < ch_num; ch++) { + // + // Write all settings to the DMA registers + AdaChannelInit(ch_settings, ch_srcattr, ch_desattr, ch, SECURE); + Ada1DIncrCommand(command_base, command_1d_incr, ch, SECURE); + SetAdaWrapRegs(command_1d_wrap, ch, SECURE); + AdaSetIntEn(ch_irqs, ch, SECURE); + + + dma_done_irq_expected = 1; + dma_done_irq_occurred = 0; + NVIC_ClearPendingIRQ(DMA_IRQn); + NVIC_EnableIRQ(DMA_IRQn); + + + printf("DMA %d configured. Starting the transfer.\n", ch); + + + // Start DMA operation and wait for done IRQ + AdaEnable(ch, SECURE); + + delay(256); + printf("DMA Interrupt Handled\n"); + uint8_t ch_enabled = 1; + while (ch_enabled == 1) { + ch_enabled = AdaGetEnable(ch, SECURE); + } + printf("DMA transfer finished\n"); + } + + NVIC_DisableIRQ(DMA_IRQn); + printf("---STARTING 1D Command Tests No interrupts---\n"); // ********************************************************************************************** // Stage #1: Copy data from COPY_ADDR_SRC to COPY_ADDR_DST using all channels @@ -381,33 +423,6 @@ int main(void) { printf("DMA transfer finished\n"); } - - printf("---STARTING 1D Command Tests With interrupts---\n"); - printf("Test BURST with 1D basic commands from COPY_ADDR_SRC to COPY_ADDR_DST...\n"); - for (uint32_t ch=0; ch < ch_num; ch++) { - // - // Write all settings to the DMA registers - AdaChannelInit(ch_settings, ch_srcattr, ch_desattr, ch, SECURE); - Ada1DIncrCommand(command_base, command_1d_incr, ch, SECURE); - SetAdaWrapRegs(command_1d_wrap, ch, SECURE); - AdaSetIntEn(ch_irqs, ch, SECURE); - - printf("DMA %d configured. Starting the transfer.\n", ch); - - dma_done_irq_expected = 1; - dma_done_irq_occurred = 0; - NVIC_ClearPendingIRQ(DMA_IRQn); - NVIC_EnableIRQ(DMA_IRQn); - // Start DMA operation and wait for done IRQ - AdaEnable(ch, SECURE); - - __WFI(); - uint8_t ch_enabled = 1; - while (ch_enabled == 1) { - ch_enabled = AdaGetEnable(ch, SECURE); - } - printf("DMA transfer finished\n"); - } UartEndSimulation(); return 0; @@ -469,19 +484,96 @@ unsigned int address_test_read(unsigned int addr) } #endif -void DMA_Handler(void){ +// Function for the Channel interrupt handlers +void DMAClearChIrq(uint32_t ch) { // Check the source of the interrupt and clear interrupts - printf("DMA Interrupted \n") - AdaStatType ST = AdaReadStatus(ch, NON_SECURE); + AdaStatType ST = AdaReadStatus(ch, SECURE); if (ST.STAT_DONE == 1) { - AdaClearChDone(ch, NON_SECURE); + AdaClearChDone(ch, SECURE); } else if (ST.STAT_ERR == 1) { - AdaClearChError(ch, NON_SECURE); + AdaClearChError(ch, SECURE); } else if (ST.STAT_DISABLED == 1) { - AdaClearChDisabled(ch, NON_SECURE); + AdaClearChDisabled(ch, SECURE); } else if (ST.STAT_STOPPED == 1) { - AdaClearChStopped(ch, NON_SECURE); + AdaClearChStopped(ch, SECURE); } else { printf("Unknown IRQ on CH%d!\n", ch); } -} \ No newline at end of file +} + +void DMA_Handler(void){ + __disable_irq(); + printf("DMA Interrupted \n"); + DMAClearChIrq(0); + DMAClearChIrq(1); + __enable_irq(); +} + +#if defined ( __CC_ARM ) +/* ARM or Keil toolchain */ +__asm void HardFault_Handler(void) +{ + MOVS r0, #4 + MOV r1, LR + TST r0, r1 + BEQ stacking_used_MSP + MRS R0, PSP ; // first parameter - stacking was using PSP + B get_LR_and_branch +stacking_used_MSP + MRS R0, MSP ; // first parameter - stacking was using MSP +get_LR_and_branch + MOV R1, LR ; // second parameter is LR current value + LDR R2,=__cpp(HardFault_Handler_c) + BX R2 + ALIGN +} +#else +/* gcc toolchain */ +void HardFault_Handler(void) __attribute__((naked)); +void HardFault_Handler(void) +{ + __asm(" movs r0,#4\n" + " mov r1,lr\n" + " tst r0,r1\n" + " beq stacking_used_MSP\n" + " mrs r0,psp\n" /* first parameter - stacking was using PSP */ + " ldr r1,=HardFault_Handler_c \n" + " bx r1\n" + "stacking_used_MSP:\n" + " mrs r0,msp\n" /* first parameter - stacking was using PSP */ + " ldr r1,=HardFault_Handler_c \n" + " bx r1\n" + ".pool\n" ); +} + +#endif + +void HardFault_Handler_c(unsigned int * hardfault_args, unsigned lr_value) +{ + unsigned int stacked_pc; + unsigned int stacked_r0; + hardfault_occurred++; + puts ("[Hard Fault Handler]"); + if (hardfault_expected==0) { + puts ("ERROR : Unexpected HardFault interrupt occurred.\n"); + UartEndSimulation(); + while (1); + } + stacked_r0 = ((unsigned long) hardfault_args[0]); + stacked_pc = ((unsigned long) hardfault_args[6]); + printf(" - Stacked R0 : 0x%x\n", stacked_r0); + printf(" - Stacked PC : 0x%x\n", stacked_pc); + /* Modify R0 to a valid address */ + hardfault_args[0] = (unsigned long) &temp_data; + + return; +} + +void delay(uint32_t t) +{ + int i; + for (i=0;i<t;i++){ + __ISB(); + } + return; +}