mirror of
https://github.com/thelsing/knx.git
synced 2025-10-12 11:15:54 +02:00
git-subtree-dir: examples/knx-cc1310/coresdk_cc13xx_cc26xx git-subtree-split: 0d78d3280357416a5c0388148cda13717c9ffaa5
289 lines
8.7 KiB
C
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);
|
|
}
|