knx/source/ti/drivers/watchdog/WatchdogCC26XX.c
Nanosonde e51b65f8c2 Squashed 'examples/knx-cc1310/coresdk_cc13xx_cc26xx/' content from commit 0d78d32
git-subtree-dir: examples/knx-cc1310/coresdk_cc13xx_cc26xx
git-subtree-split: 0d78d3280357416a5c0388148cda13717c9ffaa5
2020-10-21 10:00:49 +02:00

289 lines
8.7 KiB
C

/*
* Copyright (c) 2015-2017, 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.
*/
#include <stdint.h>
#include <stdlib.h>
#include <ti/drivers/dpl/DebugP.h>
#include <ti/drivers/dpl/HwiP.h>
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC26XX.h>
#include <ti/drivers/watchdog/WatchdogCC26XX.h>
#include <ti/devices/DeviceFamily.h>
#include DeviceFamily_constructPath(driverlib/watchdog.h)
/* Function prototypes */
void WatchdogCC26XX_clear(Watchdog_Handle handle);
void WatchdogCC26XX_close(Watchdog_Handle handle);
int_fast16_t WatchdogCC26XX_control(Watchdog_Handle handle, uint_fast16_t cmd,
void *arg);
void WatchdogCC26XX_init(Watchdog_Handle handle);
Watchdog_Handle WatchdogCC26XX_open(Watchdog_Handle handle, Watchdog_Params *params);
int_fast16_t WatchdogCC26XX_setReload(Watchdog_Handle handle,
uint32_t ticks);
uint32_t WatchdogCC26XX_convertMsToTicks(Watchdog_Handle handle,
uint32_t milliseconds);
/* WatchdogCC26XX internal functions */
static void WatchdogCC26XX_initHw(Watchdog_Handle handle);
/* Watchdog function table for CC26XX implementation */
const Watchdog_FxnTable WatchdogCC26XX_fxnTable = {
WatchdogCC26XX_clear,
WatchdogCC26XX_close,
WatchdogCC26XX_control,
WatchdogCC26XX_init,
WatchdogCC26XX_open,
WatchdogCC26XX_setReload,
WatchdogCC26XX_convertMsToTicks
};
/* Maximum allowable setReload value */
#define MAX_RELOAD_VALUE 0xFFFFFFFF
#define WATCHDOG_DIV_RATIO 32 /* Watchdog division ratio */
#define MS_RATIO 1000 /* millisecond to second ratio */
/*
* ======== WatchdogCC26XX_clear ========
*/
void WatchdogCC26XX_clear(Watchdog_Handle handle)
{
WatchdogIntClear();
}
/*
* ======== WatchdogCC26XX_close ========
*/
void WatchdogCC26XX_close(Watchdog_Handle handle)
{
/*
* Not supported for CC26XX - Once the INTEN bit of the WDTCTL
* register has been set, it can only be cleared by a hardware
* reset.
*/
DebugP_assert(false);
}
/*
* ======== WatchdogCC26XX_control ========
* @pre Function assumes that the handle is not NULL
*/
int_fast16_t WatchdogCC26XX_control(Watchdog_Handle handle, uint_fast16_t cmd,
void *arg)
{
/* No implementation yet */
return (Watchdog_STATUS_UNDEFINEDCMD);
}
/*
* ======== Watchdog_init ========
*/
void WatchdogCC26XX_init(Watchdog_Handle handle)
{
WatchdogCC26XX_Object *object = handle->object;
object->isOpen = false;
}
/*
* ======== WatchdogCC26XX_open ========
*/
Watchdog_Handle WatchdogCC26XX_open(Watchdog_Handle handle, Watchdog_Params *params)
{
unsigned int key;
HwiP_Params hwiParams;
WatchdogCC26XX_Object *object;
/* get the pointer to the object and hwAttrs */
object = handle->object;
/* disable preemption while checking if the WatchDog is open. */
key = HwiP_disable();
/* Check if the Watchdog is open already with the HWAttrs */
if (object->isOpen == true) {
HwiP_restore(key);
DebugP_log1("Watchdog: Handle %x already in use.", (uintptr_t)handle);
return (NULL);
}
object->isOpen = true;
HwiP_restore(key);
/* initialize the Watchdog object */
object->debugStallMode = params->debugStallMode;
object->resetMode = params->resetMode;
/* Construct Hwi object for Watchdog */
HwiP_Params_init(&hwiParams);
hwiParams.arg = (uintptr_t)handle;
/* setup callback function if defined */
if (params->callbackFxn != NULL) {
HwiP_plug(INT_NMI_FAULT, (void *)params->callbackFxn);
}
/* initialize the watchdog hardware */
WatchdogCC26XX_initHw(handle);
DebugP_log1("Watchdog: handle %x opened" ,(uintptr_t)handle);
/* return handle of the Watchdog object */
return (handle);
}
/*
* ======== WatchdogCC26XX_setReload ========
*/
int_fast16_t WatchdogCC26XX_setReload(Watchdog_Handle handle, uint32_t ticks)
{
unsigned int key;
/* disable preemption while unlocking WatchDog registers */
key = HwiP_disable();
/* unlock the Watchdog configuration registers */
WatchdogUnlock();
/* make sure the Watchdog is unlocked before continuing */
while(WatchdogLockState() == WATCHDOG_LOCK_LOCKED)
{ }
/* update the reload value */
WatchdogReloadSet(ticks);
/* lock register access */
WatchdogLock();
HwiP_restore(key);
DebugP_log2("Watchdog: WDT with handle 0x%x has been set to "
"reload to 0x%x", (uintptr_t)handle, ticks);
return (Watchdog_STATUS_SUCCESS);
}
/*
* ======== WatchdogCC26XX_hwInit ========
* This function initializes the Watchdog hardware module.
*
* @pre Function assumes that the Watchdog handle is pointing to a hardware
* module which has already been opened.
*/
static void WatchdogCC26XX_initHw(Watchdog_Handle handle) {
unsigned int key;
uint32_t tickValue;
WatchdogCC26XX_Object *object;
WatchdogCC26XX_HWAttrs const *hwAttrs;
/* get the pointer to the object and hwAttrs */
object = handle->object;
hwAttrs = handle->hwAttrs;
/* convert milliseconds to watchdog timer ticks */
tickValue = WatchdogCC26XX_convertMsToTicks(handle, hwAttrs->reloadValue);
/* disable preemption while unlocking WatchDog registers */
key = HwiP_disable();
/* unlock the Watchdog configuration registers */
WatchdogUnlock();
/* make sure the Watchdog is unlocked before continuing */
while(WatchdogLockState() == WATCHDOG_LOCK_LOCKED)
{ }
WatchdogReloadSet(tickValue);
/* set reset mode */
if (object->resetMode == Watchdog_RESET_ON) {
WatchdogResetEnable();
}
else {
WatchdogResetDisable();
}
/* set debug stall mode */
if (object->debugStallMode == Watchdog_DEBUG_STALL_ON) {
WatchdogStallEnable();
}
else {
WatchdogStallDisable();
}
/* enable the Watchdog interrupt as a non-maskable interrupt */
WatchdogIntTypeSet(WATCHDOG_INT_TYPE_NMI);
/* enable the Watchdog */
WatchdogEnable();
/* lock the Watchdog configuration registers */
WatchdogLock();
HwiP_restore(key);
}
/*
* ======== WatchdogCC26XX_convertMsToTicks ========
* This function converts the input value from milliseconds to
* Watchdog clock ticks.
*/
uint32_t WatchdogCC26XX_convertMsToTicks(Watchdog_Handle handle,
uint32_t milliseconds)
{
uint32_t tickValue;
uint32_t convertRatio;
uint32_t maxConvertMs;
ClockP_FreqHz freq;
/* Determine milliseconds to clock ticks conversion ratio */
/* Watchdog clock ticks/sec = CPU clock / WATCHDOG_DIV_RATIO */
/* Watchdog clock ticks/ms = CPU clock / WATCHDOG_DIV_RATIO / 1000 */
ClockP_getCpuFreq(&freq);
convertRatio = freq.lo / WATCHDOG_DIV_RATIO / MS_RATIO;
maxConvertMs = MAX_RELOAD_VALUE / convertRatio;
/* convert milliseconds to watchdog timer ticks */
/* check if value exceeds maximum */
if (milliseconds > maxConvertMs) {
tickValue = 0; /* return zero to indicate overflow */
}
else {
tickValue = (uint32_t)(milliseconds * convertRatio);
}
return(tickValue);
}