You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FreeRTOS-Kernel/FreeRTOS/Demo/PIC32MZ_MPLAB/scrap_from_main_blinky.txt

160 lines
5.5 KiB
Plaintext

#define mainISR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainISRTASK_LED ( 2 )
#define mainT5PRESCALAR ( 6 )
#define mainT5_SEMAPHORE_RATE ( 31250 )
static void prvISRBlockTask( void* pvParameters )
{
/* local variables marked as volatile so the compiler does not optimize them away */
volatile uint64_t resAcc;
volatile uint32_t arg1, arg2;
/* Create the semaphore used to signal this task */
vSemaphoreCreateBinary( xBlockSemaphore );
/* Set up timer 5 to generate an interrupt every 50 ms */
T5CON = 0;
TMR5 = 0;
/* Timer 5 is going to interrupt at 20Hz Hz. (40,000,000 / (64 * 20) */
T5CONbits.TCKPS = mainT5PRESCALAR;
PR5 = mainT5_SEMAPHORE_RATE;
/* Setup timer 5 interrupt priority to be the maximum allowed */
IPC6bits.T5IP = ( configMAX_SYSCALL_INTERRUPT_PRIORITY );
/* Clear the interrupt as a starting condition. */
IFS0bits.T5IF = 0;
/* Enable the interrupt. */
IEC0bits.T5IE = 1;
/* Start the timer. */
T5CONbits.TON = 1;
arg1 = 10;
arg2 = 2;
for( ;; )
{
/* block on the binary semaphore given by an ISR */
xSemaphoreTake( xBlockSemaphore, portMAX_DELAY );
vParTestToggleLED( mainISRTASK_LED );
/* perform some maths operations to exercise the accumulators */
resAcc = resAcc * arg2 + arg1;
}
}
/*-----------------------------------------------------------*/
void vT5InterruptHandler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* This function is the handler for the peripheral timer interrupt.
The interrupt is initially signalled in a separate assembly file
which switches to the system stack and then calls this function.
It gives a semaphore which signals the prvISRBlockTask */
xSemaphoreGiveFromISR( xBlockSemaphore, &xHigherPriorityTaskWoken );
/* Clear the interrupt */
IFS0CLR = _IFS0_T5IF_MASK;
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
#define DMA_BUFF_SIZE 400
uint32_t dmaBuff[2][DMA_BUFF_SIZE];
static void dmaTask(void* pvParameters)
{
uint32_t i;
/* this tasks hammers the dma copying data from one buffer to another */
DMACONbits.SUSPEND = 1; //Suspend ALL DMA transfers
/* currently the data will be placed in the cache and nothing will be copied
* by the dma as it only accesses physical memory, this test is designed to stress the system
* and confirm correct operation in a heavy interrupt environment */
for(i = 0; i < DMA_BUFF_SIZE; i++) {
dmaBuff[0][i] = i;
}
/* set the transfer event control: what event is to start the DMA transfer */
DCH1ECONbits.CHSIRQ = _TIMER_6_VECTOR;
DCH1ECONbits.SIRQEN = 1;
/* set up transfer */
DCH1SSA = KVA_TO_PA((void*) &dmaBuff[0][0]);
DCH1DSA = KVA_TO_PA((void*) &dmaBuff[1][0]);
DCH1SSIZ = DMA_BUFF_SIZE;
DCH1DSIZ = DMA_BUFF_SIZE;
DCH1CSIZ = 4;
/* setup interrupt response */
IPC33bits.DMA1IP = 3;
DCH1INTbits.CHBCIE = 1;
IEC4bits.DMA1IE = 1;
DCH1CONbits.CHPRI = 0b10;
/* once we configured the DMA channel we can enable it */
DCH1CONbits.CHEN = 1;
DMACONbits.ON = 1;
DMACONbits.SUSPEND = 0;
/* setup T6 to trigger the transfers */
T6CON = 0x0000;
IEC0CLR = _IEC0_T6IE_MASK;
IFS0CLR = _IFS0_T6IF_MASK;
TMR6 = 0;
PR6 = 1;
T6CONSET = _T6CON_ON_MASK;
/* once the dma is setup we delete this task */
vTaskDelete(NULL);
}
void __attribute__((vector(_DMA1_VECTOR), interrupt(ipl3))) DMAInterruptHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
uint32_t i;
/* clear the destination buffer */
for(i = 0; i < DMA_BUFF_SIZE; i++) {
dmaBuff[1][i] = 0;
}
xSemaphoreGiveFromISR( xBlockSemaphore, &xHigherPriorityTaskWoken );
/* we have just finished copying from buffer0 to buffer 1 so restart the copy operation */
DCH1INTCLR = _DCH1INT_CHBCIF_MASK;
IFS4CLR = _IFS4_DMA1IF_MASK;
DCH1CONSET = _DCH1CON_CHEN_MASK;
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
* The Blinky ISR Test:
* This demonstrates triggering an ISR from a peripheral timer. A task is created
* which blocks on a semaphore. Separately a peripheral timer is set to cause an
* interrupt every 50ms. The ISR handler (in a separate assembly file) then
* releases the semaphore which causes the task to unblock and toggle an LED. This
* sequence tests operation of the ISR and system stack handling.
*
static void prvISRBlockTask( void *pvParameters );
static void dmaTask(void *pvParameters);
/* The timer 5 interrupt handler. As this interrupt uses the FreeRTOS assembly
entry point the IPL setting in the following function prototype has no effect. */
void __attribute__( (interrupt(ipl3), vector(_TIMER_5_VECTOR))) vT5InterruptWrapper( void );
/*-----------------------------------------------------------*/
/* The semaphore used to signal the ISRBlockTask */
static xSemaphoreHandle xBlockSemaphore;
// xTaskCreate( prvISRBlockTask, ( signed char * ) "ISR", configMINIMAL_STACK_SIZE, ( void * ) NULL, mainISR_TASK_PRIORITY, NULL );
// xTaskCreate( dmaTask, (signed char *) "DMA", configMINIMAL_STACK_SIZE, (void*) NULL, 2, NULL);