blob: 551507a2777f0fc5beafad8391adc747aadb9e92 [file] [log] [blame]
/*
* Copyright (c) 2015-2016, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* ======== HwiP_freertos.c ========
* TODO is this the correct license?
*
* Writing an RTOS safe ISR for FreeRTOS is very dependent on the
* microcontroller and tool chain port of FreeRTOS being used. Refer to
* the documentation page and demo application for the RTOS port being used.
*/
#include <stdbool.h>
#include <ti/drivers/dpl/HwiP.h>
#include <FreeRTOS.h>
#include <task.h>
#include <portmacro.h>
/* Driver lib includes */
#include <ti/devices/cc32xx/inc/hw_types.h>
#include <ti/devices/cc32xx/driverlib/interrupt.h>
#include <ti/devices/cc32xx/driverlib/rom.h>
#include <ti/devices/cc32xx/driverlib/rom_map.h>
#define MAX_INTERRUPTS 256
/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
#define portVECTACTIVE_MASK (0xFFUL)
/*
* ======== HwiP_DispatchEntry ========
*/
typedef struct HwiP_DispatchEntry {
HwiP_Fxn entry;
uintptr_t arg;
} HwiP_DispatchEntry;
HwiP_DispatchEntry HwiP_dispatchTable[MAX_INTERRUPTS] = {{(HwiP_Fxn)0, 0}};
/*
* ======== HwiP_disable ========
*/
uintptr_t HwiP_disable(void)
{
uintptr_t key;
/*
* If we're not in ISR context, use the FreeRTOS macro, since
* it handles nesting.
*/
if ((portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) == 0) {
/* Cannot be called from an ISR! */
portENTER_CRITICAL();
key = 0;
}
else {
#ifdef __TI_COMPILER_VERSION__
key = _set_interrupt_priority(configMAX_SYSCALL_INTERRUPT_PRIORITY);
#else
#if defined(__IAR_SYSTEMS_ICC__)
asm volatile (
#else /* !__IAR_SYSTEMS_ICC__ */
__asm__ __volatile__ (
#endif
"mrs %0, basepri\n\t"
"msr basepri, %1"
: "=&r" (key)
: "r" (configMAX_SYSCALL_INTERRUPT_PRIORITY)
);
#endif
}
return (key);
}
/*
* ======== HwiP_restore ========
*/
void HwiP_restore(uintptr_t key)
{
if ((portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) == 0) {
/* Cannot be called from an ISR! */
portEXIT_CRITICAL();
}
else {
#ifdef __TI_COMPILER_VERSION__
_set_interrupt_priority(key);
#else
#if defined(__IAR_SYSTEMS_ICC__)
asm volatile (
#else /* !__IAR_SYSTEMS_ICC__ */
__asm__ __volatile__ (
#endif
"msr basepri, %0"
:: "r" (key)
);
#endif
}
}
#ifndef xdc_target__isaCompatible_28
typedef struct Hwi_NVIC {
uint32_t RES_00;
uint32_t ICTR;
uint32_t RES_08;
uint32_t RES_0C;
uint32_t STCSR;
uint32_t STRVR;
uint32_t STCVR;
uint32_t STCALIB;
uint32_t RES_20[56];
uint32_t ISER[8];
uint32_t RES_120[24];
uint32_t ICER[8];
uint32_t RES_1A0[24];
uint32_t ISPR[8];
uint32_t RES_220[24];
uint32_t ICPR[8];
uint32_t RES_2A0[24];
uint32_t IABR[8];
uint32_t RES_320[56];
uint8_t IPR[240];
uint32_t RES_4F0[516];
uint32_t CPUIDBR;
uint32_t ICSR;
uint32_t VTOR;
uint32_t AIRCR;
uint32_t SCR;
uint32_t CCR;
uint8_t SHPR[12];
uint32_t SHCSR;
uint8_t MMFSR;
uint8_t BFSR;
uint16_t UFSR;
uint32_t HFSR;
uint32_t DFSR;
uint32_t MMAR;
uint32_t BFAR;
uint32_t AFSR;
uint32_t PFR0;
uint32_t PFR1;
uint32_t DFR0;
uint32_t AFR0;
uint32_t MMFR0;
uint32_t MMFR1;
uint32_t MMFR2;
uint32_t MMFR3;
uint32_t ISAR0;
uint32_t ISAR1;
uint32_t ISAR2;
uint32_t ISAR3;
uint32_t ISAR4;
uint32_t RES_D74[5];
uint32_t CPACR;
uint32_t RES_D8C[93];
uint32_t STI;
uint32_t RES_F04[12];
uint32_t FPCCR;
uint32_t FPCAR;
uint32_t FPDSCR;
uint32_t MVFR0;
uint32_t MVFR1;
uint32_t RES_F48[34];
uint32_t PID4;
uint32_t PID5;
uint32_t PID6;
uint32_t PID7;
uint32_t PID0;
uint32_t PID1;
uint32_t PID2;
uint32_t PID3;
uint32_t CID0;
uint32_t CID1;
uint32_t CID2;
uint32_t CID3;
} Hwi_NVIC;
/*
* ======== HwiP_clearInterrupt ========
*/
void HwiP_clearInterrupt(int interruptNum)
{
// TODO: Should driverlib functions be prefixed with MAP_?
IntPendClear((unsigned long)interruptNum);
}
/*
* ======== HwiP_delete ========
*/
HwiP_Status HwiP_delete(HwiP_Handle handle)
{
IntDisable((int)handle);
IntUnregister((int)handle);
return (HwiP_OK);
}
/*
* ======== HwiP_disableInterrupt ========
*/
void HwiP_disableInterrupt(int interruptNum)
{
IntDisable(interruptNum);
}
/*
* ======== HwiP_dispatch ========
*/
void HwiP_dispatch(void)
{
uint32_t intNum;
Hwi_NVIC *Hwi_nvic = (Hwi_NVIC *)0xE000E000;
HwiP_DispatchEntry hwi;
/* Determine which interrupt has fired */
intNum = (Hwi_nvic->ICSR & 0x000000ff);
hwi = HwiP_dispatchTable[intNum];
if (hwi.entry) {
(hwi.entry)(hwi.arg);
taskYIELD();
}
}
/*
* ======== HwiP_enableInterrupt ========
*/
void HwiP_enableInterrupt(int interruptNum)
{
IntEnable(interruptNum);
}
/*
* ======== HwiP_create ========
*/
HwiP_Handle HwiP_create(int interruptNum,
HwiP_Fxn hwiFxn,
HwiP_Params *params)
{
HwiP_Params defaultParams;
if (params == NULL) {
params = &defaultParams;
HwiP_Params_init(&defaultParams);
}
HwiP_dispatchTable[interruptNum].entry = hwiFxn;
HwiP_dispatchTable[interruptNum].arg = params->arg;
// TODO: Should driverlib functions be prefixed with MAP_?
IntRegister(interruptNum, (void(*)(void))HwiP_dispatch);
IntPrioritySet(interruptNum, params->priority);
IntEnable(interruptNum);
return ((HwiP_Handle)interruptNum);
}
/*
* ======== HwiP_inISR ========
*/
bool HwiP_inISR(void)
{
bool stat;
if ((portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) == 0) {
/* Not currently in an ISR */
stat = false;
}
else {
stat = true;
}
return (stat);
}
/*
* ======== HwiP_Params_init ========
*/
void HwiP_Params_init(HwiP_Params *params)
{
params->name = NULL;
params->arg = 0;
params->priority = ~0;
}
#endif