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
7824 lines
227 KiB
C
7824 lines
227 KiB
C
//##### AUTO GENERATED FILE...DO NOT EDIT #####
|
|
//
|
|
// This file is autogenerated from the project definition
|
|
// and module includes defined in the 'APITable.xls'
|
|
//
|
|
//##### AUTO GENERATED FILE...DO NOT EDIT #####
|
|
#undef DEBUG
|
|
#include "lib_src/hw_ioc.h"
|
|
#include "lib_src/hw_nvic.h"
|
|
#include "lib_src/hw_gpio.h"
|
|
#include "lib_src/hw_flash.h"
|
|
#include "lib_src/hw_device.h"
|
|
#include "lib_src/hw_aux_tdc.h"
|
|
#include "lib_src/hw_ints.h"
|
|
#include "lib_src/hw_i2c.h"
|
|
#include "lib_src/hw_trng.h"
|
|
#include "lib_src/hw_gpt.h"
|
|
#include "lib_src/hw_uart.h"
|
|
#include "lib_src/hw_smph.h"
|
|
#include "lib_src/hw_aon_rtc.h"
|
|
#include "lib_src/hw_aon_wuc.h"
|
|
#include "lib_src/hw_vims.h"
|
|
#include "lib_src/hw_aon_event.h"
|
|
#include "lib_src/hw_memmap.h"
|
|
#include "lib_src/hw_aon_ioc.h"
|
|
#include "lib_src/hw_aux_wuc.h"
|
|
#include "lib_src/hw_sysctl.h"
|
|
#include "lib_src/hw_udma.h"
|
|
#include "lib_src/hw_ssi.h"
|
|
#include "lib_src/hw_aux_sce.h"
|
|
#include "lib_src/hw_aon_sysctl.h"
|
|
#include "lib_src/hw_factory_cfg.h"
|
|
#include "lib_src/hw_types.h"
|
|
#include "lib_src/hw_ddi.h"
|
|
#include "lib_src/hw_aux_timer.h"
|
|
#include "lib_src/hw_spis.h"
|
|
#include "lib_src/hw_prcm.h"
|
|
#include "lib_src/aon_event.h"
|
|
#include "lib_src/aon_ioc.h"
|
|
#include "lib_src/aon_rtc.h"
|
|
#include "lib_src/aon_wuc.h"
|
|
#include "lib_src/aux_ctrl.h"
|
|
#include "lib_src/aux_tdc.h"
|
|
#include "lib_src/aux_timer.h"
|
|
#include "lib_src/aux_wuc.h"
|
|
#include "lib_src/ddi.h"
|
|
#include "lib_src/flash.h"
|
|
#include "lib_src/i2c.h"
|
|
#include "lib_src/interrupt.h"
|
|
#include "lib_src/ioc.h"
|
|
#include "lib_src/prcm.h"
|
|
#include "lib_src/smph.h"
|
|
#include "lib_src/spis.h"
|
|
#include "lib_src/ssi.h"
|
|
#include "lib_src/timer.h"
|
|
#include "lib_src/trng.h"
|
|
#include "lib_src/uart.h"
|
|
#include "lib_src/udma.h"
|
|
#include "lib_src/vims.h"
|
|
#include "lib_src/cpu.h"
|
|
#include "lib_src/gpio.h"
|
|
#include "lib_src/debug.h"
|
|
//
|
|
// Include interrupt functions for based ROM code
|
|
//
|
|
//*****************************************************************************
|
|
//
|
|
//! Disable all external interrupts
|
|
//
|
|
//*****************************************************************************
|
|
#if defined(codered) || defined(gcc) || defined(sourcerygxx)
|
|
uint32_t __attribute__((naked))
|
|
CPUcpsid(void)
|
|
{
|
|
uint32_t ui32Ret;
|
|
|
|
//
|
|
// Read PRIMASK and disable interrupts
|
|
//
|
|
__asm(" mrs r0, PRIMASK\n"
|
|
" cpsid i\n"
|
|
" bx lr\n"
|
|
: "=r"(ui32Ret));
|
|
|
|
//
|
|
// The return is handled in the inline assembly, but the compiler will
|
|
// still complain if there is not an explicit return here (despite the fact
|
|
// that this does not result in any code being produced because of the
|
|
// naked attribute).
|
|
//
|
|
return(ui32Ret);
|
|
}
|
|
#endif
|
|
#if defined(__IAR_SYSTEMS_ICC__) || defined(DOXYGEN)
|
|
uint32_t
|
|
CPUcpsid(void)
|
|
{
|
|
//
|
|
// Read PRIMASK and disable interrupts.
|
|
//
|
|
__asm(" mrs r0, PRIMASK\n"
|
|
" cpsid i\n");
|
|
|
|
//
|
|
// "Warning[Pe940]: missing return statement at end of non-void function"
|
|
// is suppressed here to avoid putting a "bx lr" in the inline assembly
|
|
// above and a superfluous return statement here.
|
|
//
|
|
#pragma diag_suppress=Pe940
|
|
}
|
|
#pragma diag_default=Pe940
|
|
#endif
|
|
#if defined(rvmdk) || defined(__ARMCC_VERSION)
|
|
__asm uint32_t
|
|
CPUcpsid(void)
|
|
{
|
|
//
|
|
// Read PRIMASK and disable interrupts.
|
|
//
|
|
mrs r0, PRIMASK;
|
|
cpsid i;
|
|
bx lr
|
|
}
|
|
#endif
|
|
#if defined(__TI_COMPILER_VERSION__)
|
|
uint32_t
|
|
CPUcpsid(void)
|
|
{
|
|
//
|
|
// Read PRIMASK and disable interrupts.
|
|
//
|
|
__asm(" mrs r0, PRIMASK\n"
|
|
" cpsid i\n"
|
|
" bx lr\n");
|
|
|
|
//
|
|
// The following keeps the compiler happy, because it wants to see a
|
|
// return value from this function. It will generate code to return
|
|
// a zero. However, the real return is the "bx lr" above, so the
|
|
// return(0) is never executed and the function returns with the value
|
|
// you expect in R0.
|
|
//
|
|
return(0);
|
|
}
|
|
#endif
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Enable all external interrupts
|
|
//
|
|
//*****************************************************************************
|
|
#if defined(codered) || defined(gcc) || defined(sourcerygxx)
|
|
uint32_t __attribute__((naked))
|
|
CPUcpsie(void)
|
|
{
|
|
uint32_t ui32Ret;
|
|
|
|
//
|
|
// Read PRIMASK and enable interrupts.
|
|
//
|
|
__asm(" mrs r0, PRIMASK\n"
|
|
" cpsie i\n"
|
|
" bx lr\n"
|
|
: "=r"(ui32Ret));
|
|
|
|
//
|
|
// The return is handled in the inline assembly, but the compiler will
|
|
// still complain if there is not an explicit return here (despite the fact
|
|
// that this does not result in any code being produced because of the
|
|
// naked attribute).
|
|
//
|
|
return(ui32Ret);
|
|
}
|
|
#endif
|
|
#if defined(__IAR_SYSTEMS_ICC__) || defined(DOXYGEN)
|
|
uint32_t
|
|
CPUcpsie(void)
|
|
{
|
|
//
|
|
// Read PRIMASK and enable interrupts.
|
|
//
|
|
__asm(" mrs r0, PRIMASK\n"
|
|
" cpsie i\n");
|
|
|
|
//
|
|
// "Warning[Pe940]: missing return statement at end of non-void function"
|
|
// is suppressed here to avoid putting a "bx lr" in the inline assembly
|
|
// above and a superfluous return statement here.
|
|
//
|
|
#pragma diag_suppress=Pe940
|
|
}
|
|
#pragma diag_default=Pe940
|
|
#endif
|
|
#if defined(rvmdk) || defined(__ARMCC_VERSION)
|
|
__asm uint32_t
|
|
CPUcpsie(void)
|
|
{
|
|
//
|
|
// Read PRIMASK and enable interrupts.
|
|
//
|
|
mrs r0, PRIMASK;
|
|
cpsie i;
|
|
bx lr
|
|
}
|
|
#endif
|
|
#if defined(__TI_COMPILER_VERSION__)
|
|
uint32_t
|
|
CPUcpsie(void)
|
|
{
|
|
//
|
|
// Read PRIMASK and enable interrupts.
|
|
//
|
|
__asm(" mrs r0, PRIMASK\n"
|
|
" cpsie i\n"
|
|
" bx lr\n");
|
|
|
|
//
|
|
// The following keeps the compiler happy, because it wants to see a
|
|
// return value from this function. It will generate code to return
|
|
// a zero. However, the real return is the "bx lr" above, so the
|
|
// return(0) is never executed and the function returns with the value
|
|
// you expect in R0.
|
|
//
|
|
return(0);
|
|
}
|
|
#endif
|
|
//! \\addtogroup aon_event_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Select event source for the specified MCU wakeup programmable event
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONEventMcuWakeUpSet(uint32_t ui32MCUWUEvent, uint32_t ui32EventSrc)
|
|
{
|
|
uint32_t ui32Ctrl;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32MCUWUEvent == AON_EVENT_MCU_WU0) ||
|
|
(ui32MCUWUEvent == AON_EVENT_MCU_WU1) ||
|
|
(ui32MCUWUEvent == AON_EVENT_MCU_WU2) ||
|
|
(ui32MCUWUEvent == AON_EVENT_MCU_WU3));
|
|
ASSERT(ui32EventSrc <= AON_EVENT_NULL);
|
|
|
|
ui32Ctrl = HWREG(AON_EVENT_BASE + AON_EVENT_O_MCUWUSEL);
|
|
|
|
if(ui32MCUWUEvent == AON_EVENT_MCU_WU0)
|
|
{
|
|
ui32Ctrl &= ~(AON_EVENT_MCUWUSEL_WU0_EV_M);
|
|
ui32Ctrl |= (ui32EventSrc & 0x3f) << AON_EVENT_MCUWUSEL_WU0_EV_S;
|
|
}
|
|
else if(ui32MCUWUEvent == AON_EVENT_MCU_WU1)
|
|
{
|
|
ui32Ctrl &= ~(AON_EVENT_MCUWUSEL_WU1_EV_M);
|
|
ui32Ctrl |= (ui32EventSrc & 0x3f) << AON_EVENT_MCUWUSEL_WU1_EV_S;
|
|
}
|
|
else if(ui32MCUWUEvent == AON_EVENT_MCU_WU2)
|
|
{
|
|
ui32Ctrl &= ~(AON_EVENT_MCUWUSEL_WU2_EV_M);
|
|
ui32Ctrl |= (ui32EventSrc & 0x3f) << AON_EVENT_MCUWUSEL_WU2_EV_S;
|
|
}
|
|
else if(ui32MCUWUEvent == AON_EVENT_MCU_WU3)
|
|
{
|
|
ui32Ctrl &= ~(AON_EVENT_MCUWUSEL_WU3_EV_M);
|
|
ui32Ctrl |= (ui32EventSrc & 0x3f) << AON_EVENT_MCUWUSEL_WU3_EV_S;
|
|
}
|
|
|
|
HWREG(AON_EVENT_BASE + AON_EVENT_O_MCUWUSEL) = ui32Ctrl;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get event source for the specified MCU wakeup programmable event
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AONEventMcuWakeUpGet(uint32_t ui32MCUWUEvent)
|
|
{
|
|
uint32_t ui32EventSrc;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32MCUWUEvent == AON_EVENT_MCU_WU0) ||
|
|
(ui32MCUWUEvent == AON_EVENT_MCU_WU1) ||
|
|
(ui32MCUWUEvent == AON_EVENT_MCU_WU2) ||
|
|
(ui32MCUWUEvent == AON_EVENT_MCU_WU3));
|
|
|
|
ui32EventSrc = HWREG(AON_EVENT_BASE + AON_EVENT_O_MCUWUSEL);
|
|
|
|
if(ui32MCUWUEvent == AON_EVENT_MCU_WU0)
|
|
{
|
|
return((ui32EventSrc & AON_EVENT_MCUWUSEL_WU0_EV_M) >>
|
|
AON_EVENT_MCUWUSEL_WU0_EV_S);
|
|
}
|
|
else if(ui32MCUWUEvent == AON_EVENT_MCU_WU1)
|
|
{
|
|
return((ui32EventSrc & AON_EVENT_MCUWUSEL_WU1_EV_M) >>
|
|
AON_EVENT_MCUWUSEL_WU1_EV_S);
|
|
}
|
|
else if(ui32MCUWUEvent == AON_EVENT_MCU_WU2)
|
|
{
|
|
return((ui32EventSrc & AON_EVENT_MCUWUSEL_WU2_EV_M) >>
|
|
AON_EVENT_MCUWUSEL_WU2_EV_S);
|
|
}
|
|
else if(ui32MCUWUEvent == AON_EVENT_MCU_WU3)
|
|
{
|
|
return((ui32EventSrc & AON_EVENT_MCUWUSEL_WU3_EV_M) >>
|
|
AON_EVENT_MCUWUSEL_WU3_EV_S);
|
|
}
|
|
|
|
//
|
|
// Should never get to this statement, but suppress warning.
|
|
//
|
|
ASSERT(0);
|
|
return(0);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Select event source for the specified AUX wakeup programmable event
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONEventAuxWakeUpSet(uint32_t ui32AUXWUEvent, uint32_t ui32EventSrc)
|
|
{
|
|
uint32_t ui32Ctrl;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32AUXWUEvent == AON_EVENT_AUX_WU0) ||
|
|
(ui32AUXWUEvent == AON_EVENT_AUX_WU1) ||
|
|
(ui32AUXWUEvent == AON_EVENT_AUX_WU2));
|
|
ASSERT(ui32EventSrc <= AON_EVENT_NULL);
|
|
|
|
ui32Ctrl = HWREG(AON_EVENT_BASE + AON_EVENT_O_AUXWUSEL);
|
|
|
|
if(ui32AUXWUEvent == AON_EVENT_AUX_WU0)
|
|
{
|
|
ui32Ctrl &= ~(AON_EVENT_AUXWUSEL_WU0_EV_M);
|
|
ui32Ctrl |= (ui32EventSrc & 0x3f) << AON_EVENT_AUXWUSEL_WU0_EV_S;
|
|
}
|
|
else if(ui32AUXWUEvent == AON_EVENT_AUX_WU1)
|
|
{
|
|
ui32Ctrl &= ~(AON_EVENT_AUXWUSEL_WU1_EV_M);
|
|
ui32Ctrl |= (ui32EventSrc & 0x3f) << AON_EVENT_AUXWUSEL_WU1_EV_S;
|
|
}
|
|
else if(ui32AUXWUEvent == AON_EVENT_AUX_WU2)
|
|
{
|
|
ui32Ctrl &= ~(AON_EVENT_AUXWUSEL_WU2_EV_M);
|
|
ui32Ctrl |= (ui32EventSrc & 0x3f) << AON_EVENT_AUXWUSEL_WU2_EV_S;
|
|
}
|
|
|
|
HWREG(AON_EVENT_BASE + AON_EVENT_O_AUXWUSEL) = ui32Ctrl;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get event source for the specified AUX wakeup programmable event
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AONEventAuxWakeUpGet(uint32_t ui32AUXWUEvent)
|
|
{
|
|
uint32_t ui32EventSrc;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32AUXWUEvent == AON_EVENT_AUX_WU0) ||
|
|
(ui32AUXWUEvent == AON_EVENT_AUX_WU1) ||
|
|
(ui32AUXWUEvent == AON_EVENT_AUX_WU2));
|
|
|
|
ui32EventSrc = HWREG(AON_EVENT_BASE + AON_EVENT_O_AUXWUSEL);
|
|
|
|
if(ui32AUXWUEvent == AON_EVENT_AUX_WU0)
|
|
{
|
|
return((ui32EventSrc & AON_EVENT_AUXWUSEL_WU0_EV_M) >>
|
|
AON_EVENT_AUXWUSEL_WU0_EV_S);
|
|
}
|
|
else if(ui32AUXWUEvent == AON_EVENT_AUX_WU1)
|
|
{
|
|
return((ui32EventSrc & AON_EVENT_AUXWUSEL_WU1_EV_M) >>
|
|
AON_EVENT_AUXWUSEL_WU1_EV_S);
|
|
}
|
|
else if(ui32AUXWUEvent == AON_EVENT_AUX_WU2)
|
|
{
|
|
return((ui32EventSrc & AON_EVENT_AUXWUSEL_WU2_EV_M) >>
|
|
AON_EVENT_AUXWUSEL_WU2_EV_S);
|
|
}
|
|
|
|
//
|
|
// Should never get to this statement, but suppress warning.
|
|
//
|
|
ASSERT(0);
|
|
return(0);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Select event source for the specified programmable event forwarded to the
|
|
//! MCU event fabric
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONEventMcuSet(uint32_t ui32MCUEvent, uint32_t ui32EventSrc)
|
|
{
|
|
uint32_t ui32Ctrl;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32MCUEvent == AON_EVENT_MCU_EVENT0) ||
|
|
(ui32MCUEvent == AON_EVENT_MCU_EVENT1) ||
|
|
(ui32MCUEvent == AON_EVENT_MCU_EVENT2));
|
|
ASSERT(ui32EventSrc <= AON_EVENT_NULL);
|
|
|
|
ui32Ctrl = HWREG(AON_EVENT_BASE + AON_EVENT_O_EVTOMCUSEL);
|
|
|
|
if(ui32MCUEvent == AON_EVENT_MCU_EVENT0)
|
|
{
|
|
ui32Ctrl &= ~(AON_EVENT_EVTOMCUSEL_AON_PROG0_EV_M);
|
|
ui32Ctrl |= (ui32EventSrc & 0x3f) << AON_EVENT_EVTOMCUSEL_AON_PROG0_EV_S;
|
|
}
|
|
else if(ui32MCUEvent == AON_EVENT_MCU_EVENT1)
|
|
{
|
|
ui32Ctrl &= ~(AON_EVENT_EVTOMCUSEL_AON_PROG1_EV_M);
|
|
ui32Ctrl |= (ui32EventSrc & 0x3f) << AON_EVENT_EVTOMCUSEL_AON_PROG1_EV_S;
|
|
}
|
|
else if(ui32MCUEvent == AON_EVENT_MCU_EVENT2)
|
|
{
|
|
ui32Ctrl &= ~(AON_EVENT_EVTOMCUSEL_AON_PROG2_EV_M);
|
|
ui32Ctrl |= (ui32EventSrc & 0x3f) << AON_EVENT_EVTOMCUSEL_AON_PROG2_EV_S;
|
|
}
|
|
|
|
HWREG(AON_EVENT_BASE + AON_EVENT_O_EVTOMCUSEL) = ui32Ctrl;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get source for the specified programmable event forwarded to the MCU event
|
|
//! fabric.
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AONEventMcuGet(uint32_t ui32MCUEvent)
|
|
{
|
|
uint32_t ui32EventSrc;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32MCUEvent == AON_EVENT_MCU_EVENT0) ||
|
|
(ui32MCUEvent == AON_EVENT_MCU_EVENT1) ||
|
|
(ui32MCUEvent == AON_EVENT_MCU_EVENT2));
|
|
|
|
ui32EventSrc = HWREG(AON_EVENT_BASE + AON_EVENT_O_EVTOMCUSEL);
|
|
|
|
if(ui32MCUEvent == AON_EVENT_MCU_EVENT0)
|
|
{
|
|
return((ui32EventSrc & AON_EVENT_EVTOMCUSEL_AON_PROG0_EV_M) >>
|
|
AON_EVENT_EVTOMCUSEL_AON_PROG0_EV_S);
|
|
}
|
|
else if(ui32MCUEvent == AON_EVENT_MCU_EVENT1)
|
|
{
|
|
return((ui32EventSrc & AON_EVENT_EVTOMCUSEL_AON_PROG1_EV_M) >>
|
|
AON_EVENT_EVTOMCUSEL_AON_PROG1_EV_S);
|
|
}
|
|
else if(ui32MCUEvent == AON_EVENT_MCU_EVENT2)
|
|
{
|
|
return((ui32EventSrc & AON_EVENT_EVTOMCUSEL_AON_PROG2_EV_M) >>
|
|
AON_EVENT_EVTOMCUSEL_AON_PROG2_EV_S);
|
|
}
|
|
|
|
//
|
|
// Should never get to this statement, but supress warning.
|
|
//
|
|
ASSERT(0);
|
|
return(0);
|
|
}
|
|
//! @}
|
|
//! \\addtogroup aon_ioc_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Setup the drive strength for all IOs on the chip
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONIOCDriveStrengthSet(uint32_t ui32LowDrvStr, uint32_t ui32MedDrvStr,
|
|
uint32_t ui32MaxDrvStr)
|
|
{
|
|
ASSERT((ui32LowDrvStr == AONIOC_DRV_STR5_7_14) ||
|
|
(ui32LowDrvStr == AONIOC_DRV_STR5_10_20) ||
|
|
(ui32LowDrvStr == AONIOC_DRV_STR7_14_28) ||
|
|
(ui32LowDrvStr == AONIOC_DRV_STR10_20_40) ||
|
|
(ui32LowDrvStr == AONIOC_DRV_STR14_28_56) ||
|
|
(ui32LowDrvStr == AONIOC_DRV_STR20_40_80) ||
|
|
(ui32LowDrvStr == AONIOC_DRV_STR28_56_112) ||
|
|
(ui32LowDrvStr == AONIOC_DRV_STR40_80_112));
|
|
ASSERT((ui32MedDrvStr == AONIOC_DRV_STR5_7_14) ||
|
|
(ui32MedDrvStr == AONIOC_DRV_STR5_10_20) ||
|
|
(ui32MedDrvStr == AONIOC_DRV_STR7_14_28) ||
|
|
(ui32MedDrvStr == AONIOC_DRV_STR10_20_40) ||
|
|
(ui32MedDrvStr == AONIOC_DRV_STR14_28_56) ||
|
|
(ui32MedDrvStr == AONIOC_DRV_STR20_40_80) ||
|
|
(ui32MedDrvStr == AONIOC_DRV_STR28_56_112) ||
|
|
(ui32MedDrvStr == AONIOC_DRV_STR40_80_112));
|
|
ASSERT((ui32MaxDrvStr == AONIOC_DRV_STR5_7_14) ||
|
|
(ui32MaxDrvStr == AONIOC_DRV_STR5_10_20) ||
|
|
(ui32MaxDrvStr == AONIOC_DRV_STR7_14_28) ||
|
|
(ui32MaxDrvStr == AONIOC_DRV_STR10_20_40) ||
|
|
(ui32MaxDrvStr == AONIOC_DRV_STR14_28_56) ||
|
|
(ui32MaxDrvStr == AONIOC_DRV_STR20_40_80) ||
|
|
(ui32MaxDrvStr == AONIOC_DRV_STR28_56_112) ||
|
|
(ui32MaxDrvStr == AONIOC_DRV_STR40_80_112));
|
|
|
|
//
|
|
// Set the minimum drive strength.
|
|
//
|
|
HWREG(AON_IOC_BASE + AON_IOC_O_IOSTRMIN) = ui32LowDrvStr &
|
|
AON_IOC_IOSTRMIN_GRAY_CODE_M;
|
|
//
|
|
// Set the medium drive strength.
|
|
//
|
|
HWREG(AON_IOC_BASE + AON_IOC_O_IOSTRMED) = ui32MedDrvStr &
|
|
AON_IOC_IOSTRMED_GRAY_CODE_M;
|
|
//
|
|
// Set the maximum drive strength.
|
|
//
|
|
HWREG(AON_IOC_BASE + AON_IOC_O_IOSTRMAX) = ui32MaxDrvStr &
|
|
AON_IOC_IOSTRMAX_GRAY_CODE_M;
|
|
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get a specific drive level setting for all IOs
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AONIOCDriveStrengthGet(uint32_t ui32DriveLevel)
|
|
{
|
|
uint32_t ui32DrvStr;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32DriveLevel == AONIOC_MAX_DRIVE) ||
|
|
(ui32DriveLevel == AONIOC_MED_DRIVE) ||
|
|
(ui32DriveLevel == AONIOC_MIN_DRIVE));
|
|
|
|
//
|
|
// Get the specified drive strength level.
|
|
//
|
|
if(ui32DriveLevel == AONIOC_MAX_DRIVE)
|
|
{
|
|
ui32DrvStr = HWREG(AON_IOC_BASE + AON_IOC_O_IOSTRMAX);
|
|
}
|
|
else if(ui32DriveLevel == AONIOC_MED_DRIVE)
|
|
{
|
|
ui32DrvStr = HWREG(AON_IOC_BASE + AON_IOC_O_IOSTRMED);
|
|
}
|
|
else
|
|
{
|
|
ui32DrvStr = HWREG(AON_IOC_BASE + AON_IOC_O_IOSTRMIN);
|
|
}
|
|
|
|
//
|
|
// Return the drive strength value.
|
|
//
|
|
return(ui32DrvStr);
|
|
}
|
|
//! @}
|
|
//! \\addtogroup aon_rtc_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Check if the AON Real Time Clock is running.
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AONRTCStatus(void)
|
|
{
|
|
uint32_t ui32ChannelStatus;
|
|
uint32_t ui32RtcStatus;
|
|
|
|
//
|
|
// Read out the status'
|
|
//
|
|
ui32ChannelStatus = HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL);
|
|
ui32RtcStatus = HWREG(AON_RTC_BASE + AON_RTC_O_CTL) &
|
|
AON_RTC_CTL_EN ? AON_RTC_ACTIVE : 0;
|
|
|
|
//
|
|
// Return the status
|
|
//
|
|
ui32RtcStatus |= (ui32ChannelStatus & AON_RTC_CHCTL_CH2_EN ?
|
|
AON_RTC_CH2 : 0) |
|
|
(ui32ChannelStatus & AON_RTC_CHCTL_CH1_EN ?
|
|
AON_RTC_CH1 : 0) |
|
|
(ui32ChannelStatus & AON_RTC_CHCTL_CH0_EN ?
|
|
AON_RTC_CH0 : 0);
|
|
return ui32RtcStatus;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Clear event from a specified channel
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONRTCEventClear(uint32_t ui32Channel)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Channel == AON_RTC_CH0) ||
|
|
(ui32Channel == AON_RTC_CH1) ||
|
|
(ui32Channel == AON_RTC_CH2));
|
|
|
|
if(ui32Channel & AON_RTC_CH0)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH0;
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH1)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH1;
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH2)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH2;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get event status for a specified channel
|
|
//
|
|
//*****************************************************************************
|
|
bool
|
|
AONRTCEventGet(uint32_t ui32Channel)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Channel == AON_RTC_CH0) ||
|
|
(ui32Channel == AON_RTC_CH1) ||
|
|
(ui32Channel == AON_RTC_CH2));
|
|
|
|
if(ui32Channel & AON_RTC_CH0)
|
|
{
|
|
return ((HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) &
|
|
AON_RTC_EVFLAGS_CH0) ? true : false);
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH1)
|
|
{
|
|
return ((HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) &
|
|
AON_RTC_EVFLAGS_CH1) ? true : false);
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH2)
|
|
{
|
|
return ((HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) &
|
|
AON_RTC_EVFLAGS_CH2) ? true : false);
|
|
}
|
|
|
|
return(false);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set operational mode of channel 1
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONRTCModeCh1Set(uint32_t ui32Mode)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Mode == AON_RTC_MODE_CH1_CAPTURE) ||
|
|
(ui32Mode == AON_RTC_MODE_CH1_COMPARE));
|
|
|
|
if(ui32Mode == AON_RTC_MODE_CH1_CAPTURE)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) |= AON_RTC_CHCTL_CH1_CAPT_EN;
|
|
}
|
|
else if(ui32Mode == AON_RTC_MODE_CH1_COMPARE)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) &= ~(AON_RTC_CHCTL_CH1_CAPT_EN);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get operational mode of channel 1
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AONRTCModeCh1Get(void)
|
|
{
|
|
if(HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) & AON_RTC_CHCTL_CH1_CAPT_EN)
|
|
{
|
|
return(AON_RTC_MODE_CH1_CAPTURE);
|
|
}
|
|
else
|
|
{
|
|
return(AON_RTC_MODE_CH1_COMPARE);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set operational mode of channel 2
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONRTCModeCh2Set(uint32_t ui32Mode)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Mode == AON_RTC_MODE_CH2_CONTINUOUS) ||
|
|
(ui32Mode == AON_RTC_MODE_CH2_NORMALCOMPARE));
|
|
|
|
if(ui32Mode == AON_RTC_MODE_CH2_CONTINUOUS)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) |= AON_RTC_CHCTL_CH2_CONT_EN;
|
|
}
|
|
else if(ui32Mode == AON_RTC_MODE_CH2_NORMALCOMPARE)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) &= ~(AON_RTC_CHCTL_CH2_CONT_EN);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get operational mode of channel 2
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AONRTCModeCh2Get(void)
|
|
{
|
|
if(HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) & AON_RTC_CHCTL_CH2_CONT_EN)
|
|
{
|
|
return(AON_RTC_MODE_CH2_CONTINUOUS);
|
|
}
|
|
else
|
|
{
|
|
return(AON_RTC_MODE_CH2_NORMALCOMPARE);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Enable event operation for the specified channel
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONRTCChannelEnable(uint32_t ui32Channel)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Channel == AON_RTC_CH0) ||
|
|
(ui32Channel == AON_RTC_CH1) ||
|
|
(ui32Channel == AON_RTC_CH2));
|
|
|
|
if(ui32Channel & AON_RTC_CH0)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) |= AON_RTC_CHCTL_CH0_EN;
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH1)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) |= AON_RTC_CHCTL_CH1_EN;
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH2)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) |= AON_RTC_CHCTL_CH2_EN;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Disable event operation for the specified channel
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONRTCChannelDisable(uint32_t ui32Channel)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Channel == AON_RTC_CH0) ||
|
|
(ui32Channel == AON_RTC_CH1) ||
|
|
(ui32Channel == AON_RTC_CH2));
|
|
|
|
if(ui32Channel & AON_RTC_CH0)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) &= ~(AON_RTC_CHCTL_CH0_EN);
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH1)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) &= ~(AON_RTC_CHCTL_CH1_EN);
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH2)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) &= ~(AON_RTC_CHCTL_CH2_EN);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set the compare value for the given channel
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONRTCCompareValueSet(uint32_t ui32Channel, uint32_t ui32CompValue)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Channel == AON_RTC_CH0) ||
|
|
(ui32Channel == AON_RTC_CH1) ||
|
|
(ui32Channel == AON_RTC_CH2));
|
|
|
|
if(ui32Channel & AON_RTC_CH0)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CH0CMP) = ui32CompValue;
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH1)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CH1CMP) = ui32CompValue;
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH2)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_CH2CMP) = ui32CompValue;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get the compare value for the given channel
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AONRTCCompareValueGet(uint32_t ui32Channel)
|
|
{
|
|
//
|
|
// Check the arguments
|
|
//
|
|
ASSERT((ui32Channel == AON_RTC_CH0) ||
|
|
(ui32Channel == AON_RTC_CH1) ||
|
|
(ui32Channel == AON_RTC_CH2));
|
|
|
|
if(ui32Channel & AON_RTC_CH0)
|
|
{
|
|
return(HWREG(AON_RTC_BASE + AON_RTC_O_CH0CMP));
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH1)
|
|
{
|
|
return(HWREG(AON_RTC_BASE + AON_RTC_O_CH1CMP));
|
|
}
|
|
else if(ui32Channel & AON_RTC_CH2)
|
|
{
|
|
return(HWREG(AON_RTC_BASE + AON_RTC_O_CH2CMP));
|
|
}
|
|
//
|
|
// Should never return from here!
|
|
//
|
|
return(0);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get the current value of the RTC counter in a format compatible to the
|
|
//! compare registers.
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AONRTCCurrentCompareValueGet(void)
|
|
{
|
|
uint32_t ui32CurrentSec0;
|
|
uint32_t ui32CurrentSec1;
|
|
uint32_t ui32CurrentSubSec;
|
|
|
|
//
|
|
// Read the integer part of the RTC counter
|
|
//
|
|
ui32CurrentSec0 = HWREG( AON_RTC_BASE + AON_RTC_O_SEC );
|
|
|
|
//
|
|
// Read the fractional part of the RTC counter. Make sure the fractional
|
|
// part has not rolled over and incremented the integer part.
|
|
//
|
|
do {
|
|
ui32CurrentSubSec = HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC);
|
|
ui32CurrentSec1 = ui32CurrentSec0;
|
|
ui32CurrentSec0 = HWREG(AON_RTC_BASE + AON_RTC_O_SEC);
|
|
} while(ui32CurrentSec0 != ui32CurrentSec1);
|
|
|
|
//
|
|
// Return the RTC value in the correct format
|
|
//
|
|
return ((ui32CurrentSec0 << 16) | (ui32CurrentSubSec >> 16));
|
|
}
|
|
//! @}
|
|
//! \\addtogroup aon_wuc_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Set the clock source for the AUX domain
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONWUCAuxClockConfigSet(uint32_t ui32ClkSrc, uint32_t ui32ClkDiv)
|
|
{
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32ClkSrc == AONWUC_CLOCK_SRC_HF) ||
|
|
(ui32ClkSrc == AONWUC_CLOCK_SRC_MF) ||
|
|
(ui32ClkSrc == AONWUC_CLOCK_SRC_LF));
|
|
ASSERT((ui32ClkDiv == AUX_CLOCK_DIV_2) ||
|
|
(ui32ClkDiv == AUX_CLOCK_DIV_4) ||
|
|
(ui32ClkDiv == AUX_CLOCK_DIV_8) ||
|
|
(ui32ClkDiv == AUX_CLOCK_DIV_16) ||
|
|
(ui32ClkDiv == AUX_CLOCK_DIV_32) ||
|
|
(ui32ClkDiv == AUX_CLOCK_DIV_64) ||
|
|
(ui32ClkDiv == AUX_CLOCK_DIV_128) ||
|
|
(ui32ClkDiv == AUX_CLOCK_DIV_256) ||
|
|
(ui32ClkDiv == AUX_CLOCK_DIV_UNUSED));
|
|
|
|
//
|
|
// Configure the clock for the AUX domain.
|
|
//
|
|
ui32Reg = HWREG(AON_WUC_BASE + AON_WUC_O_AUXCLK);
|
|
|
|
//
|
|
// Check if we need to update the clock division factor
|
|
//
|
|
if(ui32ClkDiv != AUX_CLOCK_DIV_UNUSED)
|
|
{
|
|
ui32Reg = (ui32Reg & ~AON_WUC_AUXCLK_SCLK_HF_DIV_M) | ui32ClkDiv;
|
|
HWREG(AON_WUC_BASE + AON_WUC_O_AUXCLK) = ui32Reg;
|
|
|
|
// If switching to a HF clocks source for AUX it is necessary to
|
|
// synchronize the write on the AON RTC to ensure the clock division is
|
|
// updated before requesting the clock source
|
|
//
|
|
if(ui32ClkSrc == AONWUC_CLOCK_SRC_HF)
|
|
{
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_SYNC);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Configure the clock for the AUX domain.
|
|
//
|
|
ui32Reg &= ~AON_WUC_AUXCLK_SRC_M;
|
|
if(ui32ClkSrc == AONWUC_CLOCK_SRC_HF)
|
|
{
|
|
ui32Reg |= AON_WUC_AUXCLK_SRC_SCLK_HF;
|
|
}
|
|
else if(ui32ClkSrc == AONWUC_CLOCK_SRC_MF)
|
|
{
|
|
ui32Reg |= AON_WUC_AUXCLK_SRC_SCLK_MF;
|
|
}
|
|
else if(ui32ClkSrc == AONWUC_CLOCK_SRC_LF)
|
|
{
|
|
ui32Reg |= AON_WUC_AUXCLK_SRC_SCLK_LF;
|
|
}
|
|
HWREG(AON_WUC_BASE + AON_WUC_O_AUXCLK) = ui32Reg;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure the rentention on the AUX SRAM
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONWUCAuxSRamConfig(uint32_t ui32Retention)
|
|
{
|
|
|
|
//
|
|
// Enable/disable the retention.
|
|
//
|
|
if(ui32Retention)
|
|
{
|
|
HWREG(AON_WUC_BASE + AON_WUC_O_AUXCFG) |= AON_WUC_AUXCFG_SRAM_RET_EN;
|
|
}
|
|
else
|
|
{
|
|
HWREG(AON_WUC_BASE + AON_WUC_O_AUXCFG) &= ~AON_WUC_AUXCFG_SRAM_RET_EN;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Control the wake up procedure of the AUX domain
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONWUCAuxWakeupEvent(uint32_t ui32Mode)
|
|
{
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Mode == AONWUC_AUX_WAKEUP_SWEVT) ||
|
|
(ui32Mode == AONWUC_AUX_WAKEUP) ||
|
|
(ui32Mode == AONWUC_AUX_ALLOW_SLEEP));
|
|
|
|
//
|
|
// Wake up the AUX domain.
|
|
//
|
|
ui32Reg = HWREG(AON_WUC_BASE + AON_WUC_O_AUXCTL);
|
|
|
|
if(ui32Mode == AONWUC_AUX_ALLOW_SLEEP)
|
|
{
|
|
ui32Reg &= ~AON_WUC_AUXCTL_AUX_FORCE_ON;
|
|
}
|
|
else
|
|
{
|
|
ui32Reg |= ui32Mode;
|
|
}
|
|
|
|
HWREG(AON_WUC_BASE + AON_WUC_O_AUXCTL) = ui32Reg;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Reset the AUX domain
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONWUCAuxReset(void)
|
|
{
|
|
//
|
|
// Reset the AUX domain.
|
|
//
|
|
HWREG(AON_WUC_BASE + AON_WUC_O_AUXCTL) |= AON_WUC_AUXCTL_RESET_REQ;
|
|
|
|
//
|
|
// Wait for AON interface to be in sync.
|
|
//
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_SYNC);
|
|
|
|
//
|
|
// De-assert reset on the AUX domain.
|
|
//
|
|
HWREG(AON_WUC_BASE + AON_WUC_O_AUXCTL) &= ~AON_WUC_AUXCTL_RESET_REQ;
|
|
|
|
//
|
|
// Wait for AON interface to be in sync.
|
|
//
|
|
HWREG(AON_RTC_BASE + AON_RTC_O_SYNC);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure the recharge controller
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONWUCRechargeCtrlConfigSet(bool bAdaptEnable, uint32_t ui32AdaptRate,
|
|
uint32_t ui32Period, uint32_t ui32MaxPeriod)
|
|
{
|
|
uint32_t ui32Shift;
|
|
uint32_t ui32C1;
|
|
uint32_t ui32C2;
|
|
uint32_t ui32Reg;
|
|
uint32_t ui32Exponent;
|
|
uint32_t ui32MaxExponent;
|
|
uint32_t ui32Mantissa;
|
|
uint32_t ui32MaxMantissa;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32AdaptRate >= RC_RATE_MIN) ||
|
|
(ui32AdaptRate <= RC_RATE_MAX));
|
|
|
|
ui32C1 = 0;
|
|
ui32C2 = 0;
|
|
ui32Shift = 9;
|
|
|
|
//
|
|
// Clear the previous values.
|
|
//
|
|
ui32Reg = HWREG(AON_WUC_BASE + AON_WUC_O_RECHARGECFG);
|
|
ui32Reg &= ~(AON_WUC_RECHARGECFG_MAX_PER_M_M | AON_WUC_RECHARGECFG_MAX_PER_E_M |
|
|
AON_WUC_RECHARGECFG_ADAPTIVE_EN_M | AON_WUC_RECHARGECFG_PER_M_M |
|
|
AON_WUC_RECHARGECFG_PER_E_M | AON_WUC_RECHARGECFG_C1_M |
|
|
AON_WUC_RECHARGECFG_C2_M);
|
|
|
|
//
|
|
// Check if the recharge controller adaption algorithm should be active.
|
|
//
|
|
if(bAdaptEnable)
|
|
{
|
|
//
|
|
// Calculate adaption parameters.
|
|
//
|
|
while(ui32AdaptRate)
|
|
{
|
|
if(ui32AdaptRate & (1 << ui32Shift))
|
|
{
|
|
if(!ui32C1)
|
|
{
|
|
ui32C1 = ui32Shift;
|
|
}
|
|
else if(!ui32C2)
|
|
{
|
|
if((2 * ui32AdaptRate) > ((uint32_t)(3 << ui32Shift)))
|
|
{
|
|
ui32C2 = ui32Shift + 1;
|
|
}
|
|
else
|
|
{
|
|
ui32C2 = ui32Shift;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
ui32AdaptRate &= ~(1 << ui32Shift);
|
|
}
|
|
ui32Shift--;
|
|
}
|
|
if(!ui32C2)
|
|
{
|
|
ui32C2 = ui32C1 = ui32C1 - 1;
|
|
}
|
|
|
|
ui32C1 = 10 - ui32C1;
|
|
ui32C2 = 10 - ui32C2;
|
|
|
|
//
|
|
// Update the recharge rate parameters.
|
|
//
|
|
ui32Reg &= ~(AON_WUC_RECHARGECFG_C1_M | AON_WUC_RECHARGECFG_C2_M);
|
|
ui32Reg |= (ui32C1 << AON_WUC_RECHARGECFG_C1_S) |
|
|
(ui32C2 << AON_WUC_RECHARGECFG_C2_S) |
|
|
AON_WUC_RECHARGECFG_ADAPTIVE_EN_M;
|
|
}
|
|
|
|
//
|
|
// Resolve the period into an exponent and mantissa.
|
|
//
|
|
ui32Period = (ui32Period >> 4);
|
|
ui32Exponent = 0;
|
|
while(ui32Period > (AON_WUC_RECHARGECFG_PER_M_M >> AON_WUC_RECHARGECFG_PER_M_S))
|
|
{
|
|
ui32Period >>= 1;
|
|
ui32Exponent++;
|
|
}
|
|
ui32Mantissa = ui32Period;
|
|
|
|
//
|
|
// Resolve the max period into an exponent and mantissa.
|
|
//
|
|
ui32MaxPeriod = (ui32MaxPeriod >> 4);
|
|
ui32MaxExponent = 0;
|
|
while(ui32MaxPeriod > (AON_WUC_RECHARGECFG_MAX_PER_M_M >> AON_WUC_RECHARGECFG_MAX_PER_M_S))
|
|
{
|
|
ui32MaxPeriod >>= 1;
|
|
ui32MaxExponent++;
|
|
}
|
|
ui32MaxMantissa = ui32MaxPeriod;
|
|
|
|
|
|
//
|
|
// Configure the controller.
|
|
//
|
|
ui32Reg |= ((ui32MaxMantissa << AON_WUC_RECHARGECFG_MAX_PER_M_S) |
|
|
(ui32MaxExponent << AON_WUC_RECHARGECFG_MAX_PER_E_S) |
|
|
(ui32Mantissa << AON_WUC_RECHARGECFG_PER_M_S) |
|
|
(ui32Exponent << AON_WUC_RECHARGECFG_PER_E_S));
|
|
HWREG(AON_WUC_BASE + AON_WUC_O_RECHARGECFG) = ui32Reg;
|
|
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure the interval for oscillator amplitude calibration
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AONWUCOscConfig(uint32_t ui32Period)
|
|
{
|
|
uint32_t ui32Mantissa;
|
|
uint32_t ui32Exponent;
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Resolve the period into a exponent and mantissa.
|
|
//
|
|
ui32Period = (ui32Period >> 4);
|
|
ui32Exponent = 0;
|
|
while(ui32Period > (AON_WUC_OSCCFG_PER_M_M >> AON_WUC_OSCCFG_PER_M_S))
|
|
{
|
|
ui32Period >>= 1;
|
|
ui32Exponent++;
|
|
}
|
|
ui32Mantissa = ui32Period;
|
|
|
|
//
|
|
// Update the period for the oscillator amplitude calibration.
|
|
//
|
|
HWREG(AON_WUC_BASE + AON_WUC_O_OSCCFG) =
|
|
(ui32Mantissa << AON_WUC_OSCCFG_PER_M_S) |
|
|
(ui32Exponent << AON_WUC_OSCCFG_PER_E_S);
|
|
|
|
//
|
|
// Set the maximum reacharge period equal to the oscillator amplitude
|
|
// calibration period.
|
|
//
|
|
ui32Reg = HWREG(AON_WUC_BASE + AON_WUC_O_RECHARGECFG);
|
|
ui32Reg &= ~(AON_WUC_RECHARGECFG_MAX_PER_M_M | AON_WUC_RECHARGECFG_MAX_PER_E_M);
|
|
ui32Reg |= ((ui32Mantissa << AON_WUC_RECHARGECFG_MAX_PER_M_S) |
|
|
(ui32Exponent << AON_WUC_RECHARGECFG_MAX_PER_E_S));
|
|
|
|
//
|
|
// Write the configuration.
|
|
//
|
|
HWREG(AON_WUC_BASE + AON_WUC_O_RECHARGECFG) = ui32Reg;
|
|
}
|
|
//! @}
|
|
//! \\addtogroup aux_ctrl_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Load AUX controller Firmware into dedicated RAM
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AUXCTRLImageLoad(uint16_t *pui16Image, uint32_t ui32StartAddr,
|
|
uint32_t ui32Size)
|
|
{
|
|
uint16_t* pui16Src16;
|
|
uint16_t* pui16Dst16;
|
|
uint32_t ui32WordCnt;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32StartAddr < 512);
|
|
ASSERT(ui32Size <= 1024);
|
|
ASSERT((ui32Size / 2 + ui32StartAddr) <= 512);
|
|
|
|
//
|
|
// Copy image to AUX RAM.
|
|
//
|
|
ui32WordCnt = (ui32Size >> 1);
|
|
pui16Src16 = pui16Image;
|
|
pui16Dst16 = (uint16_t*)(AUX_RAM_BASE + (ui32StartAddr << 1));
|
|
|
|
while(ui32WordCnt--)
|
|
{
|
|
*pui16Dst16++ = *pui16Src16++;
|
|
}
|
|
}
|
|
//! @}
|
|
//! \\addtogroup aux_tdc_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure the operation of the AUX TDC
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AUXTDCConfigSet(uint32_t ui32Base, uint32_t ui32StartCondition,
|
|
uint32_t ui32StopCondition)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(AUXTDCBaseValid(ui32Base));
|
|
|
|
//
|
|
// Make sure the AUX TDC is in the idle state before changing the
|
|
// configuration.
|
|
//
|
|
while(!((HWREG(ui32Base + AUX_TDC_O_STAT) & AUX_TDC_STAT_STATE_M) ==
|
|
AUX_TDC_STAT_STATE_IDLE))
|
|
{
|
|
}
|
|
|
|
//
|
|
// Clear previous results.
|
|
//
|
|
HWREG(ui32Base + AUX_TDC_O_CTL) = 0x0;
|
|
|
|
//
|
|
// Change the configuration.
|
|
//
|
|
HWREG(ui32Base + AUX_TDC_O_TRIGSRC) = ui32StartCondition | ui32StopCondition;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Check if the AUX TDC is done measuring
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AUXTDCMeasurementDone(uint32_t ui32Base)
|
|
{
|
|
uint32_t ui32Reg;
|
|
uint32_t ui32Status;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(AUXTDCBaseValid(ui32Base));
|
|
|
|
//
|
|
// Check if the AUX TDC is done measuring.
|
|
//
|
|
ui32Reg = HWREG(ui32Base + AUX_TDC_O_STAT);
|
|
if(ui32Reg & AUX_TDC_STAT_DONE)
|
|
{
|
|
ui32Status = AUX_TDC_DONE;
|
|
}
|
|
else if(ui32Reg & AUX_TDC_STAT_SAT)
|
|
{
|
|
ui32Status = AUX_TDC_TIMEOUT;
|
|
}
|
|
else
|
|
{
|
|
ui32Status = AUX_TDC_BUSY;
|
|
}
|
|
|
|
//
|
|
// Return the status.
|
|
//
|
|
return (ui32Status);
|
|
}
|
|
//! @}
|
|
//! \\addtogroup aux_timer_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure AUX timer
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AUXTimerConfigure(uint32_t ui32Timer, uint32_t ui32Config)
|
|
{
|
|
uint32_t ui32Val;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Timer == AUX_TIMER_0) || (ui32Timer == AUX_TIMER_1) ||
|
|
(ui32Timer == AUX_TIMER_BOTH));
|
|
ASSERT(((ui32Config & 0x0000000F) == AUX_TIMER_CFG_ONE_SHOT) ||
|
|
((ui32Config & 0x0000000F) == AUX_TIMER_CFG_PERIODIC) ||
|
|
((ui32Config & 0x0000000F) == AUX_TIMER_CFG_ONE_SHOT_EDGE_COUNT) ||
|
|
((ui32Config & 0x0000000F) == AUX_TIMER_CFG_PERIODIC_EDGE_COUNT) ||
|
|
((ui32Config & 0x000000F0) == AUX_TIMER_CFG_RISING_EDGE) ||
|
|
((ui32Config & 0x000000F0) == AUX_TIMER_CFG_FALLING_EDGE) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_RTC_EVENT) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_CMP_A) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_CMP_B) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_TDCDONE) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_TIMER0_EVENT) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_TIMER1_EVENT) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_SMPH_RELEASE) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_ADC_DONE) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO0) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO1) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO2) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO3) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO4) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO5) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO6) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO7) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO8) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO9) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO10) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO11) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO12) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO13) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO14) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_AIO15) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_ACLK_REF) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_MCU_EVENT) ||
|
|
((ui32Config & 0x00000F00) == AUX_TIMER_CFG_TICK_SRC_ADC_IRQ));
|
|
|
|
//
|
|
// Configure Timer 0.
|
|
//
|
|
if(ui32Timer & AUX_TIMER_0)
|
|
{
|
|
//
|
|
// Stop timer 0.
|
|
//
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T0CTL) = 0;
|
|
|
|
//
|
|
// Set mode.
|
|
//
|
|
ui32Val = HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T0CFG);
|
|
ui32Val &= ~(AUX_TIMER_T0CFG_MODE_M | AUX_TIMER_T0CFG_RELOAD_M);
|
|
ui32Val |= (ui32Config & (AUX_TIMER_T0CFG_MODE_M |
|
|
AUX_TIMER_T0CFG_RELOAD_M));
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T0CFG) = ui32Val;
|
|
|
|
//
|
|
// If edge counter, set rising/falling edge and tick source.
|
|
//
|
|
if(ui32Config & AUX_TIMER_T0CFG_MODE_M)
|
|
{
|
|
ui32Val = HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T0CFG);
|
|
ui32Val &= ~(AUX_TIMER_T0CFG_TICK_SRC_POL_M |
|
|
AUX_TIMER_T0CFG_TICK_SRC_M);
|
|
|
|
//
|
|
// Set edge polarity.
|
|
//
|
|
if(ui32Config & AUX_TIMER_CFG_FALLING_EDGE)
|
|
{
|
|
ui32Val |= AUX_TIMER_T0CFG_TICK_SRC_POL;
|
|
}
|
|
|
|
//
|
|
// Set tick source.
|
|
//
|
|
ui32Val |= ((ui32Config & 0x00000F00) >> 8) <<
|
|
AUX_TIMER_T0CFG_TICK_SRC_S;
|
|
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T0CFG) = ui32Val;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Configure Timer 1.
|
|
//
|
|
if(ui32Timer & AUX_TIMER_1)
|
|
{
|
|
//
|
|
// Stop timer 1.
|
|
//
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T1CTL) = 0;
|
|
|
|
//
|
|
// Set mode.
|
|
//
|
|
ui32Val = HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T1CFG);
|
|
ui32Val &= ~(AUX_TIMER_T1CFG_MODE_M | AUX_TIMER_T1CFG_RELOAD_M);
|
|
ui32Val |= ((ui32Config) & (AUX_TIMER_T1CFG_MODE_M |
|
|
AUX_TIMER_T1CFG_RELOAD_M));
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T1CFG) = ui32Val;
|
|
|
|
//
|
|
// If edge counter, set rising/falling edge and tick source.
|
|
//
|
|
if(ui32Config & AUX_TIMER_T1CFG_MODE)
|
|
{
|
|
ui32Val = HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T1CFG);
|
|
ui32Val &= ~(AUX_TIMER_T1CFG_TICK_SRC_POL_M |
|
|
AUX_TIMER_T1CFG_TICK_SRC_M);
|
|
|
|
//
|
|
// Set edge polarity.
|
|
//
|
|
if(ui32Config & AUX_TIMER_CFG_FALLING_EDGE)
|
|
{
|
|
ui32Val |= AUX_TIMER_T1CFG_TICK_SRC_POL;
|
|
}
|
|
|
|
//
|
|
// Set tick source.
|
|
//
|
|
ui32Val |= ((ui32Config & 0x00000F00) >> 8) <<
|
|
AUX_TIMER_T1CFG_TICK_SRC_S;
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T1CFG) = ui32Val;
|
|
}
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Start AUX timer
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AUXTimerStart(uint32_t ui32Timer)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Timer == AUX_TIMER_0) ||
|
|
(ui32Timer == AUX_TIMER_1) ||
|
|
(ui32Timer == AUX_TIMER_BOTH));
|
|
|
|
if(ui32Timer & AUX_TIMER_0)
|
|
{
|
|
//
|
|
// Start timer 0.
|
|
//
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T0CTL) = AUX_TIMER_T0CTL_EN;
|
|
}
|
|
if(ui32Timer & AUX_TIMER_1)
|
|
{
|
|
//
|
|
// Start timer 1.
|
|
//
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T1CTL) = AUX_TIMER_T1CTL_EN;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Stop AUX timer
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AUXTimerStop(uint32_t ui32Timer)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Timer == AUX_TIMER_0) ||
|
|
(ui32Timer == AUX_TIMER_1) ||
|
|
(ui32Timer == AUX_TIMER_BOTH));
|
|
|
|
if(ui32Timer & AUX_TIMER_0)
|
|
{
|
|
//
|
|
// Stop timer 0.
|
|
//
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T0CTL) = 0;
|
|
}
|
|
if(ui32Timer & AUX_TIMER_1)
|
|
{
|
|
//
|
|
// Stop timer 1.
|
|
//
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T1CTL) = 0;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set AUX timer prescale value
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
AUXTimerPrescaleSet(uint32_t ui32Timer, uint32_t ui32PrescaleDiv)
|
|
{
|
|
uint32_t ui32Val;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Timer == AUX_TIMER_0) || (ui32Timer == AUX_TIMER_1) ||
|
|
(ui32Timer == AUX_TIMER_BOTH));
|
|
ASSERT(ui32PrescaleDiv <= AUX_TIMER_PRESCALE_DIV_32768);
|
|
|
|
if(ui32Timer & AUX_TIMER_0)
|
|
{
|
|
//
|
|
// Set timer 0 prescale value.
|
|
//
|
|
ui32Val = HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T0CFG);
|
|
ui32Val &= ~AUX_TIMER_T0CFG_PRE_M;
|
|
ui32Val |= ui32PrescaleDiv << AUX_TIMER_T0CFG_PRE_S;
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T0CFG) = ui32Val;
|
|
}
|
|
if(ui32Timer & AUX_TIMER_1)
|
|
{
|
|
//
|
|
// Set timer 1 prescale value.
|
|
//
|
|
ui32Val = HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T1CFG);
|
|
ui32Val &= ~AUX_TIMER_T1CFG_PRE_M;
|
|
ui32Val |= ui32PrescaleDiv << AUX_TIMER_T1CFG_PRE_S;
|
|
HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T1CFG) = ui32Val;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get AUX timer prescale value
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
AUXTimerPrescaleGet(uint32_t ui32Timer)
|
|
{
|
|
uint32_t ui32Val;
|
|
uint32_t ui32PrescaleDiv;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Timer == AUX_TIMER_0) || (ui32Timer == AUX_TIMER_1));
|
|
|
|
ui32Val = (HWREG(AUX_TIMER_BASE + AUX_TIMER_O_T0CFG));
|
|
if(ui32Timer & AUX_TIMER_0)
|
|
{
|
|
//
|
|
// Get timer 0 prescale value.
|
|
//
|
|
ui32PrescaleDiv =
|
|
(ui32Val & AUX_TIMER_T0CFG_PRE_M) >> AUX_TIMER_T0CFG_PRE_S;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Get timer 1 prescale value.
|
|
//
|
|
ui32PrescaleDiv =
|
|
(ui32Val & AUX_TIMER_T1CFG_PRE_M) >> AUX_TIMER_T1CFG_PRE_S;
|
|
}
|
|
|
|
return(ui32PrescaleDiv);
|
|
}
|
|
//! @}
|
|
//! \\addtogroup aux_wuc_api
|
|
//! @{
|
|
//****************************************************************************
|
|
//
|
|
//! Enable clocks for peripherals in the AUX domain
|
|
//
|
|
//****************************************************************************
|
|
void
|
|
AUXWUCClockEnable(uint32_t ui32Clocks)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Clocks & AUX_WUC_ADI_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_OSCCTRL_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_TDCIF_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_SOC_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_TIMER_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_AIODIO0_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_AIODIO1_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_SMPH_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_TDC_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_ADC_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_REF_CLOCK));
|
|
|
|
//
|
|
// Enable some of the clocks in the clock register.
|
|
//
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_MODCLKEN0) |= (ui32Clocks &
|
|
AUX_WUC_MODCLK_MASK);
|
|
|
|
//
|
|
// Check the rest.
|
|
//
|
|
if(ui32Clocks & AUX_WUC_ADC_CLOCK)
|
|
{
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_ADCCLKCTL) =
|
|
AUX_WUC_ADCCLKCTL_REQ;
|
|
}
|
|
if(ui32Clocks & AUX_WUC_TDC_CLOCK)
|
|
{
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_TDCCLKCTL) =
|
|
AUX_WUC_TDCCLKCTL_REQ;
|
|
}
|
|
if(ui32Clocks & AUX_WUC_REF_CLOCK)
|
|
{
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_REFCLKCTL) =
|
|
AUX_WUC_REFCLKCTL_REQ;
|
|
}
|
|
}
|
|
//****************************************************************************
|
|
//
|
|
//! Disable clocks for peripherals in the AUX domain
|
|
//
|
|
//****************************************************************************
|
|
void
|
|
AUXWUCClockDisable(uint32_t ui32Clocks)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Clocks & AUX_WUC_ADI_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_OSCCTRL_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_TDCIF_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_SOC_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_TIMER_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_AIODIO0_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_AIODIO1_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_SMPH_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_TDC_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_ADC_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_REF_CLOCK));
|
|
|
|
//
|
|
// Disable some of the clocks in the clock register.
|
|
//
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_MODCLKEN0) &= ~(ui32Clocks &
|
|
AUX_WUC_MODCLK_MASK);
|
|
|
|
//
|
|
// Check the rest.
|
|
//
|
|
if(ui32Clocks & AUX_WUC_ADC_CLOCK)
|
|
{
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_ADCCLKCTL) &=
|
|
~AUX_WUC_ADCCLKCTL_REQ;
|
|
}
|
|
if(ui32Clocks & AUX_WUC_TDC_CLOCK)
|
|
{
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_TDCCLKCTL) &=
|
|
~AUX_WUC_TDCCLKCTL_REQ;
|
|
}
|
|
if(ui32Clocks & AUX_WUC_REF_CLOCK)
|
|
{
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_REFCLKCTL) &=
|
|
~AUX_WUC_REFCLKCTL_REQ;
|
|
}
|
|
}
|
|
//****************************************************************************
|
|
//
|
|
//! Get the status of a clock
|
|
//
|
|
//****************************************************************************
|
|
uint32_t
|
|
AUXWUCClockStatus(uint32_t ui32Clocks)
|
|
{
|
|
bool bClockStatus;
|
|
uint32_t ui32ClockRegister;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Clocks & AUX_WUC_ADI_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_OSCCTRL_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_TDCIF_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_SOC_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_TIMER_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_AIODIO0_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_AIODIO1_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_SMPH_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_TDC_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_ADC_CLOCK) ||
|
|
(ui32Clocks & AUX_WUC_REF_CLOCK));
|
|
|
|
bClockStatus = true;
|
|
|
|
//
|
|
// Read the status registers.
|
|
//
|
|
ui32ClockRegister = HWREG(AUX_WUC_BASE + AUX_WUC_O_MODCLKEN0);
|
|
|
|
//
|
|
// Check all requested clocks
|
|
//
|
|
if(ui32Clocks & AUX_WUC_ADI_CLOCK)
|
|
{
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_MODCLKEN0_AUX_ADI ?
|
|
true : false);
|
|
}
|
|
if(ui32Clocks & AUX_WUC_OSCCTRL_CLOCK)
|
|
{
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_MODCLKEN0_OSCCTL ?
|
|
true : false);
|
|
}
|
|
if(ui32Clocks & AUX_WUC_TDCIF_CLOCK)
|
|
{
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_MODCLKEN0_TDC ?
|
|
true : false);
|
|
}
|
|
if(ui32Clocks & AUX_WUC_SOC_CLOCK)
|
|
{
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_MODCLKEN0_SOC ?
|
|
true : false);
|
|
}
|
|
if(ui32Clocks & AUX_WUC_TIMER_CLOCK)
|
|
{
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_MODCLKEN0_TIMER ?
|
|
true : false);
|
|
}
|
|
if(ui32Clocks & AUX_WUC_AIODIO0_CLOCK)
|
|
{
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_MODCLKEN0_AIODIO0 ?
|
|
true : false);
|
|
}
|
|
if(ui32Clocks & AUX_WUC_AIODIO1_CLOCK)
|
|
{
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_MODCLKEN0_AIODIO1 ?
|
|
true : false);
|
|
}
|
|
if(ui32Clocks & AUX_WUC_SMPH_CLOCK)
|
|
{
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_MODCLKEN0_SMPH ?
|
|
true : false);
|
|
}
|
|
if(ui32Clocks & AUX_WUC_ADC_CLOCK)
|
|
{
|
|
ui32ClockRegister = HWREG(AUX_WUC_BASE + AUX_WUC_O_ADCCLKCTL);
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_ADCCLKCTL_ACK ?
|
|
true : false);
|
|
}
|
|
if(ui32Clocks & AUX_WUC_TDC_CLOCK)
|
|
{
|
|
ui32ClockRegister = HWREG(AUX_WUC_BASE + AUX_WUC_O_TDCCLKCTL);
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_TDCCLKCTL_ACK ?
|
|
true : false);
|
|
}
|
|
if(ui32Clocks & AUX_WUC_REF_CLOCK)
|
|
{
|
|
ui32ClockRegister = HWREG(AUX_WUC_BASE + AUX_WUC_O_REFCLKCTL);
|
|
bClockStatus = bClockStatus && (ui32ClockRegister &
|
|
AUX_WUC_REFCLKCTL_ACK ?
|
|
true : false);
|
|
}
|
|
|
|
//
|
|
// Return the clock status.
|
|
//
|
|
return bClockStatus ? AUX_WUC_CLOCK_READY : AUX_WUC_CLOCK_OFF;
|
|
}
|
|
//****************************************************************************
|
|
//
|
|
//! Control the power to the AUX domain
|
|
//
|
|
//****************************************************************************
|
|
void
|
|
AUXWUCPowerCtrl(uint32_t ui32PowerMode)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32PowerMode == AUX_WUC_POWER_OFF) ||
|
|
(ui32PowerMode == AUX_WUC_POWER_DOWN) ||
|
|
(ui32PowerMode == AUX_WUC_POWER_ACTIVE));
|
|
|
|
//
|
|
// Power on/off.
|
|
//
|
|
if(ui32PowerMode == AUX_WUC_POWER_OFF)
|
|
{
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_PWROFFREQ) = AUX_WUC_PWROFFREQ_REQ;
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_MCUBUSCTL) = AUX_WUC_MCUBUSCTL_DISCONNECT_REQ;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_PWROFFREQ) = 0x0;
|
|
}
|
|
|
|
//
|
|
// Power down/active.
|
|
//
|
|
if(ui32PowerMode == AUX_WUC_POWER_DOWN)
|
|
{
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_PWRDWNREQ) =
|
|
AUX_WUC_PWRDWNREQ_REQ;
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_MCUBUSCTL) = AUX_WUC_MCUBUSCTL_DISCONNECT_REQ;
|
|
}
|
|
else
|
|
{
|
|
HWREG(AUX_WUC_BASE + AUX_WUC_O_PWRDWNREQ) = 0x0;
|
|
}
|
|
}
|
|
//! @}
|
|
//! \\addtogroup ddi_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Write a single bit using a 16-bit maskable write
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
DDI16BitWrite(uint32_t ui32Base, uint32_t ui32Reg,
|
|
uint32_t ui32Mask, uint32_t ui32WrData)
|
|
{
|
|
uint32_t ui32RegAddr;
|
|
uint32_t ui32Data;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(DDIBaseValid(ui32Base));
|
|
ASSERT(!((ui32Mask & 0xFFFF0000) ^ (ui32Mask & 0x0000FFFF)));
|
|
ASSERT(!(ui32WrData & 0xFFFF0000));
|
|
|
|
//
|
|
// DDI 16-bit target is on 32-bit boundary so double offset
|
|
//
|
|
ui32RegAddr = ui32Base + (ui32Reg << 1) + DDI_O_MASK16B;
|
|
|
|
//
|
|
// Adjust for target bit in high half of the word.
|
|
//
|
|
if(ui32Mask & 0xFFFF0000)
|
|
{
|
|
ui32RegAddr += 4;
|
|
ui32Mask >>= 16;
|
|
}
|
|
|
|
//
|
|
// Write mask if data is not zero (to set mask bit), else write '0'.
|
|
//
|
|
ui32Data = ui32WrData ? ui32Mask : 0x0;
|
|
|
|
//
|
|
// Update the register.
|
|
//
|
|
HWREG(ui32RegAddr) = (ui32Mask << 16) | ui32Data;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Write a bitfield via the DDI using 16-bit maskable write
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
DDI16BitfieldWrite(uint32_t ui32Base, uint32_t ui32Reg,
|
|
uint32_t ui32Mask, uint32_t ui32Shift,
|
|
uint16_t ui32Data)
|
|
{
|
|
uint32_t ui32RegAddr;
|
|
uint32_t ui32WrData;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(DDIBaseValid(ui32Base));
|
|
|
|
//
|
|
// 16-bit target is on 32-bit boundary so double offset.
|
|
//
|
|
ui32RegAddr = ui32Base + (ui32Reg << 1) + DDI_O_MASK16B;
|
|
|
|
//
|
|
// Adjust for target bit in high half of the word.
|
|
//
|
|
if(ui32Shift >= 16)
|
|
{
|
|
ui32Shift = ui32Shift - 16;
|
|
ui32RegAddr += 4;
|
|
ui32Mask = ui32Mask >> 16;
|
|
}
|
|
|
|
//
|
|
// Shift data in to position.
|
|
//
|
|
ui32WrData = ui32Data << ui32Shift;
|
|
|
|
//
|
|
// Write data.
|
|
//
|
|
HWREG(ui32RegAddr) = (ui32Mask << 16) | ui32WrData;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Read a bit via the DDI using 16-bit READ.
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t
|
|
DDI16BitRead(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Mask)
|
|
{
|
|
uint32_t ui32RegAddr;
|
|
uint16_t ui16Data;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(DDIBaseValid(ui32Base));
|
|
|
|
//
|
|
// Calculate the address of the register.
|
|
//
|
|
ui32RegAddr = ui32Base + ui32Reg + DDI_O_DIR;
|
|
|
|
//
|
|
// Adjust for target bit in high half of the word.
|
|
//
|
|
if(ui32Mask & 0xFFFF0000)
|
|
{
|
|
ui32RegAddr += 2;
|
|
ui32Mask = ui32Mask >> 16;
|
|
}
|
|
|
|
//
|
|
// Read a halfword on the DDI interface.
|
|
//
|
|
ui16Data = HWREGH(ui32RegAddr);
|
|
|
|
//
|
|
// Mask data.
|
|
//
|
|
ui16Data = ui16Data & ui32Mask;
|
|
|
|
//
|
|
// Return masked data.
|
|
//
|
|
return(ui16Data);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Read a bitfield via the DDI using 16-bit read.
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t
|
|
DDI16BitfieldRead(uint32_t ui32Base, uint32_t ui32Reg,
|
|
uint32_t ui32Mask, uint32_t ui32Shift)
|
|
{
|
|
uint32_t ui32RegAddr;
|
|
uint16_t ui16Data;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(DDIBaseValid(ui32Base));
|
|
|
|
//
|
|
// Calculate the register address.
|
|
//
|
|
ui32RegAddr = ui32Base + ui32Reg + DDI_O_DIR;
|
|
|
|
//
|
|
// Adjust for target bit in high half of the word.
|
|
//
|
|
if(ui32Shift >= 16)
|
|
{
|
|
ui32Shift = ui32Shift - 16;
|
|
ui32RegAddr += 2;
|
|
ui32Mask = ui32Mask >> 16;
|
|
}
|
|
|
|
//
|
|
// Read the register.
|
|
//
|
|
ui16Data = HWREGH(ui32RegAddr);
|
|
|
|
//
|
|
// Mask data and shift into place.
|
|
//
|
|
ui16Data &= ui32Mask;
|
|
ui16Data >>= ui32Shift;
|
|
|
|
//
|
|
// Return data.
|
|
//
|
|
return(ui16Data);
|
|
}
|
|
//! @}
|
|
//! \\addtogroup flash_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
// Default values for security control in customer configuration area in flash
|
|
// top sector. TBD! It must be asured that layout corresponds with CCFG.
|
|
//
|
|
//*****************************************************************************
|
|
const uint8_t g_pui8CcfgDefaultSec[] = {0xFF, 0xFF, 0xFF, 0xC5,
|
|
0xFF, 0xFF, 0xFF, 0xFF,
|
|
0xC5, 0xFF, 0xFF, 0xFF,
|
|
0xC5, 0xC5, 0xC5, 0xFF,
|
|
0xC5, 0xC5, 0xC5, 0xFF
|
|
};
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Function prototypes for static functions
|
|
//
|
|
//*****************************************************************************
|
|
static void IssueFsmCommand(tFlashStateCommandsType eCommand);
|
|
static void EnableSectorsForWrite(void);
|
|
static uint32_t ScaleCycleValues(uint32_t ui32SpecifiedTiming,
|
|
uint32_t ui32ScaleValue);
|
|
static void SetWriteMode(void);
|
|
static void SetReadMode(void);
|
|
static void TrimForWrite(void);
|
|
//*****************************************************************************
|
|
//
|
|
//! \internal
|
|
//! Issues a command to the Flash State Machine.
|
|
//!
|
|
//! \param eCommand specifies the FSM command.
|
|
//!
|
|
//! Issues a command to the Flash State Machine.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
static void
|
|
IssueFsmCommand(tFlashStateCommandsType eCommand)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(
|
|
eCommand == FAPI_ERASE_SECTOR || eCommand == FAPI_ERASE_BANK ||
|
|
eCommand == FAPI_VALIDATE_SECTOR || eCommand == FAPI_CLEAR_STATUS ||
|
|
eCommand == FAPI_PROGRAM_RESUME || eCommand == FAPI_ERASE_RESUME ||
|
|
eCommand == FAPI_CLEAR_MORE || eCommand == FAPI_PROGRAM_SECTOR ||
|
|
eCommand == FAPI_PROGRAM_DATA || eCommand == FAPI_ERASE_OTP);
|
|
|
|
//
|
|
// Enable write to FSM register.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
|
|
//
|
|
// Issue FSM command.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_CMD) = eCommand;
|
|
|
|
//
|
|
// Start command execute.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_EXECUTE) = FLASH_CMD_EXEC;
|
|
|
|
//
|
|
// Disable write to FSM register.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! \internal
|
|
//! Enables all sectors for erase and programming on the active bank.
|
|
//!
|
|
//! This function disables the idle reading power reduction mode, selects the
|
|
//! flash bank and enables all sectors for erase and programming on the active
|
|
//! bank.
|
|
//! Sectores may be protected from programming depending on the value of the
|
|
//! FLASH_O_FSM_BSLPx registers.
|
|
//! Sectores may be protected from erase depending on the value of the
|
|
//! FLASH_O_FSM_BSLEx registers. Additional sector erase protection is set by
|
|
//! the FLASH_O_FSM_SECTOR1 register.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
static void
|
|
EnableSectorsForWrite(void)
|
|
{
|
|
//
|
|
// Trim flash module for program/erase operation.
|
|
//
|
|
TrimForWrite();
|
|
|
|
//
|
|
// Configure flash to write mode
|
|
//
|
|
SetWriteMode();
|
|
|
|
//
|
|
// Select flash bank.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FMAC) = 0x00;
|
|
|
|
//
|
|
// Disable Level 1 Protection.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
|
|
|
|
//
|
|
// Enable all sectors for erase and programming.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBSE) = 0xFFFF;
|
|
|
|
//
|
|
// Enable Level 1 Protection
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! \internal
|
|
//! Trims the Flash Bank and Flash Pump for program/erase functionality
|
|
//!
|
|
//! This trimming will make it possible to perform erase and program operations
|
|
//! of the flash. Trim values are loaded from factory configuration area
|
|
//! (referred to as FCGF1). The trimming done by this function is valid until
|
|
//! reset of the flash module.
|
|
//!
|
|
//! Some registers shall be written with a value that is a number of FCLK
|
|
//! cycles. The trim values controlling these registers have a value of
|
|
//! number of half us. FCLK = SysClk / ((RWAIT+1) x 2).
|
|
//! In order to calculate the register value for these registers the
|
|
//! following calculation must be done:
|
|
//!
|
|
//! OtpValue SysClkMHz
|
|
//! -------- us OtpValue x ---------
|
|
//! 2 (RWAIT+1)
|
|
//! RegValue_in_no_of_clk_cycles = ----------------- = ---------------------
|
|
//! 1 4
|
|
//! --------------
|
|
//! SysClkMHz
|
|
//! ------------
|
|
//! (RWAIT+1)x 2
|
|
//!
|
|
//! This is equevivalent to:
|
|
//!
|
|
//! 16 x SysClkMHz
|
|
//! OtpValue x ---------------
|
|
//! (RWAIT+1)
|
|
//! RegValue_in_no_of_clk_cycles = ----------------------------
|
|
//! 64
|
|
//!
|
|
//! 16 x SysClkMHz
|
|
//! A scaling factor is set equal to: ui32FclkScale = --------------
|
|
//! (RWAIT+1)
|
|
//!
|
|
//! which gives:
|
|
//! OtpValue x ui32FclkScale
|
|
//! RegValue_in_no_of_clk_cycles = ------------------------
|
|
//! 64
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
static void
|
|
TrimForWrite(void)
|
|
{
|
|
uint32_t ui32Value;
|
|
uint32_t ui32TempVal;
|
|
uint32_t ui32FclkScale;
|
|
uint32_t ui32RWait;
|
|
|
|
//
|
|
// Return if flash is already trimmed for program/erase operations.
|
|
//
|
|
if(HWREG(FLASH_BASE + FLASH_O_FWFLAG) & FW_WRT_TRIMMED)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//***********************************************************************//
|
|
// //
|
|
// Configure the FSM registers //
|
|
// //
|
|
//***********************************************************************//
|
|
|
|
//
|
|
// Enable access to the FSM registers.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
|
|
//
|
|
// Determine the scaling value to be used on timing related trim values.
|
|
// The scaling value is based on the flash module clock frequency and RWAIT
|
|
//
|
|
ui32RWait = (HWREG(FLASH_BASE + FLASH_O_FRDCTL) &
|
|
FLASH_FRDCTL_RWAIT_M) >> FLASH_FRDCTL_RWAIT_S;
|
|
ui32FclkScale = (16 * FLASH_MODULE_CLK_FREQ) / (ui32RWait + 1);
|
|
|
|
//
|
|
// Configure Program puls width bits 15:0.
|
|
// (FCFG1 offset 0x188 bits 15:0).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_PROG_EP) &
|
|
FACTORY_CFG_FLASH_PROG_EP_PROGRAM_PW_M) >>
|
|
FACTORY_CFG_FLASH_PROG_EP_PROGRAM_PW_S;
|
|
|
|
ui32Value = ScaleCycleValues(ui32Value, ui32FclkScale);
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PW) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PW) &
|
|
~FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M) |
|
|
((ui32Value << FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_S) &
|
|
FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M);
|
|
|
|
//
|
|
// Configure Erase puls width bits 31:0.
|
|
// (FCFG1 offset 0x18C bits 31:0).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_ERA_PW) &
|
|
FACTORY_CFG_FLASH_ERA_PW_ERASE_PW_M) >>
|
|
FACTORY_CFG_FLASH_ERA_PW_ERASE_PW_S;
|
|
|
|
ui32Value = ScaleCycleValues(ui32Value, ui32FclkScale);
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PW) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PW) &
|
|
~FLASH_FSM_ERA_PW_FSM_ERA_PW_M) |
|
|
((ui32Value << FLASH_FSM_ERA_PW_FSM_ERA_PW_S) &
|
|
FLASH_FSM_ERA_PW_FSM_ERA_PW_M);
|
|
|
|
|
|
//
|
|
// Configure no of flash clock cycles from EXECUTEZ going low to the
|
|
// verify data can be read in the program verify mode bits 7:0.
|
|
// (FCFG1 offset 0x174 bits 23:16).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_C_E_P_R) &
|
|
FACTORY_CFG_FLASH_C_E_P_R_PV_ACCESS_M) >>
|
|
FACTORY_CFG_FLASH_C_E_P_R_PV_ACCESS_S;
|
|
|
|
ui32Value = ScaleCycleValues(ui32Value, ui32FclkScale);
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) &
|
|
~FLASH_FSM_EX_VAL_EXE_VALD_M) |
|
|
((ui32Value << FLASH_FSM_EX_VAL_EXE_VALD_S) &
|
|
FLASH_FSM_EX_VAL_EXE_VALD_M);
|
|
|
|
//
|
|
// Configure the number of flash clocks from the start of the Read mode at
|
|
// the end of the operations until the FSM clears the BUSY bit in FMSTAT.
|
|
// (FCFG1 offset 0x178 bits 23:16).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_P_R_PV) &
|
|
FACTORY_CFG_FLASH_P_R_PV_RH_M) >>
|
|
FACTORY_CFG_FLASH_P_R_PV_RH_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_RD_H) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_RD_H) &
|
|
~FLASH_FSM_RD_H_RD_H_M) |
|
|
((ui32Value << FLASH_FSM_RD_H_RD_H_S) &
|
|
FLASH_FSM_RD_H_RD_H_M);
|
|
|
|
//
|
|
// Configure Program hold time
|
|
// (FCFG1 offset 0x178 bits 31:24).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_P_R_PV) &
|
|
FACTORY_CFG_FLASH_P_R_PV_PH_M) >>
|
|
FACTORY_CFG_FLASH_P_R_PV_PH_S;
|
|
|
|
ui32Value = ScaleCycleValues(ui32Value, ui32FclkScale);
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_P_OH) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_P_OH) &
|
|
~FLASH_FSM_P_OH_PGM_OH_M) |
|
|
((ui32Value << FLASH_FSM_P_OH_PGM_OH_S) &
|
|
FLASH_FSM_P_OH_PGM_OH_M);
|
|
|
|
//
|
|
// Configure Erase hold time
|
|
// (FCFG1 offset 0x17C bits 31:24).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_EH_SEQ) &
|
|
FACTORY_CFG_FLASH_EH_SEQ_EH_M) >>
|
|
FACTORY_CFG_FLASH_EH_SEQ_EH_S;
|
|
|
|
ui32Value = ScaleCycleValues(ui32Value, ui32FclkScale);
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ERA_OH) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_OH) &
|
|
~FLASH_FSM_ERA_OH_ERA_OH_M) |
|
|
((ui32Value << FLASH_FSM_ERA_OH_ERA_OH_S) &
|
|
FLASH_FSM_ERA_OH_ERA_OH_M);
|
|
|
|
//
|
|
// Configure Program verify row switch time
|
|
// (FCFG1 offset0x178 bits 15:8).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_P_R_PV) &
|
|
FACTORY_CFG_FLASH_P_R_PV_PVH_M) >>
|
|
FACTORY_CFG_FLASH_P_R_PV_PVH_S;
|
|
|
|
ui32Value = ScaleCycleValues(ui32Value, ui32FclkScale);
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_PE_VH) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_PE_VH) &
|
|
~FLASH_FSM_PE_VH_PGM_VH_M) |
|
|
((ui32Value << FLASH_FSM_PE_VH_PGM_VH_S) &
|
|
FLASH_FSM_PE_VH_PGM_VH_M);
|
|
|
|
//
|
|
// Configure Program Operation Setup time
|
|
// (FCFG1 offset 0x170 bits 31:24).
|
|
//
|
|
ui32Value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_E_P) &
|
|
FACTORY_CFG_FLASH_E_P_PSU_M) >>
|
|
FACTORY_CFG_FLASH_E_P_PSU_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) &
|
|
~FLASH_FSM_PE_OSU_PGM_OSU_M) |
|
|
((ui32Value << FLASH_FSM_PE_OSU_PGM_OSU_S) &
|
|
FLASH_FSM_PE_OSU_PGM_OSU_M);
|
|
|
|
//
|
|
// Configure Erase Operation Setup time
|
|
// (FCGF1 offset 0x170 bits 23:16).
|
|
//
|
|
ui32Value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_E_P) &
|
|
FACTORY_CFG_FLASH_E_P_ESU_M) >>
|
|
FACTORY_CFG_FLASH_E_P_ESU_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) &
|
|
~FLASH_FSM_PE_OSU_ERA_OSU_M) |
|
|
((ui32Value << FLASH_FSM_PE_OSU_ERA_OSU_S) &
|
|
FLASH_FSM_PE_OSU_ERA_OSU_M);
|
|
|
|
//
|
|
// Confgure Program Verify Setup time
|
|
// (FCFG1 offset 0x170 bits 15:8).
|
|
//
|
|
ui32Value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_E_P) &
|
|
FACTORY_CFG_FLASH_E_P_PVSU_M) >>
|
|
FACTORY_CFG_FLASH_E_P_PVSU_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) &
|
|
~FLASH_FSM_PE_VSU_PGM_VSU_M) |
|
|
((ui32Value << FLASH_FSM_PE_VSU_PGM_VSU_S) &
|
|
FLASH_FSM_PE_VSU_PGM_VSU_M);
|
|
|
|
//
|
|
// Configure Erase Verify Setup time
|
|
// (FCFG1 offset 0x170 bits 7:0).
|
|
//
|
|
ui32Value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_E_P) &
|
|
FACTORY_CFG_FLASH_E_P_EVSU_M) >>
|
|
FACTORY_CFG_FLASH_E_P_EVSU_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) &
|
|
~FLASH_FSM_PE_VSU_ERA_VSU_M) |
|
|
((ui32Value << FLASH_FSM_PE_VSU_ERA_VSU_S) &
|
|
FLASH_FSM_PE_VSU_ERA_VSU_M);
|
|
|
|
//
|
|
// Configure Addr to EXECUTEZ low setup time
|
|
// (FCFG1 offset 0x174 bits 15:12).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_C_E_P_R) &
|
|
FACTORY_CFG_FLASH_C_E_P_R_A_EXEZ_SETUP_M) >>
|
|
FACTORY_CFG_FLASH_C_E_P_R_A_EXEZ_SETUP_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_CMP_VSU) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_CMP_VSU) &
|
|
~FLASH_FSM_CMP_VSU_ADD_EXZ_M) |
|
|
((ui32Value << FLASH_FSM_CMP_VSU_ADD_EXZ_S) &
|
|
FLASH_FSM_CMP_VSU_ADD_EXZ_M);
|
|
|
|
//
|
|
// Configure Voltage Status Count
|
|
// (FCFG1 offset 0x17C bits 15:12).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_EH_SEQ) &
|
|
FACTORY_CFG_FLASH_EH_SEQ_VSTAT_M) >>
|
|
FACTORY_CFG_FLASH_EH_SEQ_VSTAT_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_VSTAT) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_VSTAT) &
|
|
~FLASH_FSM_VSTAT_VSTAT_CNT_M) |
|
|
((ui32Value << FLASH_FSM_VSTAT_VSTAT_CNT_S) &
|
|
FLASH_FSM_VSTAT_VSTAT_CNT_M);
|
|
|
|
//
|
|
// Configure Repeat Verify action setup
|
|
// (FCFG1 offset 0x174 bits 31:24).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_C_E_P_R) &
|
|
FACTORY_CFG_FLASH_C_E_P_R_RVSU_M) >>
|
|
FACTORY_CFG_FLASH_C_E_P_R_RVSU_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) &
|
|
~FLASH_FSM_EX_VAL_REP_VSU_M) |
|
|
((ui32Value << FLASH_FSM_EX_VAL_REP_VSU_S) &
|
|
FLASH_FSM_EX_VAL_REP_VSU_M);
|
|
|
|
//
|
|
// Configure Maximum Programming Pulses
|
|
// (FCFG1 offset 0x184 bits 15:0).
|
|
//
|
|
ui32Value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_PP) &
|
|
FACTORY_CFG_FLASH_PP_MAX_PP_M) >>
|
|
FACTORY_CFG_FLASH_PP_MAX_PP_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) &
|
|
~FLASH_FSM_PRG_PUL_MAX_PRG_PUL_M) |
|
|
((ui32Value << FLASH_FSM_PRG_PUL_MAX_PRG_PUL_S) &
|
|
FLASH_FSM_PRG_PUL_MAX_PRG_PUL_M);
|
|
|
|
//
|
|
// Configure Beginning level for VHVCT used during erase modes
|
|
// (FCFG1 offset 0x180 bits 31:16).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_VHV_E) &
|
|
FACTORY_CFG_FLASH_VHV_E_VHV_E_START_M) >>
|
|
FACTORY_CFG_FLASH_VHV_E_VHV_E_START_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) &
|
|
~FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M) |
|
|
((ui32Value << FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_S) &
|
|
FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M);
|
|
|
|
//
|
|
// Configure Maximum EC Level
|
|
// (FCFG1 offset 0x2B0 bits 21:18).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_OTP_DATA3) &
|
|
FACTORY_CFG_FLASH_OTP_DATA3_MAX_EC_LEVEL_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA3_MAX_EC_LEVEL_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) &
|
|
~FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M) |
|
|
((ui32Value << FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_S) &
|
|
FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M);
|
|
|
|
//
|
|
// Configure Maximum Erase Pulses
|
|
// (FCFG1 offset 0x188 bits 31:16).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_PROG_EP) &
|
|
FACTORY_CFG_FLASH_PROG_EP_MAX_EP_M) >>
|
|
FACTORY_CFG_FLASH_PROG_EP_MAX_EP_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) &
|
|
~FLASH_FSM_ERA_PUL_MAX_ERA_PUL_M) |
|
|
((ui32Value << FLASH_FSM_ERA_PUL_MAX_ERA_PUL_S) &
|
|
FLASH_FSM_ERA_PUL_MAX_ERA_PUL_M);
|
|
|
|
//
|
|
// Configure the VHVCT Step Size. This is the number of erase pulses that
|
|
// must be completed for each level before the FSM increments the
|
|
// CUR_EC_LEVEL to the next higher level. Actual erase pulses per level
|
|
// equals (EC_STEP_SIZE +1). The stepping is only needed for the VHVCT
|
|
// voltage.
|
|
// (FCFG1 offset 0x2B0 bits 31:23).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_OTP_DATA3) &
|
|
FACTORY_CFG_FLASH_OTP_DATA3_EC_STEP_SIZE_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA3_EC_STEP_SIZE_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_STEP_SIZE) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_STEP_SIZE) &
|
|
~FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M) |
|
|
((ui32Value << FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_S) &
|
|
FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M);
|
|
|
|
//
|
|
// Configure the hight of each EC step. This is the number of counts that
|
|
// the CUR_EC_LEVEL will increment when going to a new level. Actual count
|
|
// size equals (EC_STEP_HEIGHT + 1). The stepping applies only to the VHVCT
|
|
// voltage.
|
|
// The read trim value is decremented by 1 before written to the register
|
|
// since actual counts equals (register value + 1).
|
|
// (FCFG1 offset 0x180 bits 15:0).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_VHV_E) &
|
|
FACTORY_CFG_FLASH_VHV_E_VHV_E_STEP_HIGHT_M) >>
|
|
FACTORY_CFG_FLASH_VHV_E_VHV_E_STEP_HIGHT_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_EC_STEP_HEIGHT) = ((ui32Value - 1) &
|
|
FLASH_FSM_EC_STEP_HEIGHT_EC_STEP_HEIGHT_M);
|
|
|
|
//
|
|
// Configure Precondition used in erase operations
|
|
// (FCFG1 offset 0x2B0 bit 22).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_OTP_DATA3) &
|
|
FACTORY_CFG_FLASH_OTP_DATA3_DO_PRECOND_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA3_DO_PRECOND_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &
|
|
~FLASH_FSM_ST_MACHINE_DO_PRECOND_M) |
|
|
((ui32Value << FLASH_FSM_ST_MACHINE_DO_PRECOND_S) &
|
|
FLASH_FSM_ST_MACHINE_DO_PRECOND_M);
|
|
|
|
//
|
|
// Enable the recommended Good Time function.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=
|
|
FLASH_FSM_ST_MACHINE_ONE_TIME_GOOD;
|
|
|
|
//
|
|
// Disable write access to FSM registers.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
|
|
|
|
//***********************************************************************//
|
|
// //
|
|
// Configure the voltage registers //
|
|
// //
|
|
//***********************************************************************//
|
|
|
|
//
|
|
// Unlock voltage registers (0x2080 - 0x2098).
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
|
|
|
|
//
|
|
// Configure voltage level for the specified pump voltage of high
|
|
// voltage supply input during erase operation VHVCT_E and the TRIM13_E
|
|
// (FCFG1 offset 0x190 bits[3:0] and bits[11:8]).
|
|
//
|
|
ui32TempVal = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_VHV);
|
|
|
|
ui32Value = ((ui32TempVal & FACTORY_CFG_FLASH_VHV_TRIM13_E_M)>>
|
|
FACTORY_CFG_FLASH_VHV_TRIM13_E_S) << FLASH_FVHVCT1_TRIM13_E_S;
|
|
ui32Value |= ((ui32TempVal & FACTORY_CFG_FLASH_VHV_VHV_E_M)>>
|
|
FACTORY_CFG_FLASH_VHV_VHV_E_S) << FLASH_FVHVCT1_VHVCT_E_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FVHVCT1) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT1) &
|
|
~(FLASH_FVHVCT1_TRIM13_E_M | FLASH_FVHVCT1_VHVCT_E_M)) | ui32Value;
|
|
|
|
//
|
|
// Configure voltage level for the specified pump voltage of high voltage
|
|
// supply input during program verify operation VHVCT_PV and the TRIM13_PV
|
|
// (OTP offset 0x194 bits[19:16] and bits[27:24]).
|
|
//
|
|
ui32TempVal =
|
|
HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_VHV_PV);
|
|
|
|
ui32Value = ((ui32TempVal & FACTORY_CFG_FLASH_VHV_PV_TRIM13_PV_M)>>
|
|
FACTORY_CFG_FLASH_VHV_PV_TRIM13_PV_S) <<
|
|
FLASH_FVHVCT1_TRIM13_PV_S;
|
|
ui32Value |= ((ui32TempVal & FACTORY_CFG_FLASH_VHV_PV_VHV_PV_M)>>
|
|
FACTORY_CFG_FLASH_VHV_PV_VHV_PV_S) <<
|
|
FLASH_FVHVCT1_VHVCT_PV_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FVHVCT1) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT1) &
|
|
~(FLASH_FVHVCT1_TRIM13_PV_M | FLASH_FVHVCT1_VHVCT_PV_M)) | ui32Value;
|
|
|
|
//
|
|
// Configure voltage level for the specified pump voltage of high voltage
|
|
// supply input during program operation VHVCT_P and TRIM13_P
|
|
// (FCFG1 offset 0x190 bits[19:16] and bits[27:24]).
|
|
//
|
|
ui32TempVal =
|
|
HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_VHV);
|
|
|
|
ui32Value = ((ui32TempVal & FACTORY_CFG_FLASH_VHV_TRIM13_P_M)>>
|
|
FACTORY_CFG_FLASH_VHV_TRIM13_P_S) << FLASH_FVHVCT2_TRIM13_P_S;
|
|
ui32Value |= ((ui32TempVal & FACTORY_CFG_FLASH_VHV_VHV_P_M)>>
|
|
FACTORY_CFG_FLASH_VHV_VHV_P_S) << FLASH_FVHVCT2_VHVCT_P_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FVHVCT2) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FVHVCT2) &
|
|
~(FLASH_FVHVCT2_TRIM13_P_M | FLASH_FVHVCT2_VHVCT_P_M)) | ui32Value;
|
|
|
|
//
|
|
// Configure voltage level for the specified pump voltage of wordline power
|
|
// supply for read mode
|
|
// (FCFG1 offset 0x198 Bits 15:8).
|
|
//
|
|
ui32Value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_V) &
|
|
FACTORY_CFG_FLASH_V_V_READ_M) >>
|
|
FACTORY_CFG_FLASH_V_V_READ_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FVREADCT) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FVREADCT) &
|
|
~FLASH_FVREADCT_VREADCT_M) |
|
|
((ui32Value << FLASH_FVREADCT_VREADCT_S) &
|
|
FLASH_FVREADCT_VREADCT_M);
|
|
|
|
//
|
|
// Configure the voltage level for the VCG 2.5 CT pump voltage
|
|
// (FCFG1 offset 0x194 bits 15:8).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_VHV_PV) &
|
|
FACTORY_CFG_FLASH_VHV_PV_VCG2P5_M) >>
|
|
FACTORY_CFG_FLASH_VHV_PV_VCG2P5_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FVNVCT) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FVNVCT) &
|
|
~FLASH_FVNVCT_VCG2P5CT_M) |
|
|
((ui32Value << FLASH_FVNVCT_VCG2P5CT_S) &
|
|
FLASH_FVNVCT_VCG2P5CT_M);
|
|
|
|
//
|
|
// Configure the voltage level for the specified pump voltage of high
|
|
// current power input during program operation
|
|
// (FCFG1 offset 0x198 bits 31:24).
|
|
//
|
|
ui32Value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_V) &
|
|
FACTORY_CFG_FLASH_V_VSL_P_M) >>
|
|
FACTORY_CFG_FLASH_V_VSL_P_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FVSLP) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FVSLP) &
|
|
~FLASH_FVSLP_VSL_P_M) |
|
|
((ui32Value << FLASH_FVSLP_VSL_P_S) &
|
|
FLASH_FVSLP_VSL_P_M);
|
|
|
|
//
|
|
// Configure the voltage level for the specified pump voltage of wordline
|
|
// power supply during programming operations
|
|
// (OTP offset 0x198 bits 23:16).
|
|
//
|
|
ui32Value = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_V) &
|
|
FACTORY_CFG_FLASH_V_VWL_P_M) >>
|
|
FACTORY_CFG_FLASH_V_VWL_P_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FVWLCT) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FVWLCT) &
|
|
~FLASH_FVWLCT_VWLCT_P_M) |
|
|
((ui32Value << FLASH_FVWLCT_VWLCT_P_S) &
|
|
FLASH_FVWLCT_VWLCT_P_M);
|
|
|
|
//
|
|
// Configure the pump's TRIM_1P7 port pins.
|
|
// (FCFG1 offset 0x2B0 bits 17:16).
|
|
//
|
|
ui32Value =
|
|
(HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_OTP_DATA3) &
|
|
FACTORY_CFG_FLASH_OTP_DATA3_TRIM_1P7_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA3_TRIM_1P7_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
|
|
~FLASH_FSEQPMP_TRIM_1P7_M) |
|
|
((ui32Value << FLASH_FSEQPMP_TRIM_1P7_S) &
|
|
FLASH_FSEQPMP_TRIM_1P7_M);
|
|
|
|
//
|
|
// Lock the voltage registers.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
|
|
|
|
//
|
|
// Set trimmed flag.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 5;
|
|
HWREG(FLASH_BASE + FLASH_O_FWFLAG) |= FW_WRT_TRIMMED;
|
|
HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 0;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! \internal
|
|
//! Used to scale the TI OTP values based on the FClk scaling value.
|
|
//!
|
|
//! \param ui32SpecifiedTiming
|
|
//! \param ui32ScaleValue
|
|
//!
|
|
//! Used to scale the TI OTP values based on the FClk scaling value.
|
|
//!
|
|
//! \return Returns the scaled value
|
|
//
|
|
//*****************************************************************************
|
|
static uint32_t
|
|
ScaleCycleValues(uint32_t ui32SpecifiedTiming, uint32_t ui32ScaleValue)
|
|
{
|
|
return((ui32SpecifiedTiming * ui32ScaleValue) >> 6);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! \internal
|
|
//! Used to set flash in read mode.
|
|
//!
|
|
//! Flash is configured with values loaded from OTP dependent on the current
|
|
//! regulator mode.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
static void
|
|
SetReadMode(void)
|
|
{
|
|
uint32_t ui32TrimValue;
|
|
uint32_t ui32Value;
|
|
|
|
//
|
|
// Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
|
|
// VIN_AT_X and VIN_BY_PASS for read mode
|
|
//
|
|
if(HWREG(AON_SYSCTL_BASE + AON_SYSCTL_O_PWRCTL) &
|
|
AON_SYSCTL_PWRCTL_EXT_REG_MODE)
|
|
{
|
|
// Select trim values for external regulator mode:
|
|
// Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)
|
|
// COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 6:5)
|
|
// Must be done while the register bit field CONFIG.DIS_STANDBY = 1
|
|
HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
|
|
|
|
ui32TrimValue =
|
|
HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_OTP_DATA4);
|
|
|
|
ui32Value = ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<
|
|
FLASH_CFG_STANDBY_MODE_SEL_S;
|
|
|
|
ui32Value |= ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<
|
|
FLASH_CFG_STANDBY_PW_SEL_S;
|
|
|
|
// Configure DIS_STANDBY (OTP offset 0x308 bit 4).
|
|
// Configure DIS_IDLE (OTP offset 0x308 bit 3).
|
|
ui32Value |= ((ui32TrimValue &
|
|
(FACTORY_CFG_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |
|
|
FACTORY_CFG_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<
|
|
FLASH_CFG_DIS_IDLE_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
|
|
~(FLASH_CFG_STANDBY_MODE_SEL_M |
|
|
FLASH_CFG_STANDBY_PW_SEL_M |
|
|
FLASH_CFG_DIS_STANDBY_M |
|
|
FLASH_CFG_DIS_IDLE_M)) | ui32Value;
|
|
|
|
// Check if sample and hold functionality is disabled.
|
|
if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
|
|
{
|
|
//
|
|
// Wait for disabled sample and hold functionality to be stable.
|
|
//
|
|
while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
|
|
{
|
|
}
|
|
}
|
|
|
|
// Configure VIN_AT_X (OTP offset 0x308 bits 2:0)
|
|
ui32Value = ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<
|
|
FLASH_FSEQPMP_VIN_AT_X_S;
|
|
|
|
// Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
|
|
// If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
|
|
// VIN_BY_PASS should be 1
|
|
if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
|
|
FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
|
|
{
|
|
ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
|
|
}
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
|
|
HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
|
|
~(FLASH_FSEQPMP_VIN_BY_PASS_M |
|
|
FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
|
|
}
|
|
else
|
|
{
|
|
// Select trim values for internal regulator mode:
|
|
// Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)
|
|
// COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 14:13)
|
|
// Must be done while the register bit field CONFIG.DIS_STANDBY = 1
|
|
HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
|
|
|
|
ui32TrimValue =
|
|
HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_OTP_DATA4);
|
|
|
|
ui32Value = ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<
|
|
FLASH_CFG_STANDBY_MODE_SEL_S;
|
|
|
|
ui32Value |= ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<
|
|
FLASH_CFG_STANDBY_PW_SEL_S;
|
|
|
|
// Configure DIS_STANDBY (OTP offset 0x308 bit 12).
|
|
// Configure DIS_IDLE (OTP offset 0x308 bit 11).
|
|
ui32Value |= ((ui32TrimValue &
|
|
(FACTORY_CFG_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |
|
|
FACTORY_CFG_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<
|
|
FLASH_CFG_DIS_IDLE_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
|
|
~(FLASH_CFG_STANDBY_MODE_SEL_M |
|
|
FLASH_CFG_STANDBY_PW_SEL_M |
|
|
FLASH_CFG_DIS_STANDBY_M |
|
|
FLASH_CFG_DIS_IDLE_M)) | ui32Value;
|
|
|
|
// Check if sample and hold functionality is disabled.
|
|
if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
|
|
{
|
|
//
|
|
// Wait for disabled sample and hold functionality to be stable.
|
|
//
|
|
while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
|
|
{
|
|
}
|
|
}
|
|
|
|
// Configure VIN_AT_X (OTP offset 0x308 bits 10:8)
|
|
ui32Value = (((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<
|
|
FLASH_FSEQPMP_VIN_AT_X_S);
|
|
|
|
// Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
|
|
// If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
|
|
// VIN_BY_PASS should be 1
|
|
if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
|
|
FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
|
|
{
|
|
ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
|
|
}
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
|
|
HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
|
|
~(FLASH_FSEQPMP_VIN_BY_PASS_M |
|
|
FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! \internal
|
|
//! Used to set flash in write mode.
|
|
//!
|
|
//! Flash is configured with values loaded from OTP dependent on the current
|
|
//! regulator mode.
|
|
//!
|
|
//! \return None.
|
|
//
|
|
//*****************************************************************************
|
|
static void
|
|
SetWriteMode(void)
|
|
{
|
|
uint32_t ui32TrimValue;
|
|
uint32_t ui32Value;
|
|
|
|
//
|
|
// Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
|
|
// VIN_AT_X and VIN_BY_PASS for program/erase mode
|
|
//
|
|
if(HWREG(AON_SYSCTL_BASE + AON_SYSCTL_O_PWRCTL) &
|
|
AON_SYSCTL_PWRCTL_EXT_REG_MODE)
|
|
{
|
|
// Select trim values for external regulator mode:
|
|
// Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 23)
|
|
// COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 22:21)
|
|
// Must be done while the register bit field CONFIG.DIS_STANDBY = 1
|
|
HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
|
|
|
|
ui32TrimValue =
|
|
HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_OTP_DATA4);
|
|
|
|
ui32Value = ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_S) <<
|
|
FLASH_CFG_STANDBY_MODE_SEL_S;
|
|
|
|
ui32Value |= ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_S) <<
|
|
FLASH_CFG_STANDBY_PW_SEL_S;
|
|
|
|
// Configure DIS_STANDBY (OTP offset 0x308 bit 20).
|
|
// Configure DIS_IDLE (OTP offset 0x308 bit 19).
|
|
ui32Value |= ((ui32TrimValue &
|
|
(FACTORY_CFG_FLASH_OTP_DATA4_DIS_STANDBY_EXT_WRT_M |
|
|
FACTORY_CFG_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_M)) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_S) <<
|
|
FLASH_CFG_DIS_IDLE_S;
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
|
|
~(FLASH_CFG_STANDBY_MODE_SEL_M |
|
|
FLASH_CFG_STANDBY_PW_SEL_M |
|
|
FLASH_CFG_DIS_STANDBY_M |
|
|
FLASH_CFG_DIS_IDLE_M)) | ui32Value;
|
|
|
|
// Check if sample and hold functionality is disabled.
|
|
if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
|
|
{
|
|
//
|
|
// Wait for disabled sample and hold functionality to be stable.
|
|
//
|
|
while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
|
|
{
|
|
}
|
|
}
|
|
|
|
// Configure VIN_AT_X (OTP offset 0x308 bits 18:16)
|
|
ui32Value = ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_S) <<
|
|
FLASH_FSEQPMP_VIN_AT_X_S;
|
|
|
|
// Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
|
|
// If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
|
|
// VIN_BY_PASS should be 1
|
|
if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
|
|
FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
|
|
{
|
|
ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
|
|
}
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
|
|
HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
|
|
~(FLASH_FSEQPMP_VIN_BY_PASS_M |
|
|
FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
|
|
}
|
|
else
|
|
{
|
|
// Select trim values for internal regulator mode:
|
|
// Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 31)
|
|
// COnfigure STANDBY_PW_SEL (OTP offset 0x308 bit 30:29)
|
|
// Must be done while the register bit field CONFIG.DIS_STANDBY = 1
|
|
HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
|
|
|
|
ui32TrimValue =
|
|
HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FACTORY_CFG_O_FLASH_OTP_DATA4);
|
|
|
|
ui32Value = ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_S) <<
|
|
FLASH_CFG_STANDBY_MODE_SEL_S;
|
|
|
|
ui32Value |= ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_S) <<
|
|
FLASH_CFG_STANDBY_PW_SEL_S;
|
|
|
|
// Configure DIS_STANDBY (OTP offset 0x308 bit 28).
|
|
// Configure DIS_IDLE (OTP offset 0x308 bit 27).
|
|
ui32Value |= ((ui32TrimValue &
|
|
(FACTORY_CFG_FLASH_OTP_DATA4_DIS_STANDBY_INT_WRT_M |
|
|
FACTORY_CFG_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_M)) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_S) <<
|
|
FLASH_CFG_DIS_IDLE_S;
|
|
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
|
|
~(FLASH_CFG_STANDBY_MODE_SEL_M |
|
|
FLASH_CFG_STANDBY_PW_SEL_M |
|
|
FLASH_CFG_DIS_STANDBY_M |
|
|
FLASH_CFG_DIS_IDLE_M)) | ui32Value;
|
|
|
|
// Check if sample and hold functionality is disabled.
|
|
if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
|
|
{
|
|
//
|
|
// Wait for disabled sample and hold functionality to be stable.
|
|
//
|
|
while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
|
|
{
|
|
}
|
|
}
|
|
|
|
// Configure VIN_AT_X (OTP offset 0x308 bits 26:24)
|
|
ui32Value = ((ui32TrimValue &
|
|
FACTORY_CFG_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_M) >>
|
|
FACTORY_CFG_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_S) <<
|
|
FLASH_FSEQPMP_VIN_AT_X_S;
|
|
|
|
// Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
|
|
// If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
|
|
// VIN_BY_PASS should be 1
|
|
if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
|
|
FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
|
|
{
|
|
ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
|
|
}
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
|
|
HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
|
|
~(FLASH_FSEQPMP_VIN_BY_PASS_M |
|
|
FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set power mode
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
FlashPowerModeSet(uint32_t ui32PowerMode, uint32_t ui32BankGracePeriode,
|
|
uint32_t ui32PumpGracePeriode)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32PowerMode == FLASH_PWR_ACTIVE_MODE ||
|
|
ui32PowerMode == FLASH_PWR_OFF_MODE ||
|
|
ui32PowerMode == FLASH_PWR_DEEP_STDBY_MODE);
|
|
ASSERT(ui32BankGracePeriode <= 0xFF);
|
|
ASSERT(ui32PumpGracePeriode <= 0xFFFF);
|
|
|
|
switch(ui32PowerMode)
|
|
{
|
|
case FLASH_PWR_ACTIVE_MODE:
|
|
//
|
|
// Set bank power mode to ACTIVE.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &=
|
|
(~FLASH_FBFALLBACK_BANKPWR0_M | FBFALLBACK_ACTIVE);
|
|
|
|
//
|
|
// Set charge pump power mode to ACTIVE mode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FPAC1) |= 1 << FLASH_FPAC1_PUMPPWR_S;
|
|
break;
|
|
|
|
case FLASH_PWR_OFF_MODE:
|
|
//
|
|
// Set bank grace periode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBAC) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
|
|
((ui32BankGracePeriode << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
|
|
|
|
//
|
|
// Set pump grace periode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FPAC2) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
|
|
((ui32PumpGracePeriode << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
|
|
|
|
//
|
|
// Set bank power mode to SLEEP.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &=
|
|
(~FLASH_FBFALLBACK_BANKPWR0_M | FBFALLBACK_SLEEP);
|
|
|
|
//
|
|
// Set charge pump power mode to SLEEP mode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FPAC1) &= ~FLASH_FPAC1_PUMPPWR_M;
|
|
break;
|
|
|
|
case FLASH_PWR_DEEP_STDBY_MODE:
|
|
//
|
|
// Set bank grace periode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBAC) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
|
|
((ui32BankGracePeriode << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
|
|
|
|
//
|
|
// Set pump grace periode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FPAC2) =
|
|
(HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
|
|
((ui32PumpGracePeriode << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
|
|
|
|
//
|
|
// Set bank power mode to DEEP STANDBY mode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &=
|
|
(~FLASH_FBFALLBACK_BANKPWR0_M | FBFALLBACK_DEEP_STDBY);
|
|
|
|
//
|
|
// Set charge pump power mode to SLEEP mode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FPAC1) &= ~FLASH_FPAC1_PUMPPWR_M;
|
|
break;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get current configured power mode
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
FlashPowerModeGet(void)
|
|
{
|
|
uint32_t ui32PowerMode;
|
|
uint32_t ui32BankPwrMode;
|
|
|
|
ui32BankPwrMode = HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
|
|
FLASH_FBFALLBACK_BANKPWR0_M;
|
|
|
|
if(ui32BankPwrMode == FBFALLBACK_SLEEP)
|
|
{
|
|
ui32PowerMode = FLASH_PWR_OFF_MODE;
|
|
}
|
|
else if(ui32BankPwrMode == FBFALLBACK_DEEP_STDBY)
|
|
{
|
|
ui32PowerMode = FLASH_PWR_DEEP_STDBY_MODE;
|
|
}
|
|
else
|
|
{
|
|
ui32PowerMode = FLASH_PWR_ACTIVE_MODE;
|
|
}
|
|
|
|
//
|
|
// Return power mode.
|
|
//
|
|
return(ui32PowerMode);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set sector protection
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
FlashProtectionSet(uint32_t ui32SectorAddress, uint32_t ui32ProtectMode)
|
|
{
|
|
uint32_t ui32SectorNumber;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
|
|
FlashSectorSizeGet()));
|
|
ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
|
|
|
|
if(ui32ProtectMode == FLASH_WRITE_PROTECT)
|
|
{
|
|
ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) /
|
|
FlashSectorSizeGet();
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
|
|
if(ui32SectorNumber <= 31)
|
|
{
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) |= (1 << ui32SectorNumber);
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) |= (1 << ui32SectorNumber);
|
|
}
|
|
else if(ui32SectorNumber <= 63)
|
|
{
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) |=
|
|
(1 << (ui32SectorNumber & 0x1F));
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) |=
|
|
(1 << (ui32SectorNumber & 0x1F));
|
|
}
|
|
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get sector protection
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
FlashProtectionGet(uint32_t ui32SectorAddress)
|
|
{
|
|
uint32_t ui32SectorProtect;
|
|
uint32_t ui32SectorNumber;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
|
|
FlashSectorSizeGet()));
|
|
ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
|
|
|
|
ui32SectorProtect = FLASH_NO_PROTECT;
|
|
ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
|
|
|
|
if(ui32SectorNumber <= 31)
|
|
{
|
|
if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) & (1 << ui32SectorNumber)) &&
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) & (1 << ui32SectorNumber)))
|
|
{
|
|
ui32SectorProtect = FLASH_WRITE_PROTECT;
|
|
}
|
|
}
|
|
else if(ui32SectorNumber <= 63)
|
|
{
|
|
if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) &
|
|
(1 << (ui32SectorNumber & 0x1F))) &&
|
|
(HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) &
|
|
(1 << (ui32SectorNumber & 0x1F))))
|
|
{
|
|
ui32SectorProtect = FLASH_WRITE_PROTECT;
|
|
}
|
|
}
|
|
|
|
return(ui32SectorProtect);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Save sector protection to make it permanent
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
FlashProtectionSave(uint32_t ui32SectorAddress)
|
|
{
|
|
uint32_t ui32ErrorReturn;
|
|
uint32_t ui32SectorNumber;
|
|
uint32_t ui32CcfgSectorAddr;
|
|
uint8_t pui8ProgBuf[4];
|
|
|
|
ui32ErrorReturn = FAPI_STATUS_SUCCESS;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
|
|
FlashSectorSizeGet()));
|
|
ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
|
|
|
|
if(FlashProtectionGet(ui32SectorAddress) == FLASH_WRITE_PROTECT)
|
|
{
|
|
//
|
|
// Find sector number for specified sector.
|
|
//
|
|
ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
|
|
ui32CcfgSectorAddr = FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet();
|
|
|
|
//
|
|
// Adjust CCFG address to the 32-bit CCFG word holding the
|
|
// protect-bit for the specified sector.
|
|
//
|
|
ui32CcfgSectorAddr += (((ui32SectorNumber >> 5) * 4) + CCFG_OFFSET_SECT_PROT);
|
|
|
|
//
|
|
// Find value to program by setting the protect-bit which
|
|
// corresponds to specified sector number, to 0.
|
|
// Leave other protect-bits unchanged.
|
|
//
|
|
*(uint32_t *)pui8ProgBuf = (~(1 << (ui32SectorNumber & 0x1F))) &
|
|
*(uint32_t *)ui32CcfgSectorAddr;
|
|
|
|
ui32ErrorReturn = FlashProgram(pui8ProgBuf, ui32CcfgSectorAddr,
|
|
CCFG_SIZE_SECT_PROT);
|
|
}
|
|
|
|
//
|
|
// Return status.
|
|
//
|
|
return(ui32ErrorReturn);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Erase a flash sector
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
FlashSectorErase(uint32_t ui32SectorAddress)
|
|
{
|
|
uint32_t ui32ErrorReturn;
|
|
uint32_t ui32Error;
|
|
uint32_t ui32SectorBit;
|
|
uint32_t ui32SectorNumber;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
|
|
FlashSectorSizeGet()));
|
|
ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
|
|
|
|
//
|
|
// Enable all sectors for erase.
|
|
//
|
|
EnableSectorsForWrite();
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
if((ui32SectorAddress >
|
|
(FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet())) ||
|
|
((ui32SectorAddress & (FlashSectorSizeGet() - 1)) != 00))
|
|
{
|
|
//
|
|
// Invalid arguments. Exit function!
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
return (FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH);
|
|
}
|
|
|
|
//
|
|
// Clear the Status register.
|
|
//
|
|
IssueFsmCommand(FAPI_CLEAR_STATUS);
|
|
|
|
//
|
|
// Unprotect sector to be erased.
|
|
//
|
|
ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
|
|
ui32SectorBit = 1 << (ui32SectorNumber & 0x1F);
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
if(ui32SectorNumber < 0x20)
|
|
{
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = ~ui32SectorBit;
|
|
}
|
|
else
|
|
{
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = ~ui32SectorBit;
|
|
}
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
|
|
//
|
|
// Write the address to the FSM.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FADDR) = ui32SectorAddress + ADDR_OFFSET;
|
|
|
|
//
|
|
// Issue the sector erase command to the FSM.
|
|
//
|
|
IssueFsmCommand(FAPI_ERASE_SECTOR);
|
|
|
|
//
|
|
// Wait for erase to finish.
|
|
//
|
|
while(FlashCheckFsmForReady() == FAPI_STATUS_FSM_BUSY)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Update status.
|
|
//
|
|
ui32ErrorReturn = FlashCheckFsmForError();
|
|
|
|
//
|
|
// Disable sectors for erase.
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
|
|
//
|
|
// Check if flash top sector was erased.
|
|
//
|
|
if(ui32SectorAddress == (FLASHMEM_BASE + FlashSizeGet() -
|
|
FlashSectorSizeGet()))
|
|
{
|
|
//
|
|
// Program security data to default values in the customer configuration
|
|
// area within the flash top sector.
|
|
//
|
|
ui32Error = FlashProgram((uint8_t *)g_pui8CcfgDefaultSec,
|
|
(ui32SectorAddress + CCFG_OFFSET_SECURITY),
|
|
CCFG_SIZE_SECURITY);
|
|
|
|
if((ui32Error != FAPI_STATUS_SUCCESS) &&
|
|
(ui32ErrorReturn == FAPI_STATUS_SUCCESS))
|
|
{
|
|
ui32ErrorReturn = ui32Error;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Return status of operation.
|
|
//
|
|
return(ui32ErrorReturn);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Programs unprotected main bank flash sectors
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
FlashProgram(uint8_t *pui8DataBuffer, uint32_t ui32Address, uint32_t ui32Count)
|
|
{
|
|
uint32_t ui32StartIndex;
|
|
uint32_t ui32StopIndex;
|
|
uint32_t ui32Index;
|
|
uint8_t ui8BankWidth;
|
|
uint8_t ui8NoOfBytes;
|
|
tFwpWriteByte *oFwpWriteByte;
|
|
uint32_t ui32ErrorReturn;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Address + ui32Count) <= (FLASHMEM_BASE + FlashSizeGet()));
|
|
|
|
//
|
|
// Enable sectors for programming.
|
|
//
|
|
EnableSectorsForWrite();
|
|
oFwpWriteByte = FWPWRITE_BYTE_ADDRESS;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
if((ui32Address + ui32Count) > (FLASHMEM_BASE + FlashSizeGet()))
|
|
{
|
|
//
|
|
// Invalid arguments. Exit function!
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
return (FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH);
|
|
}
|
|
|
|
//
|
|
// Set the status to indicate success.
|
|
//
|
|
ui32ErrorReturn = FAPI_STATUS_SUCCESS;
|
|
|
|
//
|
|
// Find flash bank width in number of bytes.
|
|
//
|
|
ui8BankWidth =
|
|
(uint8_t)(((HWREG(FLASH_BASE + FLASH_O_FCFG_BANK) &
|
|
FLASH_FCFG_BANK_MAIN_BANK_WIDTH_M) >>
|
|
FLASH_FCFG_BANK_MAIN_BANK_WIDTH_S) >> 3);
|
|
|
|
//
|
|
// Loop over the bytes to be programmed.
|
|
//
|
|
while(ui32Count)
|
|
{
|
|
//
|
|
// Setup the start position within the write data registers.
|
|
//
|
|
ui32StartIndex = ui32Address & (uint32_t)(ui8BankWidth - 1);
|
|
|
|
//
|
|
// Setup number of bytes to program.
|
|
//
|
|
ui8NoOfBytes = ui8BankWidth - ui32StartIndex;
|
|
if(ui8NoOfBytes > ui32Count)
|
|
{
|
|
ui8NoOfBytes = ui32Count;
|
|
}
|
|
|
|
//
|
|
// Clear the Status register.
|
|
//
|
|
IssueFsmCommand(FAPI_CLEAR_STATUS);
|
|
|
|
//
|
|
// Write address to FADDR register.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FADDR) = ui32Address + ADDR_OFFSET;
|
|
|
|
//
|
|
// Setup the stop position within the write data registers.
|
|
//
|
|
ui32StopIndex = ui32StartIndex + (uint32_t)(ui8NoOfBytes - 1);
|
|
|
|
//
|
|
// Write each byte to the FWPWrite registers.
|
|
//
|
|
for(ui32Index = ui32StartIndex; ui32Index <= ui32StopIndex; ui32Index++)
|
|
{
|
|
oFwpWriteByte[ui32Index] = *(pui8DataBuffer++);
|
|
}
|
|
|
|
//
|
|
// Issue the Program command to the FSM.
|
|
//
|
|
IssueFsmCommand(FAPI_PROGRAM_DATA);
|
|
|
|
//
|
|
// Wait until the word has been programmed.
|
|
//
|
|
while(FlashCheckFsmForReady() == FAPI_STATUS_FSM_BUSY)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Exit if an access violation occurred.
|
|
//
|
|
ui32ErrorReturn = FlashCheckFsmForError();
|
|
if(ui32ErrorReturn != FAPI_STATUS_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Prepare for next data burst.
|
|
//
|
|
ui32Count -= ((ui32StopIndex - ui32StartIndex) + 1);
|
|
ui32Address += ((ui32StopIndex - ui32StartIndex) + 1);
|
|
}
|
|
|
|
//
|
|
// Disable sectors for programming.
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
|
|
//
|
|
// Return status of operation.
|
|
//
|
|
return(ui32ErrorReturn);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Starts programming within unprotected main bank flash sector and returns
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
FlashProgramNowait(uint32_t ui32StartAddress, uint8_t *pui8DataBuffer,
|
|
uint8_t ui8NoOfBytes)
|
|
{
|
|
uint32_t ui32StartIndex;
|
|
uint32_t ui32StopIndex;
|
|
uint32_t ui32Index;
|
|
uint32_t ui32BankWidth;
|
|
uint32_t ui32ErrorReturn;
|
|
tFwpWriteByte *oFwpWriteByte;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32StartAddress + ui8NoOfBytes) <= (FLASHMEM_BASE + FlashSizeGet()));
|
|
|
|
//
|
|
// Enable sectors for programming.
|
|
//
|
|
EnableSectorsForWrite();
|
|
oFwpWriteByte = FWPWRITE_BYTE_ADDRESS;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
if((ui32StartAddress + ui8NoOfBytes) > (FLASHMEM_BASE + FlashSizeGet()))
|
|
{
|
|
//
|
|
// Invalid arguments. Exit function!
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
return (FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH);
|
|
}
|
|
|
|
//
|
|
// Set status to indicate success
|
|
//
|
|
ui32ErrorReturn = FAPI_STATUS_SUCCESS;
|
|
|
|
//
|
|
// Find flash bank width in number of bytes.
|
|
//
|
|
ui32BankWidth = (((HWREG(FLASH_BASE + FLASH_O_FCFG_BANK) &
|
|
FLASH_FCFG_BANK_MAIN_BANK_WIDTH_M) >>
|
|
FLASH_FCFG_BANK_MAIN_BANK_WIDTH_S) >> 3);
|
|
|
|
//
|
|
// Setup the start position within the write data registers.
|
|
//
|
|
ui32StartIndex = ui32StartAddress & (ui32BankWidth - 1);
|
|
|
|
//
|
|
// Check to see if there is more data in the buffer than the register.
|
|
// width.
|
|
//
|
|
if((ui8NoOfBytes == 0) || ((ui32StartIndex + ui8NoOfBytes) > ui32BankWidth))
|
|
{
|
|
ui32ErrorReturn = FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH;
|
|
}
|
|
|
|
if(ui32ErrorReturn == FAPI_STATUS_SUCCESS)
|
|
{
|
|
//
|
|
// Clear the Status register.
|
|
//
|
|
IssueFsmCommand(FAPI_CLEAR_STATUS);
|
|
|
|
//
|
|
// Write address to FADDR register.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FADDR) = ui32StartAddress + ADDR_OFFSET;
|
|
|
|
//
|
|
// Setup the stop position within the write data registers.
|
|
//
|
|
ui32StopIndex = ui32StartIndex + (uint32_t)(ui8NoOfBytes - 1);
|
|
|
|
//
|
|
// Write each byte to the FWPWrite registers.
|
|
//
|
|
for(ui32Index = ui32StartIndex; ui32Index <= ui32StopIndex; ui32Index++)
|
|
{
|
|
oFwpWriteByte[ui32Index] = *(pui8DataBuffer++);
|
|
}
|
|
|
|
//
|
|
// Issue the Program command to the FSM.
|
|
//
|
|
IssueFsmCommand(FAPI_PROGRAM_DATA);
|
|
}
|
|
|
|
//
|
|
// Return the function status.
|
|
//
|
|
return(ui32ErrorReturn);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Reads efuse data from specified row
|
|
//
|
|
//*****************************************************************************
|
|
bool
|
|
FlashEfuseReadRow(uint32_t *pui32EfuseData, uint32_t ui32RowAddress)
|
|
{
|
|
bool bStatus;
|
|
|
|
//
|
|
// Make sure the clock for the efuse is enabled
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_CFG) &= ~FLASH_CFG_DIS_EFUSECLK;
|
|
|
|
//
|
|
// Set timing for EFUSE read operations.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_EFUSEREAD) |= ((5 << FLASH_EFUSEREAD_READCLOCK_S) &
|
|
FLASH_EFUSEREAD_READCLOCK_M);
|
|
|
|
//
|
|
// Clear status register.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) = 0;
|
|
|
|
//
|
|
// Select the FuseROM block 0.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_EFUSEADDR) = 0x00000000;
|
|
|
|
//
|
|
// Start the read operation.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_EFUSE) =
|
|
(DUMPWORD_INSTR << FLASH_EFUSE_INSTRUCTION_S) |
|
|
(ui32RowAddress & FLASH_EFUSE_DUMPWORD_M);
|
|
|
|
//
|
|
// Wait for operation to finish.
|
|
//
|
|
while(!(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_DONE))
|
|
{
|
|
}
|
|
|
|
//
|
|
// Check if error reported.
|
|
//
|
|
if(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_CODE_M)
|
|
{
|
|
//
|
|
// Set error status.
|
|
//
|
|
bStatus = 1;
|
|
|
|
//
|
|
// Clear data.
|
|
//
|
|
*pui32EfuseData = 0;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Set ok status.
|
|
//
|
|
bStatus = 0;
|
|
|
|
//
|
|
// No error. Get data from data register.
|
|
//
|
|
*pui32EfuseData = HWREG(FLASH_BASE + FLASH_O_DATALOWER);
|
|
}
|
|
|
|
//
|
|
// Disable the efuse clock to conserve power
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_EFUSECLK;
|
|
|
|
//
|
|
// Return the data.
|
|
//
|
|
return(bStatus);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Disables all sectors for erase and programming on the active bank
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
FlashDisableSectorsForWrite(void)
|
|
{
|
|
//
|
|
// Configure flash back to read mode
|
|
//
|
|
SetReadMode();
|
|
|
|
//
|
|
// Disable Level 1 Protection.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
|
|
|
|
//
|
|
// Disable all sectors for erase and programming.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;
|
|
|
|
//
|
|
// Enable Level 1 Protection.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
|
|
|
|
//
|
|
// Protect sectors from sector erase.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Erase all unprotected sectors in the flash main bank
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
FlashBankErase(bool bForcePrecondition)
|
|
{
|
|
uint32_t ui32ErrorReturn;
|
|
uint32_t ui32Error;
|
|
uint32_t ui32SectorAddress;
|
|
uint32_t ui32RegVal;
|
|
|
|
//
|
|
// Enable all sectors for erase.
|
|
//
|
|
EnableSectorsForWrite();
|
|
|
|
//
|
|
// Clear the Status register.
|
|
//
|
|
IssueFsmCommand(FAPI_CLEAR_STATUS);
|
|
|
|
//
|
|
// Enable erase of all sectors and enable precondition if required.
|
|
//
|
|
ui32RegVal = HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE);
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0x00000000;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0x00000000;
|
|
if(bForcePrecondition)
|
|
{
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=
|
|
FLASH_FSM_ST_MACHINE_DO_PRECOND;
|
|
}
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
|
|
//
|
|
// Issue the bank erase command to the FSM.
|
|
//
|
|
IssueFsmCommand(FAPI_ERASE_BANK);
|
|
|
|
//
|
|
// Wait for erase to finish.
|
|
//
|
|
while(FlashCheckFsmForReady() == FAPI_STATUS_FSM_BUSY)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Update status.
|
|
//
|
|
ui32ErrorReturn = FlashCheckFsmForError();
|
|
|
|
//
|
|
// Disable sectors for erase.
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
|
|
//
|
|
// Set configured precondition mode since it may have been forced on.
|
|
//
|
|
if(!(ui32RegVal & FLASH_FSM_ST_MACHINE_DO_PRECOND))
|
|
{
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &=
|
|
~FLASH_FSM_ST_MACHINE_DO_PRECOND;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
}
|
|
|
|
//
|
|
// Program security data to default values in the customer configuration
|
|
// area within the flash top sector.
|
|
//
|
|
ui32SectorAddress = FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet();
|
|
ui32Error = FlashProgram((uint8_t *)g_pui8CcfgDefaultSec,
|
|
(ui32SectorAddress + CCFG_OFFSET_SECURITY),
|
|
CCFG_SIZE_SECURITY);
|
|
|
|
if((ui32Error != FAPI_STATUS_SUCCESS) &&
|
|
(ui32ErrorReturn == FAPI_STATUS_SUCCESS))
|
|
{
|
|
ui32ErrorReturn = ui32Error;
|
|
}
|
|
|
|
//
|
|
// Return status of operation.
|
|
//
|
|
return(ui32ErrorReturn);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Erase flash OTP/ENGR areas.
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
FlashhOtpEngrErase(void)
|
|
{
|
|
uint32_t ui32ErrorReturn;
|
|
uint32_t ui32RegVal;
|
|
|
|
//
|
|
// Enable all sectors for erase.
|
|
//
|
|
EnableSectorsForWrite();
|
|
|
|
//
|
|
// Clear the Status register.
|
|
//
|
|
IssueFsmCommand(FAPI_CLEAR_STATUS);
|
|
|
|
//
|
|
// Disable OTP protection.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBAC) |= FLASH_FBAC_OTPPROTDIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
|
|
|
|
//
|
|
// Enable test commands.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
|
|
HWREG(FLASH_BASE + FLASH_O_FTCTL) |= FLASH_FTCTL_TEST_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
|
|
|
|
//
|
|
// Set address to OTP.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FADDR) = 0xF0000000;
|
|
|
|
//
|
|
// Enable for FSM test commands and erase precondition.
|
|
//
|
|
ui32RegVal = HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE);
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=
|
|
(FLASH_FSM_ST_MACHINE_CMD_EN | FLASH_FSM_ST_MACHINE_DO_PRECOND);
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
|
|
//
|
|
// Issue the erase command to the FSM.
|
|
//
|
|
IssueFsmCommand(FAPI_ERASE_OTP);
|
|
|
|
//
|
|
// Wait for erase to finish.
|
|
//
|
|
while(FlashCheckFsmForReady() == FAPI_STATUS_FSM_BUSY)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Update status.
|
|
//
|
|
ui32ErrorReturn = FlashCheckFsmForError();
|
|
|
|
//
|
|
// Disable sectors for erase.
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
|
|
//
|
|
// Disable test commands.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
|
|
HWREG(FLASH_BASE + FLASH_O_FTCTL) &= ~FLASH_FTCTL_TEST_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
|
|
|
|
//
|
|
// Renable OTP protection.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBAC) &= ~FLASH_FBAC_OTPPROTDIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
|
|
|
|
//
|
|
// Disable FSM test command mode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &= ~FLASH_FSM_ST_MACHINE_CMD_EN;
|
|
|
|
//
|
|
// Set configured precondition mode since it may have been changed.
|
|
//
|
|
if(!(ui32RegVal & FLASH_FSM_ST_MACHINE_DO_PRECOND))
|
|
{
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &=
|
|
~FLASH_FSM_ST_MACHINE_DO_PRECOND;
|
|
}
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
|
|
//
|
|
// Return status of operation.
|
|
//
|
|
return(ui32ErrorReturn);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Programs a data pattern in a main bank flash sector.
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
FlashProgramPattern(uint32_t ui32SectorAddress, uint32_t ui32DataPattern,
|
|
bool bInvertData)
|
|
{
|
|
uint8_t ui8Index;
|
|
uint8_t ui8BankWidth;
|
|
tFwpWriteByte *oFwpWriteByte;
|
|
uint32_t ui32ErrorReturn;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
|
|
FlashSectorSizeGet()));
|
|
ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
|
|
|
|
//
|
|
// Enable sectors for programming.
|
|
//
|
|
EnableSectorsForWrite();
|
|
oFwpWriteByte = FWPWRITE_BYTE_ADDRESS;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
if((ui32SectorAddress >
|
|
(FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet())) ||
|
|
((ui32SectorAddress & (FlashSectorSizeGet() - 1)) != 00))
|
|
{
|
|
//
|
|
// Invalid arguments. Exit function!
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
return (FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH);
|
|
}
|
|
|
|
//
|
|
// Find flash bank width in number of bytes.
|
|
//
|
|
ui8BankWidth =
|
|
(uint8_t)(((HWREG(FLASH_BASE + FLASH_O_FCFG_BANK) &
|
|
FLASH_FCFG_BANK_MAIN_BANK_WIDTH_M) >>
|
|
FLASH_FCFG_BANK_MAIN_BANK_WIDTH_S) >> 3);
|
|
|
|
//
|
|
// Clear the Status register.
|
|
//
|
|
IssueFsmCommand(FAPI_CLEAR_STATUS);
|
|
|
|
//
|
|
// Write address to FADDR register.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FADDR) = ui32SectorAddress + ADDR_OFFSET;
|
|
|
|
//
|
|
// Write each byte of the pattern to the FWPWrite registers.
|
|
//
|
|
for(ui8Index = 0; ui8Index < ui8BankWidth; ui8Index++)
|
|
{
|
|
oFwpWriteByte[ui8Index] = ui32DataPattern >> ((ui8Index * 8) &
|
|
(PATTERN_BITS - 1));
|
|
}
|
|
|
|
//
|
|
// Enable for FSM test command and enable the Invert Data option if
|
|
// required.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |= FLASH_FSM_ST_MACHINE_CMD_EN;
|
|
if(bInvertData)
|
|
{
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |= FLASH_FSM_ST_MACHINE_INV_DATA;
|
|
}
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
|
|
//
|
|
// Issue the Program command to the FSM.
|
|
//
|
|
IssueFsmCommand(FAPI_PROGRAM_SECTOR);
|
|
|
|
//
|
|
// Wait until the sector has been programmed.
|
|
//
|
|
while(FlashCheckFsmForReady() == FAPI_STATUS_FSM_BUSY)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Update status of the program operation.
|
|
//
|
|
ui32ErrorReturn = FlashCheckFsmForError();
|
|
|
|
//
|
|
// Disable sectors for programming.
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
|
|
//
|
|
// Disable FSM test command mode and the Invert Data option.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &= ~FLASH_FSM_ST_MACHINE_CMD_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &= ~FLASH_FSM_ST_MACHINE_INV_DATA;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
|
|
//
|
|
// Return status of operation.
|
|
//
|
|
return(ui32ErrorReturn);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Programs flash ENGR area
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
FlashProgramEngr(uint8_t *pui8DataBuffer, uint32_t ui32AddressOffset,
|
|
uint32_t ui32Count)
|
|
{
|
|
uint32_t ui32StartIndex;
|
|
uint32_t ui32StopIndex;
|
|
uint32_t ui32Index;
|
|
uint8_t ui8BankWidth;
|
|
uint8_t ui8NoOfBytes;
|
|
tFwpWriteByte *oFwpWriteByte;
|
|
uint32_t ui32ErrorReturn;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32AddressOffset + ui32Count) <= 1024);
|
|
|
|
//
|
|
// Enable sectors for programming.
|
|
//
|
|
EnableSectorsForWrite();
|
|
oFwpWriteByte = FWPWRITE_BYTE_ADDRESS;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
if((ui32AddressOffset + ui32Count) > 1024)
|
|
{
|
|
//
|
|
// Invalid arguments. Exit function!
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
return (FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH);
|
|
}
|
|
|
|
//
|
|
// Set the status to indicate success.
|
|
//
|
|
ui32ErrorReturn = FAPI_STATUS_SUCCESS;
|
|
|
|
//
|
|
// Find flash bank width in number of bytes.
|
|
//
|
|
ui8BankWidth =
|
|
(uint8_t)(((HWREG(FLASH_BASE + FLASH_O_FCFG_BANK) &
|
|
FLASH_FCFG_BANK_MAIN_BANK_WIDTH_M) >>
|
|
FLASH_FCFG_BANK_MAIN_BANK_WIDTH_S) >> 3);
|
|
|
|
//
|
|
// Disable OTP protection.
|
|
//
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBAC) |= FLASH_FBAC_OTPPROTDIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
|
|
|
|
//
|
|
// Enable test commands.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
|
|
HWREG(FLASH_BASE + FLASH_O_FTCTL) |= FLASH_FTCTL_TEST_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
|
|
|
|
//
|
|
// Enable for FSM test command.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |= FLASH_FSM_ST_MACHINE_CMD_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
|
|
//
|
|
// Loop over the bytes to be programmed.
|
|
//
|
|
while(ui32Count)
|
|
{
|
|
//
|
|
// Setup the start position within the write data registers.
|
|
//
|
|
ui32StartIndex = ui32AddressOffset & (uint32_t)(ui8BankWidth - 1);
|
|
|
|
//
|
|
// Setup number of bytes to program.
|
|
//
|
|
ui8NoOfBytes = ui8BankWidth - ui32StartIndex;
|
|
if(ui8NoOfBytes > ui32Count)
|
|
{
|
|
ui8NoOfBytes = ui32Count;
|
|
}
|
|
|
|
//
|
|
// Clear the Status register.
|
|
//
|
|
IssueFsmCommand(FAPI_CLEAR_STATUS);
|
|
|
|
//
|
|
// Write address to FADDR register.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FADDR) = ui32AddressOffset + 0xF0080000;
|
|
|
|
//
|
|
// Setup the stop position within the write data registers.
|
|
//
|
|
ui32StopIndex = ui32StartIndex + (uint32_t)(ui8NoOfBytes - 1);
|
|
|
|
//
|
|
// Write each byte to the FWPWrite registers.
|
|
//
|
|
for(ui32Index = ui32StartIndex; ui32Index <= ui32StopIndex; ui32Index++)
|
|
{
|
|
oFwpWriteByte[ui32Index] = *(pui8DataBuffer++);
|
|
}
|
|
|
|
//
|
|
// Issue programming command.
|
|
//
|
|
IssueFsmCommand(FAPI_PROGRAM_DATA);
|
|
|
|
//
|
|
// Wait until the word has been programmed.
|
|
//
|
|
while(FlashCheckFsmForReady() == FAPI_STATUS_FSM_BUSY)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Update error status and exit if an error occurred.
|
|
//
|
|
ui32ErrorReturn = FlashCheckFsmForError();
|
|
if(ui32ErrorReturn != FAPI_STATUS_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Prepare for next data burst.
|
|
//
|
|
ui32Count -= ((ui32StopIndex - ui32StartIndex) + 1);
|
|
ui32AddressOffset += ((ui32StopIndex - ui32StartIndex) + 1);
|
|
}
|
|
|
|
//
|
|
// Disable sectors for programming.
|
|
//
|
|
FlashDisableSectorsForWrite();
|
|
|
|
//
|
|
// Reenable OTP protection.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBAC) &= ~FLASH_FBAC_OTPPROTDIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
|
|
|
|
//
|
|
// Disable test commands.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
|
|
HWREG(FLASH_BASE + FLASH_O_FTCTL) &= ~FLASH_FTCTL_TEST_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
|
|
|
|
//
|
|
// Disable FSM test command mode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &= ~FLASH_FSM_ST_MACHINE_CMD_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
|
|
//
|
|
// Return status of operation.
|
|
//
|
|
return(ui32ErrorReturn);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! FlashOtpProgramEraseSetup prepares program and erase of the OTP/ENGR
|
|
//! sector.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
FlashOtpProgramEraseSetup(void)
|
|
{
|
|
//
|
|
// Disable OTP protection.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBAC) |= FLASH_FBAC_OTPPROTDIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
|
|
|
|
//
|
|
// Enable test commands by performing the following steps:
|
|
// - Enable SW Interface mode
|
|
// - Enable for test commands
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x0000AAAA;
|
|
HWREG(FLASH_BASE + FLASH_O_FTCTL) |= FLASH_FTCTL_TEST_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x000055AA;
|
|
|
|
//
|
|
// Enable for FSM test commands.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |= FLASH_FSM_ST_MACHINE_CMD_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! FlashOtpProgramEraseCleanup restores to default program and erase
|
|
//! protection.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
FlashOtpProgramEraseCleanup(void)
|
|
{
|
|
//
|
|
// Reenable OTP protection.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBAC) &= ~FLASH_FBAC_OTPPROTDIS;
|
|
HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
|
|
|
|
//
|
|
// Disable test commands and turn off SW interface mode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x0000AAAA;
|
|
HWREG(FLASH_BASE + FLASH_O_FTCTL) &= ~FLASH_FTCTL_TEST_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
|
|
|
|
//
|
|
// Disable FSM test command mode.
|
|
//
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &= ~FLASH_FSM_ST_MACHINE_CMD_EN;
|
|
HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
|
|
}
|
|
//! @}
|
|
//! \\addtogroup i2c_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Initializes the I2C Master block
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk,
|
|
bool bFast)
|
|
{
|
|
uint32_t ui32SCLFreq;
|
|
uint32_t ui32TPR;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(I2CBaseValid(ui32Base));
|
|
|
|
//
|
|
// Must enable the device before doing anything else.
|
|
//
|
|
I2CMasterEnable(ui32Base);
|
|
|
|
//
|
|
// Get the desired SCL speed.
|
|
//
|
|
if(bFast == true)
|
|
{
|
|
ui32SCLFreq = 400000;
|
|
}
|
|
else
|
|
{
|
|
ui32SCLFreq = 100000;
|
|
}
|
|
|
|
//
|
|
// Compute the clock divider that achieves the fastest speed less than or
|
|
// equal to the desired speed. The numerator is biased to favor a larger
|
|
// clock divider so that the resulting clock is always less than or equal
|
|
// to the desired clock, never greater.
|
|
//
|
|
ui32TPR = ((ui32I2CClk + (2 * 10 * ui32SCLFreq) - 1) / (2 * 10 * ui32SCLFreq)) - 1;
|
|
HWREG(ui32Base + I2C_O_MTPR) = ui32TPR;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets the error status of the I2C Master module
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
I2CMasterErr(uint32_t ui32Base)
|
|
{
|
|
uint32_t ui32Err;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(I2CBaseValid(ui32Base));
|
|
|
|
//
|
|
// Get the raw error state.
|
|
//
|
|
ui32Err = HWREG(ui32Base + I2C_O_MSTAT);
|
|
|
|
//
|
|
// If the I2C master is busy, then all the other status bits are invalid,
|
|
// and there is no error to report.
|
|
//
|
|
if(ui32Err & I2C_MSTAT_BUSY)
|
|
{
|
|
return(I2C_MASTER_ERR_NONE);
|
|
}
|
|
|
|
//
|
|
// Check for errors.
|
|
//
|
|
if(ui32Err & (I2C_MSTAT_ERR | I2C_MSTAT_ARBLST))
|
|
{
|
|
return(ui32Err & (I2C_MSTAT_ARBLST | I2C_MSTAT_DATACK | I2C_MSTAT_ADRACK));
|
|
}
|
|
else
|
|
{
|
|
return(I2C_MASTER_ERR_NONE);
|
|
}
|
|
}
|
|
//! @}
|
|
//! \\addtogroup interrupt_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! This is a mapping between priority grouping encodings and the number of
|
|
//! preemption priority bits.
|
|
//
|
|
//*****************************************************************************
|
|
static const uint32_t g_pui32Priority[] =
|
|
{
|
|
NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6,
|
|
NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4, NVIC_APINT_PRIGROUP_5_3,
|
|
NVIC_APINT_PRIGROUP_6_2, NVIC_APINT_PRIGROUP_7_1
|
|
};
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! This is a mapping between interrupt number and the register that contains
|
|
//! the priority encoding for that interrupt.
|
|
//
|
|
//*****************************************************************************
|
|
static const uint32_t g_pui32Regs[] =
|
|
{
|
|
0, NVIC_SYS_PRI1, NVIC_SYS_PRI2, NVIC_SYS_PRI3, NVIC_PRI0, NVIC_PRI1,
|
|
NVIC_PRI2, NVIC_PRI3, NVIC_PRI4, NVIC_PRI5, NVIC_PRI6, NVIC_PRI7,
|
|
NVIC_PRI8, NVIC_PRI9, NVIC_PRI10, NVIC_PRI11, NVIC_PRI12, NVIC_PRI13
|
|
};
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the priority grouping of the interrupt controller.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IntPriorityGroupingSet(uint32_t ui32Bits)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32Bits < NUM_PRIORITY);
|
|
|
|
//
|
|
// Set the priority grouping.
|
|
//
|
|
HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | g_pui32Priority[ui32Bits];
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets the priority grouping of the interrupt controller
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
IntPriorityGroupingGet(void)
|
|
{
|
|
uint32_t ui32Loop, ui32Value;
|
|
|
|
//
|
|
// Read the priority grouping.
|
|
//
|
|
ui32Value = HWREG(NVIC_APINT) & NVIC_APINT_PRIGROUP_M;
|
|
|
|
//
|
|
// Loop through the priority grouping values.
|
|
//
|
|
for(ui32Loop = 0; ui32Loop < NUM_PRIORITY; ui32Loop++)
|
|
{
|
|
//
|
|
// Stop looping if this value matches.
|
|
//
|
|
if(ui32Value == g_pui32Priority[ui32Loop])
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Return the number of priority bits.
|
|
//
|
|
return(ui32Loop);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the priority of an interrupt
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IntPrioritySet(uint32_t ui32Interrupt, uint8_t ui8Priority)
|
|
{
|
|
uint32_t ui32Temp;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS));
|
|
ASSERT(ui8Priority <= INT_PRI_LEVEL7);
|
|
|
|
//
|
|
// Set the interrupt priority.
|
|
//
|
|
ui32Temp = HWREG(g_pui32Regs[ui32Interrupt >> 2]);
|
|
ui32Temp &= ~(0xFF << (8 * (ui32Interrupt & 3)));
|
|
ui32Temp |= ui8Priority << (8 * (ui32Interrupt & 3));
|
|
HWREG(g_pui32Regs[ui32Interrupt >> 2]) = ui32Temp;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets the priority of an interrupt
|
|
//
|
|
//*****************************************************************************
|
|
int32_t
|
|
IntPriorityGet(uint32_t ui32Interrupt)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS));
|
|
|
|
//
|
|
// Return the interrupt priority.
|
|
//
|
|
return((HWREG(g_pui32Regs[ui32Interrupt >> 2]) >> (8 * (ui32Interrupt & 3))) &
|
|
0xFF);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Enables an interrupt
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IntEnable(uint32_t ui32Interrupt)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32Interrupt < NUM_INTERRUPTS);
|
|
|
|
//
|
|
// Determine the interrupt to enable.
|
|
//
|
|
if(ui32Interrupt == FAULT_MPU)
|
|
{
|
|
//
|
|
// Enable the MemManage interrupt.
|
|
//
|
|
HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_MEM;
|
|
}
|
|
else if(ui32Interrupt == FAULT_BUS)
|
|
{
|
|
//
|
|
// Enable the bus fault interrupt.
|
|
//
|
|
HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_BUS;
|
|
}
|
|
else if(ui32Interrupt == FAULT_USAGE)
|
|
{
|
|
//
|
|
// Enable the usage fault interrupt.
|
|
//
|
|
HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_USAGE;
|
|
}
|
|
else if(ui32Interrupt == FAULT_SYSTICK)
|
|
{
|
|
//
|
|
// Enable the System Tick interrupt.
|
|
//
|
|
HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN;
|
|
}
|
|
else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
|
|
{
|
|
//
|
|
// Enable the general interrupt.
|
|
//
|
|
HWREG(NVIC_EN0) = 1 << (ui32Interrupt - 16);
|
|
}
|
|
else if(ui32Interrupt >= 48)
|
|
{
|
|
//
|
|
// Enable the general interrupt.
|
|
//
|
|
HWREG(NVIC_EN1) = 1 << (ui32Interrupt - 48);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Disables an interrupt
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IntDisable(uint32_t ui32Interrupt)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32Interrupt < NUM_INTERRUPTS);
|
|
|
|
//
|
|
// Determine the interrupt to disable.
|
|
//
|
|
if(ui32Interrupt == FAULT_MPU)
|
|
{
|
|
//
|
|
// Disable the MemManage interrupt.
|
|
//
|
|
HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_MEM);
|
|
}
|
|
else if(ui32Interrupt == FAULT_BUS)
|
|
{
|
|
//
|
|
// Disable the bus fault interrupt.
|
|
//
|
|
HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_BUS);
|
|
}
|
|
else if(ui32Interrupt == FAULT_USAGE)
|
|
{
|
|
//
|
|
// Disable the usage fault interrupt.
|
|
//
|
|
HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_USAGE);
|
|
}
|
|
else if(ui32Interrupt == FAULT_SYSTICK)
|
|
{
|
|
//
|
|
// Disable the System Tick interrupt.
|
|
//
|
|
HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN);
|
|
}
|
|
else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
|
|
{
|
|
//
|
|
// Disable the general interrupt.
|
|
//
|
|
HWREG(NVIC_DIS0) = 1 << (ui32Interrupt - 16);
|
|
}
|
|
else if(ui32Interrupt >= 48)
|
|
{
|
|
//
|
|
// Disable the general interrupt.
|
|
//
|
|
HWREG(NVIC_DIS1) = 1 << (ui32Interrupt - 48);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Pends an interrupt
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IntPendSet(uint32_t ui32Interrupt)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32Interrupt < NUM_INTERRUPTS);
|
|
|
|
//
|
|
// Determine the interrupt to pend.
|
|
//
|
|
if(ui32Interrupt == FAULT_NMI)
|
|
{
|
|
//
|
|
// Pend the NMI interrupt.
|
|
//
|
|
HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_NMI_SET;
|
|
}
|
|
else if(ui32Interrupt == FAULT_PENDSV)
|
|
{
|
|
//
|
|
// Pend the PendSV interrupt.
|
|
//
|
|
HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PEND_SV;
|
|
}
|
|
else if(ui32Interrupt == FAULT_SYSTICK)
|
|
{
|
|
//
|
|
// Pend the SysTick interrupt.
|
|
//
|
|
HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTSET;
|
|
}
|
|
else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
|
|
{
|
|
//
|
|
// Pend the general interrupt.
|
|
//
|
|
HWREG(NVIC_PEND0) = 1 << (ui32Interrupt - 16);
|
|
}
|
|
else if(ui32Interrupt >= 48)
|
|
{
|
|
//
|
|
// Pend the general interrupt.
|
|
//
|
|
HWREG(NVIC_PEND1) = 1 << (ui32Interrupt - 48);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Query whether an interrupt is pending
|
|
//
|
|
//*****************************************************************************
|
|
bool
|
|
IntPendGet(uint32_t ui32Interrupt)
|
|
{
|
|
uint32_t ui32IntPending;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32Interrupt < NUM_INTERRUPTS);
|
|
|
|
//
|
|
// Assume no interrupts are pending.
|
|
//
|
|
ui32IntPending = 0;
|
|
|
|
//
|
|
// The lower 16 IRQ vectors are unsupported by this function
|
|
//
|
|
if (ui32Interrupt < 16)
|
|
{
|
|
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Subtract lower 16 irq vectors
|
|
//
|
|
ui32Interrupt -= 16;
|
|
|
|
//
|
|
// Check if the interrupt is pending
|
|
//
|
|
ui32IntPending = HWREG(NVIC_PEND0 + (ui32Interrupt / 32));
|
|
ui32IntPending &= (1 << (ui32Interrupt & 31));
|
|
|
|
return ui32IntPending ? true : false;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Unpends an interrupt
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IntPendClear(uint32_t ui32Interrupt)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32Interrupt < NUM_INTERRUPTS);
|
|
|
|
//
|
|
// Determine the interrupt to unpend.
|
|
//
|
|
if(ui32Interrupt == FAULT_PENDSV)
|
|
{
|
|
//
|
|
// Unpend the PendSV interrupt.
|
|
//
|
|
HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_UNPEND_SV;
|
|
}
|
|
else if(ui32Interrupt == FAULT_SYSTICK)
|
|
{
|
|
//
|
|
// Unpend the SysTick interrupt.
|
|
//
|
|
HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTCLR;
|
|
}
|
|
else if((ui32Interrupt >= 16) && (ui32Interrupt <= 47))
|
|
{
|
|
//
|
|
// Unpend the general interrupt.
|
|
//
|
|
HWREG(NVIC_UNPEND0) = 1 << (ui32Interrupt - 16);
|
|
}
|
|
else if(ui32Interrupt >= 48)
|
|
{
|
|
//
|
|
// Unpend the general interrupt.
|
|
//
|
|
HWREG(NVIC_UNPEND1) = 1 << (ui32Interrupt - 48);
|
|
}
|
|
}
|
|
//! @}
|
|
//! \\addtogroup ioc_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
// This is the mapping between an IO and the corresponding configuration
|
|
// register.
|
|
//
|
|
//*****************************************************************************
|
|
static const uint32_t g_pui32IOCfgReg[] =
|
|
{
|
|
IOC_O_IOCFG0, IOC_O_IOCFG1, IOC_O_IOCFG2, IOC_O_IOCFG3, IOC_O_IOCFG4,
|
|
IOC_O_IOCFG5, IOC_O_IOCFG6, IOC_O_IOCFG7, IOC_O_IOCFG8, IOC_O_IOCFG9,
|
|
IOC_O_IOCFG10, IOC_O_IOCFG11, IOC_O_IOCFG12, IOC_O_IOCFG13, IOC_O_IOCFG14,
|
|
IOC_O_IOCFG15, IOC_O_IOCFG16, IOC_O_IOCFG17, IOC_O_IOCFG18, IOC_O_IOCFG19,
|
|
IOC_O_IOCFG20, IOC_O_IOCFG21, IOC_O_IOCFG22, IOC_O_IOCFG23, IOC_O_IOCFG24,
|
|
IOC_O_IOCFG25, IOC_O_IOCFG26, IOC_O_IOCFG27, IOC_O_IOCFG28, IOC_O_IOCFG29,
|
|
IOC_O_IOCFG30, IOC_O_IOCFG31
|
|
};
|
|
//*****************************************************************************
|
|
//
|
|
//! Set the configuration of an IO port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCPortConfigureSet(uint32_t ui32IOId, uint32_t ui32PortId,
|
|
uint32_t ui32IOConfig)
|
|
{
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT(ui32PortId <= IOC_PORT_RFC_SMI_CL_IN);
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32Reg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the port.
|
|
//
|
|
HWREG(ui32Reg) = ui32IOConfig | ui32PortId;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get the configuration of an IO port
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
IOCPortConfigureGet(uint32_t ui32IOId)
|
|
{
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32Reg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Return the IO configuration.
|
|
//
|
|
return HWREG(ui32Reg);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set wake-up on an IO port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIOShutdownSet(uint32_t ui32IOId, uint32_t ui32IOShutdown)
|
|
{
|
|
uint32_t ui32Reg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT((ui32IOShutdown == IOC_NO_WAKE_UP) ||
|
|
(ui32IOShutdown == IOC_WAKE_ON_LOW) ||
|
|
(ui32IOShutdown == IOC_WAKE_ON_HIGH));
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32Reg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the IO.
|
|
//
|
|
ui32Config = HWREG(ui32Reg);
|
|
ui32Config &= ~IOC_IOCFG0_WU_CFG_M;
|
|
HWREG(ui32Reg) = ui32Config | ui32IOShutdown;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set wake-up on an IO port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIOJTagSet(uint32_t ui32IOId, uint32_t ui32IOJTag)
|
|
{
|
|
uint32_t ui32Reg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT((ui32IOJTag == IOC_JTAG_TDO_ENABLE) ||
|
|
(ui32IOJTag == IOC_JTAG_TDI_ENABLE) ||
|
|
(ui32IOJTag == IOC_JTAG_DISABLE));
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32Reg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the IO.
|
|
//
|
|
ui32Config = HWREG(ui32Reg);
|
|
ui32Config &= ~(IOC_IOCFG0_TDI | IOC_IOCFG0_TDO);
|
|
HWREG(ui32Reg) = ui32Config | ui32IOJTag;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set the IO Mode of an IO Port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIOModeSet(uint32_t ui32IOId, uint32_t ui32IOMode)
|
|
{
|
|
uint32_t ui32Reg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT((ui32IOMode == IOC_IOMODE_NORMAL) ||
|
|
(ui32IOMode == IOC_IOMODE_INV) ||
|
|
(ui32IOMode == IOC_IOMODE_OPEN_DRAIN_NORMAL) ||
|
|
(ui32IOMode == IOC_IOMODE_OPEN_DRAIN_INV) ||
|
|
(ui32IOMode == IOC_IOMODE_OPEN_SRC_NORMAL) ||
|
|
(ui32IOMode == IOC_IOMODE_OPEN_SRC_INV));
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32Reg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the IO.
|
|
//
|
|
ui32Config = HWREG(ui32Reg);
|
|
ui32Config &= ~IOC_IOCFG0_IOMODE_M;
|
|
HWREG(ui32Reg) = ui32Config | ui32IOMode;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Setup interrupt detection on an IO Port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIOIntSet(uint32_t ui32IOId, uint32_t ui32Int, uint32_t ui32EdgeDet)
|
|
{
|
|
uint32_t ui32IOReg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT((ui32Int == IOC_INT_ENABLE) ||
|
|
(ui32Int == IOC_INT_DISABLE));
|
|
ASSERT((ui32EdgeDet == IOC_NO_EDGE) ||
|
|
(ui32EdgeDet == IOC_FALLING_EDGE) ||
|
|
(ui32EdgeDet == IOC_RISING_EDGE) ||
|
|
(ui32EdgeDet == IOC_BOTH_EDGES));
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32IOReg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the IO.
|
|
//
|
|
ui32Config = HWREG(ui32IOReg);
|
|
ui32Config &= ~(IOC_IOCFG0_EDGE_IRQ_EN | IOC_IOCFG0_EDGE_DET_M);
|
|
HWREG(ui32IOReg) = ui32Config | ((ui32Int ? IOC_IOCFG0_EDGE_IRQ_EN : 0) | ui32EdgeDet);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set the pull on an IO port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIOPortPullSet(uint32_t ui32IOId, uint32_t ui32Pull)
|
|
{
|
|
uint32_t ui32IOReg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the argument.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT((ui32Pull == IOC_NO_IOPULL) ||
|
|
(ui32Pull == IOC_IOPULL_UP) ||
|
|
(ui32Pull == IOC_IOPULL_DOWN));
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32IOReg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the IO.
|
|
//
|
|
ui32Config = HWREG(ui32IOReg);
|
|
ui32Config &= ~IOC_IOCFG0_PULL_CTL_M;
|
|
HWREG(ui32IOReg) = ui32Config | ui32Pull;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure hysteresis on and IO port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIOHystSet(uint32_t ui32IOId, uint32_t ui32Hysteresis)
|
|
{
|
|
uint32_t ui32IOReg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT((ui32Hysteresis == IOC_HYST_ENABLE) ||
|
|
(ui32Hysteresis == IOC_HYST_DISABLE));
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32IOReg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the IO.
|
|
//
|
|
ui32Config = HWREG(ui32IOReg);
|
|
ui32Config &= ~IOC_IOCFG0_HYST_EN;
|
|
HWREG(ui32IOReg) = ui32Config | ui32Hysteresis;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Enable/disable IO port as input
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIOInputSet(uint32_t ui32IOId, uint32_t ui32Input)
|
|
{
|
|
uint32_t ui32IOReg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT((ui32Input == IOC_INPUT_ENABLE) ||
|
|
(ui32Input == IOC_INPUT_DISABLE));
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32IOReg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the IO.
|
|
//
|
|
ui32Config = HWREG(ui32IOReg);
|
|
ui32Config &= ~IOC_IOCFG0_IE;
|
|
HWREG(ui32IOReg) = ui32Config | ui32Input;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Enable/disable the slew control on an IO port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIOSlewCtrlSet(uint32_t ui32IOId, uint32_t ui32SlewEnable)
|
|
{
|
|
uint32_t ui32IOReg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT((ui32SlewEnable == IOC_SLEW_ENABLE) ||
|
|
(ui32SlewEnable == IOC_SLEW_DISABLE));
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32IOReg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the IO.
|
|
//
|
|
ui32Config = HWREG(ui32IOReg);
|
|
ui32Config &= ~IOC_IOCFG0_SLEW_RED;
|
|
HWREG(ui32IOReg) = ui32Config | ui32SlewEnable;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure the drive strength and maxium current of an IO port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIODrvStrengthSet(uint32_t ui32IOId, uint32_t ui32IOCurrent,
|
|
uint32_t ui32DrvStrength)
|
|
{
|
|
uint32_t ui32IOReg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT((ui32IOCurrent == IOC_CURRENT_2MA) ||
|
|
(ui32IOCurrent == IOC_CURRENT_4MA) ||
|
|
(ui32IOCurrent == IOC_CURRENT_8MA) ||
|
|
(ui32IOCurrent == IOC_CURRENT_16MA));
|
|
ASSERT((ui32DrvStrength == IOC_STRENGTH_MIN) ||
|
|
(ui32DrvStrength == IOC_STRENGTH_MAX) ||
|
|
(ui32DrvStrength == IOC_STRENGTH_MED) ||
|
|
(ui32DrvStrength == IOC_STRENGTH_AUTO));
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32IOReg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the IO.
|
|
//
|
|
ui32Config = HWREG(ui32IOReg);
|
|
ui32Config &= ~(IOC_IOCFG0_IOCURR_M | IOC_IOCFG0_IOSTR_M);
|
|
HWREG(ui32IOReg) = ui32Config | (ui32IOCurrent | ui32DrvStrength);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Setup the Port ID for this IO
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIOPortIdSet(uint32_t ui32IOId, uint32_t ui32PortId)
|
|
{
|
|
uint32_t ui32IOReg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
ASSERT(ui32PortId <= IOC_PORT_RFC_SMI_CL_IN);
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32IOReg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Configure the IO.
|
|
//
|
|
ui32Config = HWREG(ui32IOReg);
|
|
ui32Config &= ~IOC_IOCFG0_PORT_ID_M;
|
|
HWREG(ui32IOReg) = ui32Config | ui32PortId;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Enables individual IO edge detect interrupt
|
|
//!
|
|
//! \param ui32IOId is the IO to enable edge detect interrupt for.
|
|
//!
|
|
//! This function enables the indicated IO edge interrupt sources. Only the
|
|
//! sources that are enabled can be reflected to the processor interrupt;
|
|
//! disabled sources have no effect on the processor.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIntEnable(uint32_t ui32IOId)
|
|
{
|
|
uint32_t ui32IOReg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32IOReg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Enable the specified interrupt.
|
|
//
|
|
ui32Config = HWREG(ui32IOReg);
|
|
ui32Config |= IOC_IOCFG0_EDGE_IRQ_EN;
|
|
HWREG(ui32IOReg) = ui32Config;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Disables individual IO edge interrupt sources
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCIntDisable(uint32_t ui32IOId)
|
|
{
|
|
uint32_t ui32IOReg;
|
|
uint32_t ui32Config;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
|
|
//
|
|
// Get the register address.
|
|
//
|
|
ui32IOReg = IOC_BASE + g_pui32IOCfgReg[ui32IOId];
|
|
|
|
//
|
|
// Disable the specified interrupt.
|
|
//
|
|
ui32Config = HWREG(ui32IOReg);
|
|
ui32Config &= ~IOC_IOCFG0_EDGE_IRQ_EN;
|
|
HWREG(ui32IOReg) = ui32Config;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Setup an IO for standard GPIO input
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCPinTypeGpioInput(uint32_t ui32IOId)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
|
|
//
|
|
// Setup the IO for standard input.
|
|
//
|
|
IOCPortConfigureSet(ui32IOId, IOC_PORT_GPIO, IOC_STD_INPUT);
|
|
|
|
//
|
|
// Enable input mode in the GPIO module.
|
|
//
|
|
GPIODirModeSet(1 << ui32IOId, GPIO_DIR_MODE_IN);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Setup an IO for standard GPIO output
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCPinTypeGpioOutput(uint32_t ui32IOId)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32IOId <= IOID_31);
|
|
|
|
//
|
|
// Setup the IO for standard input.
|
|
//
|
|
IOCPortConfigureSet(ui32IOId, IOC_PORT_GPIO, IOC_STD_OUTPUT);
|
|
|
|
//
|
|
// Enable output mode in the GPIO module.
|
|
//
|
|
GPIODirModeSet(1 << ui32IOId, GPIO_DIR_MODE_OUT);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure a set of IOs for standard UART peripheral control
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCPinTypeUart(uint32_t ui32Base, uint32_t ui32Rx, uint32_t ui32Tx,
|
|
uint32_t ui32Cts, uint32_t ui32Rts)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32Base == UART0_BASE);
|
|
ASSERT((ui32Rx <= IOID_31) || (ui32Rx == IOID_UNUSED));
|
|
ASSERT((ui32Tx <= IOID_31) || (ui32Tx == IOID_UNUSED));
|
|
ASSERT((ui32Cts <= IOID_31) || (ui32Cts == IOID_UNUSED));
|
|
ASSERT((ui32Rts <= IOID_31) || (ui32Rts == IOID_UNUSED));
|
|
|
|
//
|
|
// Setup the IOs in the desired configuration.
|
|
//
|
|
if(ui32Rx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Rx, IOC_PORT_MCU_UART0_RX, IOC_STD_INPUT);
|
|
}
|
|
if(ui32Tx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Tx, IOC_PORT_MCU_UART0_TX, IOC_STD_OUTPUT);
|
|
}
|
|
if(ui32Cts != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Cts, IOC_PORT_MCU_UART0_CTS, IOC_STD_INPUT);
|
|
}
|
|
if(ui32Rts != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Rts, IOC_PORT_MCU_UART0_RTS, IOC_STD_OUTPUT);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure a set of IOs for standard SSI peripheral master control
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCPinTypeSsiMaster(uint32_t ui32Base, uint32_t ui32Rx,
|
|
uint32_t ui32Tx, uint32_t ui32Fss,
|
|
uint32_t ui32Clk)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE));
|
|
ASSERT((ui32Rx <= IOID_31) || (ui32Rx == IOID_UNUSED));
|
|
ASSERT((ui32Tx <= IOID_31) || (ui32Tx == IOID_UNUSED));
|
|
ASSERT((ui32Fss <= IOID_31) || (ui32Fss == IOID_UNUSED));
|
|
ASSERT((ui32Clk <= IOID_31) || (ui32Clk == IOID_UNUSED));
|
|
|
|
//
|
|
// Setup the IOs in the desired configuration.
|
|
//
|
|
if(ui32Base == SSI0_BASE)
|
|
{
|
|
if(ui32Rx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Rx, IOC_PORT_MCU_SSI0_RX, IOC_STD_INPUT);
|
|
}
|
|
if(ui32Tx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Tx, IOC_PORT_MCU_SSI0_TX, IOC_STD_OUTPUT);
|
|
}
|
|
if(ui32Fss != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Fss, IOC_PORT_MCU_SSI0_FSS, IOC_STD_OUTPUT);
|
|
}
|
|
if(ui32Clk != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Clk, IOC_PORT_MCU_SSI0_CLK, IOC_STD_OUTPUT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(ui32Rx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Rx, IOC_PORT_MCU_SSI1_RX, IOC_STD_INPUT);
|
|
}
|
|
if(ui32Tx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Tx, IOC_PORT_MCU_SSI1_TX, IOC_STD_OUTPUT);
|
|
}
|
|
if(ui32Fss != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Fss, IOC_PORT_MCU_SSI1_FSS, IOC_STD_OUTPUT);
|
|
}
|
|
if(ui32Clk != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Clk, IOC_PORT_MCU_SSI1_CLK, IOC_STD_OUTPUT);
|
|
}
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure a set of IOs for standard SSI peripheral slave control
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCPinTypeSsiSlave(uint32_t ui32Base, uint32_t ui32Rx,
|
|
uint32_t ui32Tx, uint32_t ui32Fss,
|
|
uint32_t ui32Clk)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE));
|
|
ASSERT((ui32Rx <= IOID_31) || (ui32Rx == IOID_UNUSED));
|
|
ASSERT((ui32Tx <= IOID_31) || (ui32Tx == IOID_UNUSED));
|
|
ASSERT((ui32Fss <= IOID_31) || (ui32Fss == IOID_UNUSED));
|
|
ASSERT((ui32Clk <= IOID_31) || (ui32Clk == IOID_UNUSED));
|
|
|
|
//
|
|
// Setup the IOs in the desired configuration.
|
|
//
|
|
if(ui32Base == SSI0_BASE)
|
|
{
|
|
if(ui32Rx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Rx, IOC_PORT_MCU_SSI0_RX, IOC_STD_INPUT);
|
|
}
|
|
if(ui32Tx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Tx, IOC_PORT_MCU_SSI0_TX, IOC_STD_OUTPUT);
|
|
}
|
|
if(ui32Fss != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Fss, IOC_PORT_MCU_SSI0_FSS, IOC_STD_INPUT);
|
|
}
|
|
if(ui32Clk != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Clk, IOC_PORT_MCU_SSI0_CLK, IOC_STD_INPUT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(ui32Rx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Rx, IOC_PORT_MCU_SSI1_RX, IOC_STD_INPUT);
|
|
}
|
|
if(ui32Tx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Tx, IOC_PORT_MCU_SSI1_TX, IOC_STD_OUTPUT);
|
|
}
|
|
if(ui32Fss != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Fss, IOC_PORT_MCU_SSI1_FSS, IOC_STD_INPUT);
|
|
}
|
|
if(ui32Clk != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Clk, IOC_PORT_MCU_SSI1_CLK, IOC_STD_INPUT);
|
|
}
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure a set of IOs for standard I2C peripheral control
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCPinTypeI2c(uint32_t ui32Base, uint32_t ui32Data, uint32_t ui32Clk)
|
|
{
|
|
uint32_t ui32IOConfig;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Data <= IOID_31) || (ui32Data == IOID_UNUSED));
|
|
ASSERT((ui32Clk <= IOID_31) || (ui32Clk == IOID_UNUSED));
|
|
|
|
//
|
|
// Define the IO configuration parameters.
|
|
//
|
|
ui32IOConfig = IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | IOC_IOPULL_UP |
|
|
IOC_SLEW_DISABLE | IOC_HYST_DISABLE | IOC_NO_EDGE |
|
|
IOC_INT_DISABLE | IOC_IOMODE_OPEN_DRAIN_NORMAL |
|
|
IOC_NO_WAKE_UP | IOC_INPUT_ENABLE;
|
|
|
|
//
|
|
// Setup the IOs in the desired configuration.
|
|
//
|
|
IOCPortConfigureSet(ui32Data, IOC_PORT_MCU_I2C_MSSDA, ui32IOConfig);
|
|
IOCPortConfigureSet(ui32Clk, IOC_PORT_MCU_I2C_MSSCL, ui32IOConfig);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure a set of IOs for standard SPIS peripheral control
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCPinTypeSpis(uint32_t ui32Rx, uint32_t ui32Tx, uint32_t ui32Fss,
|
|
uint32_t ui32Clk)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Rx <= IOID_31) || (ui32Rx == IOID_UNUSED));
|
|
ASSERT((ui32Tx <= IOID_31) || (ui32Tx == IOID_UNUSED));
|
|
ASSERT((ui32Fss <= IOID_31) || (ui32Fss == IOID_UNUSED));
|
|
ASSERT((ui32Clk <= IOID_31) || (ui32Clk == IOID_UNUSED));
|
|
|
|
//
|
|
// Setup the IOs in the desired configuration.
|
|
//
|
|
if(ui32Rx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Rx, IOC_PORT_AON_SDI, IOC_STD_INPUT);
|
|
}
|
|
if(ui32Tx != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Tx, IOC_PORT_AON_SDO, IOC_STD_OUTPUT);
|
|
}
|
|
if(ui32Fss != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Fss, IOC_PORT_AON_SCS, IOC_STD_INPUT);
|
|
}
|
|
if(ui32Clk != IOID_UNUSED)
|
|
{
|
|
IOCPortConfigureSet(ui32Clk, IOC_PORT_AON_SCK, IOC_STD_INPUT);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure an IO for AUX control
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
IOCPinTypeAux(uint32_t ui32IOId)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32IOId <= IOID_31) || (ui32IOId == IOID_UNUSED));
|
|
|
|
//
|
|
// Setup the IO.
|
|
//
|
|
IOCPortConfigureSet(ui32IOId, IOC_PORT_AUX_IO, IOC_STD_INPUT);
|
|
}
|
|
//! @}
|
|
//! \\addtogroup prcm_api
|
|
//! @{
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// Arrays that maps the "peripheral set" number (which is stored in the
|
|
// third nibble of the PRCM_PERIPH_* defines) to the PRCM register that
|
|
// contains the relevant bit for that peripheral.
|
|
//
|
|
//*****************************************************************************
|
|
|
|
// Run mode registers
|
|
static const uint32_t g_pui32RCGCRegs[] =
|
|
{
|
|
PRCM_O_GPTCLKGR,
|
|
PRCM_O_SSICLKGR,
|
|
PRCM_O_UARTCLKGR,
|
|
PRCM_O_I2CCLKGR,
|
|
PRCM_O_SECDMACLKGR,
|
|
PRCM_O_GPIOCLKGR,
|
|
PRCM_O_I2SCLKGR
|
|
};
|
|
|
|
// Sleep mode registers
|
|
static const uint32_t g_pui32SCGCRegs[] =
|
|
{
|
|
PRCM_O_GPTCLKGS,
|
|
PRCM_O_SSICLKGS,
|
|
PRCM_O_UARTCLKGS,
|
|
PRCM_O_I2CCLKGS,
|
|
PRCM_O_SECDMASCLKG,
|
|
PRCM_O_GPIOCLKGS,
|
|
PRCM_O_I2SCLKGS
|
|
};
|
|
|
|
// Deep sleep mode registers
|
|
static const uint32_t g_pui32DCGCRegs[] =
|
|
{
|
|
PRCM_O_GPTCLKGDS,
|
|
PRCM_O_SSICLKGDS,
|
|
PRCM_O_UARTCLKGDS,
|
|
PRCM_O_I2CCLKGDS,
|
|
PRCM_O_SECDMACLKGDS,
|
|
PRCM_O_GPIOCLKGDS,
|
|
PRCM_O_I2SCLKGDS
|
|
};
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// This macro extracts the array index out of the peripheral number
|
|
//
|
|
//*****************************************************************************
|
|
#define PRCM_PERIPH_INDEX(a) (((a) >> 8) & 0xf)
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// This macro extracts the peripheral instance number and generates bit mask
|
|
//
|
|
//*****************************************************************************
|
|
#define PRCM_PERIPH_MASKBIT(a) (0x00000001 << ((a) & 0xf))
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure the infrastructure clock.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMInfClockConfigureSet(uint32_t ui32ClkDiv, uint32_t ui32PowerMode)
|
|
{
|
|
uint32_t ui32Divisor;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32ClkDiv == PRCM_CLOCK_DIV_1) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_2) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_8) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_32));
|
|
ASSERT((ui32PowerMode == PRCM_RUN_MODE) ||
|
|
(ui32PowerMode == PRCM_SLEEP_MODE) ||
|
|
(ui32PowerMode == PRCM_DEEP_SLEEP_MODE));
|
|
|
|
ui32Divisor = 0;
|
|
|
|
//
|
|
// Find the correct division factor.
|
|
//
|
|
if(ui32ClkDiv == PRCM_CLOCK_DIV_1)
|
|
{
|
|
ui32Divisor = 0x0;
|
|
}
|
|
else if(ui32ClkDiv == PRCM_CLOCK_DIV_2)
|
|
{
|
|
ui32Divisor = 0x1;
|
|
}
|
|
else if(ui32ClkDiv == PRCM_CLOCK_DIV_8)
|
|
{
|
|
ui32Divisor = 0x2;
|
|
}
|
|
else if(ui32ClkDiv == PRCM_CLOCK_DIV_32)
|
|
{
|
|
ui32Divisor = 0x3;
|
|
}
|
|
|
|
//
|
|
// Determine the correct power mode set the division factor accordingly.
|
|
//
|
|
if(ui32PowerMode == PRCM_RUN_MODE)
|
|
{
|
|
HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVR) = ui32Divisor;
|
|
}
|
|
else if(ui32PowerMode == PRCM_SLEEP_MODE)
|
|
{
|
|
HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVS) = ui32Divisor;
|
|
}
|
|
else if(ui32PowerMode == PRCM_DEEP_SLEEP_MODE)
|
|
{
|
|
HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVDS) = ui32Divisor;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Use this function to retreive the set infrastructure clock configuration
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
PRCMInfClockConfigureGet(uint32_t ui32PowerMode)
|
|
{
|
|
uint32_t ui32ClkDiv;
|
|
uint32_t ui32Divisor;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32PowerMode == PRCM_RUN_MODE) ||
|
|
(ui32PowerMode == PRCM_SLEEP_MODE) ||
|
|
(ui32PowerMode == PRCM_DEEP_SLEEP_MODE));
|
|
|
|
ui32ClkDiv = 0;
|
|
ui32Divisor = 0;
|
|
|
|
//
|
|
// Determine the correct power mode.
|
|
//
|
|
if(ui32PowerMode == PRCM_RUN_MODE)
|
|
{
|
|
ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVR);
|
|
}
|
|
else if(ui32PowerMode == PRCM_SLEEP_MODE)
|
|
{
|
|
ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVS);
|
|
}
|
|
else if(ui32PowerMode == PRCM_DEEP_SLEEP_MODE)
|
|
{
|
|
ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVDS);
|
|
}
|
|
|
|
//
|
|
// Find the correct division factor.
|
|
//
|
|
if(ui32ClkDiv == 0x0)
|
|
{
|
|
ui32Divisor = PRCM_CLOCK_DIV_1;
|
|
}
|
|
else if(ui32ClkDiv == 0x1)
|
|
{
|
|
ui32Divisor = PRCM_CLOCK_DIV_2;
|
|
}
|
|
else if(ui32ClkDiv == 0x2)
|
|
{
|
|
ui32Divisor = PRCM_CLOCK_DIV_8;
|
|
}
|
|
else if(ui32ClkDiv == 0x3)
|
|
{
|
|
ui32Divisor = PRCM_CLOCK_DIV_32;
|
|
}
|
|
|
|
//
|
|
// Return the clock divison factor.
|
|
//
|
|
return ui32Divisor;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Setup the clock division factor for a subsystem in the MCU voltage
|
|
//! domain.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMClockConfigureSet(uint32_t ui32Domains, uint32_t ui32ClkDiv)
|
|
{
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Domains & PRCM_DOMAIN_SYSBUS) ||
|
|
(ui32Domains & PRCM_DOMAIN_CPU) ||
|
|
(ui32Domains & PRCM_DOMAIN_PERIPH) ||
|
|
(ui32Domains & PRCM_DOMAIN_TIMER) ||
|
|
(ui32Domains & PRCM_DOMAIN_SERIAL));
|
|
ASSERT((ui32ClkDiv == PRCM_CLOCK_DIV_1) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_2) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_4) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_8) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_16) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_32) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_64) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_128) ||
|
|
(ui32ClkDiv == PRCM_CLOCK_DIV_256));
|
|
|
|
//
|
|
// Configure the selected clock dividers.
|
|
//
|
|
if(ui32Domains & PRCM_DOMAIN_SYSBUS)
|
|
{
|
|
ui32Reg = PRCM_O_SYSBUSCLKDIV;
|
|
HWREG(PRCM_BASE + ui32Reg) = ui32ClkDiv;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_CPU)
|
|
{
|
|
ui32Reg = PRCM_O_CPUCLKDIV;
|
|
HWREG(PRCM_BASE + ui32Reg) = ui32ClkDiv;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_PERIPH)
|
|
{
|
|
ui32Reg = PRCM_O_PERBUSCPUCLKDIV;
|
|
HWREG(PRCM_BASE + ui32Reg) = ui32ClkDiv;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_SERIAL)
|
|
{
|
|
ui32Reg = PRCM_O_PERDMACLKDIV;
|
|
HWREG(PRCM_BASE + ui32Reg) = ui32ClkDiv;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_TIMER)
|
|
{
|
|
ui32Reg = PRCM_O_GPTCLKDIV;
|
|
HWREG(PRCM_BASE + ui32Reg) = ui32ClkDiv;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get the clock configuration for a specific sub system in the MCU Voltage
|
|
//! Domain.
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
PRCMClockConfigureGet(uint32_t ui32Domain)
|
|
{
|
|
uint32_t ui32ClkDiv;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Domain == PRCM_DOMAIN_SYSBUS) ||
|
|
(ui32Domain == PRCM_DOMAIN_CPU) ||
|
|
(ui32Domain == PRCM_DOMAIN_PERIPH) ||
|
|
(ui32Domain == PRCM_DOMAIN_TIMER) ||
|
|
(ui32Domain == PRCM_DOMAIN_SERIAL));
|
|
|
|
ui32ClkDiv = 0;
|
|
|
|
//
|
|
// Find the correct sub system.
|
|
//
|
|
if(ui32Domain == PRCM_DOMAIN_SYSBUS)
|
|
{
|
|
ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_SYSBUSCLKDIV);
|
|
}
|
|
else if(ui32Domain == PRCM_DOMAIN_CPU)
|
|
{
|
|
ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_CPUCLKDIV);
|
|
}
|
|
else if(ui32Domain == PRCM_DOMAIN_PERIPH)
|
|
{
|
|
ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_PERBUSCPUCLKDIV);
|
|
}
|
|
else if(ui32Domain == PRCM_DOMAIN_SERIAL)
|
|
{
|
|
ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_PERDMACLKDIV);
|
|
}
|
|
else if(ui32Domain == PRCM_DOMAIN_TIMER)
|
|
{
|
|
ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_GPTCLKDIV);
|
|
}
|
|
|
|
//
|
|
// Return the clock configuration.
|
|
//
|
|
return(ui32ClkDiv);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure the audio clock generation
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMAudioClockConfigSet(uint32_t ui32ClkConfig, uint32_t ui32SampleRate)
|
|
{
|
|
uint32_t ui32Reg;
|
|
uint32_t ui32MstDiv;
|
|
uint32_t ui32BitDiv;
|
|
uint32_t ui32WordDiv;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(!(ui32ClkConfig & (PRCM_I2SCLKCTL_WCLK_PHASE_M | PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_M)));
|
|
ASSERT((ui32SampleRate == I2S_SAMPLE_RATE_16K) ||
|
|
(ui32SampleRate == I2S_SAMPLE_RATE_24K) ||
|
|
(ui32SampleRate == I2S_SAMPLE_RATE_32K) ||
|
|
(ui32SampleRate == I2S_SAMPLE_RATE_48K));
|
|
|
|
ui32MstDiv = 0;
|
|
ui32BitDiv = 0;
|
|
ui32WordDiv = 0;
|
|
|
|
//
|
|
// Make sure the audio clock generation is disabled before reconfiguring.
|
|
//
|
|
PRCMAudioClockDisable();
|
|
|
|
//
|
|
// Define the clock division factors for the audio interface.
|
|
//
|
|
switch(ui32SampleRate)
|
|
{
|
|
case I2S_SAMPLE_RATE_16K :
|
|
ui32MstDiv = 6;
|
|
ui32BitDiv = 60;
|
|
ui32WordDiv = 25;
|
|
break;
|
|
case I2S_SAMPLE_RATE_24K :
|
|
ui32MstDiv = 4;
|
|
ui32BitDiv = 40;
|
|
ui32WordDiv = 25;
|
|
break;
|
|
case I2S_SAMPLE_RATE_32K :
|
|
ui32MstDiv = 3;
|
|
ui32BitDiv = 30;
|
|
ui32WordDiv = 25;
|
|
break;
|
|
case I2S_SAMPLE_RATE_48K :
|
|
ui32MstDiv = 2;
|
|
ui32BitDiv = 20;
|
|
ui32WordDiv = 25;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Make sure to compensate the Frame clock division factor if using single
|
|
// phase format.
|
|
//
|
|
if((ui32ClkConfig & PRCM_I2SCLKCTL_WCLK_PHASE_M) == PRCM_WCLK_SINGLE_PHASE)
|
|
{
|
|
ui32WordDiv -= 1;
|
|
}
|
|
|
|
//
|
|
// Write the clock divison factors.
|
|
//
|
|
HWREG(PRCM_BASE + PRCM_O_I2SMCLKDIV) = ui32MstDiv;
|
|
HWREG(PRCM_BASE + PRCM_O_I2SBCLKDIV) = ui32BitDiv;
|
|
HWREG(PRCM_BASE + PRCM_O_I2SWCLKDIV) = ui32WordDiv;
|
|
|
|
//
|
|
// Configure the Word clock format and polarity.
|
|
//
|
|
ui32Reg = HWREG(PRCM_BASE + PRCM_O_I2SCLKCTL) & ~(PRCM_I2SCLKCTL_WCLK_PHASE_M |
|
|
PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_M);
|
|
HWREG(PRCM_BASE + PRCM_O_I2SCLKCTL) = ui32Reg | ui32ClkConfig;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Turn power on in power domains in the MCU domain
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMPowerDomainOn(uint32_t ui32Domains)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Domains & PRCM_DOMAIN_RFCORE) ||
|
|
(ui32Domains & PRCM_DOMAIN_SERIAL) ||
|
|
(ui32Domains & PRCM_DOMAIN_PERIPH) ||
|
|
(ui32Domains & PRCM_DOMAIN_CPU) ||
|
|
(ui32Domains & PRCM_DOMAIN_VIMS));
|
|
|
|
//
|
|
// Assert the request to power on the right domains.
|
|
//
|
|
if(ui32Domains & PRCM_DOMAIN_RFCORE)
|
|
{
|
|
HWREG(PRCM_BASE +
|
|
PRCM_O_PDCTL0RFC) |= PRCM_PDCTL0RFC_ON;
|
|
HWREG(PRCM_BASE + PRCM_O_PDCTL1RFC) |= PRCM_PDCTL1RFC_ON;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_SERIAL)
|
|
{
|
|
HWREG(PRCM_BASE +
|
|
PRCM_O_PDCTL0SERIAL) |= PRCM_PDCTL0SERIAL_ON;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_PERIPH)
|
|
{
|
|
HWREG(PRCM_BASE +
|
|
PRCM_O_PDCTL0PERIPH) |= PRCM_PDCTL0PERIPH_ON;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_VIMS)
|
|
{
|
|
HWREG(PRCM_BASE + PRCM_O_PDCTL1VIMS) |=
|
|
PRCM_PDCTL1VIMS_ON;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_CPU)
|
|
{
|
|
HWREG(PRCM_BASE + PRCM_O_PDCTL1CPU) |= PRCM_PDCTL1CPU_ON;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Turn off a specific power domain
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMPowerDomainOff(uint32_t ui32Domains)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Domains & PRCM_DOMAIN_RFCORE) ||
|
|
(ui32Domains & PRCM_DOMAIN_SERIAL) ||
|
|
(ui32Domains & PRCM_DOMAIN_PERIPH) ||
|
|
(ui32Domains & PRCM_DOMAIN_CPU) ||
|
|
(ui32Domains & PRCM_DOMAIN_VIMS));
|
|
|
|
//
|
|
// Assert the request to power off the right domains.
|
|
//
|
|
if(ui32Domains & PRCM_DOMAIN_RFCORE)
|
|
{
|
|
HWREG(PRCM_BASE +
|
|
PRCM_O_PDCTL0RFC) &= ~PRCM_PDCTL0RFC_ON;
|
|
HWREG(PRCM_BASE + PRCM_O_PDCTL1RFC) &= ~PRCM_PDCTL1RFC_ON;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_SERIAL)
|
|
{
|
|
HWREG(PRCM_BASE +
|
|
PRCM_O_PDCTL0SERIAL) &= ~PRCM_PDCTL0SERIAL_ON;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_PERIPH)
|
|
{
|
|
HWREG(PRCM_BASE +
|
|
PRCM_O_PDCTL0PERIPH) &= ~PRCM_PDCTL0PERIPH_ON;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_VIMS)
|
|
{
|
|
HWREG(PRCM_BASE + PRCM_O_PDCTL1VIMS) &=
|
|
~PRCM_PDCTL1VIMS_ON;
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_CPU)
|
|
{
|
|
HWREG(PRCM_BASE + PRCM_O_PDCTL1CPU) &= ~PRCM_PDCTL1CPU_ON;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Enables a peripheral in Run mode
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMPeripheralRunEnable(uint32_t ui32Peripheral)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(PRCMPeripheralValid(ui32Peripheral));
|
|
|
|
//
|
|
// Enable module in Run Mode.
|
|
//
|
|
HWREG(PRCM_BASE + g_pui32RCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) |=
|
|
PRCM_PERIPH_MASKBIT(ui32Peripheral);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Disables a peripheral in Run mode
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMPeripheralRunDisable(uint32_t ui32Peripheral)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(PRCMPeripheralValid(ui32Peripheral));
|
|
|
|
//
|
|
// Disable module in Run Mode.
|
|
//
|
|
HWREG(PRCM_BASE + g_pui32RCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) &=
|
|
~PRCM_PERIPH_MASKBIT(ui32Peripheral);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Enables a peripheral in sleep mode
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMPeripheralSleepEnable(uint32_t ui32Peripheral)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(PRCMPeripheralValid(ui32Peripheral));
|
|
|
|
//
|
|
// Enable this peripheral in sleep mode.
|
|
//
|
|
HWREG(PRCM_BASE + g_pui32SCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) |=
|
|
PRCM_PERIPH_MASKBIT(ui32Peripheral);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Disables a peripheral in sleep mode
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMPeripheralSleepDisable(uint32_t ui32Peripheral)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(PRCMPeripheralValid(ui32Peripheral));
|
|
|
|
//
|
|
// Disable this peripheral in sleep mode
|
|
//
|
|
HWREG(PRCM_BASE + g_pui32SCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) &=
|
|
~PRCM_PERIPH_MASKBIT(ui32Peripheral);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Enables a peripheral in deep-sleep mode
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMPeripheralDeepSleepEnable(uint32_t ui32Peripheral)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(PRCMPeripheralValid(ui32Peripheral));
|
|
|
|
//
|
|
// Enable this peripheral in deep-sleep mode.
|
|
//
|
|
HWREG(PRCM_BASE + g_pui32DCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) |=
|
|
PRCM_PERIPH_MASKBIT(ui32Peripheral);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Disables a peripheral in deep-sleep mode
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMPeripheralDeepSleepDisable(uint32_t ui32Peripheral)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(PRCMPeripheralValid(ui32Peripheral));
|
|
|
|
//
|
|
// Disable this peripheral in Deep Sleep mode.
|
|
//
|
|
HWREG(PRCM_BASE + g_pui32DCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) &=
|
|
~PRCM_PERIPH_MASKBIT(ui32Peripheral);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get the status for a specific power domain
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
PRCMPowerDomainStatus(uint32_t ui32Domains)
|
|
{
|
|
bool bStatus;
|
|
uint32_t ui32StatusRegister0;
|
|
uint32_t ui32StatusRegister1;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Domains & (PRCM_DOMAIN_RFCORE |
|
|
PRCM_DOMAIN_SERIAL |
|
|
PRCM_DOMAIN_PERIPH)));
|
|
|
|
bStatus = true;
|
|
ui32StatusRegister0 = HWREG(PRCM_BASE + PRCM_O_PDSTAT0);
|
|
ui32StatusRegister1 = HWREG(PRCM_BASE + PRCM_O_PDSTAT1);
|
|
|
|
//
|
|
// Return the correct power status.
|
|
//
|
|
if(ui32Domains & PRCM_DOMAIN_RFCORE)
|
|
{
|
|
bStatus = bStatus &&
|
|
((ui32StatusRegister0 & PRCM_PDSTAT0_RFC_ON) ||
|
|
(ui32StatusRegister1 & PRCM_PDSTAT1_RFC_ON));
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_SERIAL)
|
|
{
|
|
bStatus = bStatus && (ui32StatusRegister0 & PRCM_PDSTAT0_SERIAL_ON);
|
|
}
|
|
if(ui32Domains & PRCM_DOMAIN_PERIPH)
|
|
{
|
|
bStatus = bStatus && (ui32StatusRegister0 & PRCM_PDSTAT0_PERIPH_ON);
|
|
}
|
|
|
|
//
|
|
// Return the status.
|
|
//
|
|
return (bStatus ? PRCM_DOMAIN_POWER_ON : PRCM_DOMAIN_POWER_OFF);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Put the processor into deep-sleep mode
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMDeepSleep(void)
|
|
{
|
|
//
|
|
// Enable deep-sleep.
|
|
//
|
|
HWREG(NVIC_SYS_CTRL) |= NVIC_SYS_CTRL_SLEEPDEEP;
|
|
|
|
//
|
|
// Wait for an interrupt.
|
|
//
|
|
CPUwfi();
|
|
|
|
//
|
|
// Disable deep-sleep so that a future sleep will work correctly.
|
|
//
|
|
HWREG(NVIC_SYS_CTRL) &= ~(NVIC_SYS_CTRL_SLEEPDEEP);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Enable retention on specific power domains
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMRetentionEnable(uint32_t ui32PowerDomain)
|
|
{
|
|
uint32_t ui32Retention;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((PRCM_DOMAIN_PERIPH & ui32PowerDomain) ||
|
|
(PRCM_DOMAIN_CPU & ui32PowerDomain));
|
|
|
|
//
|
|
// Get the current register.
|
|
//
|
|
ui32Retention = HWREG(PRCM_BASE + PRCM_O_PDRETEN);
|
|
|
|
//
|
|
// Set the bits.
|
|
//
|
|
if(PRCM_DOMAIN_PERIPH & ui32PowerDomain)
|
|
{
|
|
ui32Retention |= PRCM_PDRETEN_PERIPH;
|
|
}
|
|
if(PRCM_DOMAIN_CPU & ui32PowerDomain)
|
|
{
|
|
ui32Retention |= PRCM_PDRETEN_CPU;
|
|
}
|
|
|
|
//
|
|
// Reconfigure retention.
|
|
//
|
|
HWREG(PRCM_BASE + PRCM_O_PDRETEN) = ui32Retention;
|
|
|
|
//
|
|
// Get the current register values.
|
|
//
|
|
ui32Retention = HWREG(PRCM_BASE + PRCM_O_RAMRETEN);
|
|
|
|
//
|
|
// Enable retention on RF core SRAM.
|
|
//
|
|
if(PRCM_DOMAIN_RFCORE & ui32PowerDomain)
|
|
{
|
|
ui32Retention |= PRCM_RAMRETEN_RFC_M;
|
|
}
|
|
|
|
//
|
|
// Enable retention on VIMS cache.
|
|
//
|
|
if(PRCM_DOMAIN_VIMS & ui32PowerDomain)
|
|
{
|
|
ui32Retention |= PRCM_RAMRETEN_VIMS_M;
|
|
}
|
|
|
|
//
|
|
// Reconfigure retention.
|
|
//
|
|
HWREG(PRCM_BASE + PRCM_O_RAMRETEN) = ui32Retention;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Disable retention on power domains
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
PRCMRetentionDisable(uint32_t ui32PowerDomain)
|
|
{
|
|
uint32_t ui32Retention;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((PRCM_DOMAIN_PERIPH & ui32PowerDomain) ||
|
|
(PRCM_DOMAIN_CPU & ui32PowerDomain));
|
|
|
|
//
|
|
// Get the current register.
|
|
//
|
|
ui32Retention = HWREG(PRCM_BASE + PRCM_O_PDRETEN);
|
|
|
|
//
|
|
// Clear the bits.
|
|
//
|
|
if(PRCM_DOMAIN_PERIPH & ui32PowerDomain)
|
|
{
|
|
ui32Retention &= ~PRCM_PDRETEN_PERIPH;
|
|
}
|
|
if(PRCM_DOMAIN_CPU & ui32PowerDomain)
|
|
{
|
|
ui32Retention &= ~PRCM_PDRETEN_CPU;
|
|
}
|
|
|
|
//
|
|
// Reconfigure retention.
|
|
//
|
|
HWREG(PRCM_BASE + PRCM_O_PDRETEN) = ui32Retention;
|
|
|
|
//
|
|
// Get the current register values
|
|
//
|
|
ui32Retention = HWREG(PRCM_BASE + PRCM_O_RAMRETEN);
|
|
|
|
//
|
|
// Disable retention on RF core SRAM
|
|
//
|
|
if(PRCM_DOMAIN_RFCORE & ui32PowerDomain)
|
|
{
|
|
ui32Retention &= ~PRCM_RAMRETEN_RFC_M;
|
|
}
|
|
|
|
//
|
|
// Disable retention on VIMS cache
|
|
//
|
|
if(PRCM_DOMAIN_VIMS & ui32PowerDomain)
|
|
{
|
|
ui32Retention &= ~PRCM_RAMRETEN_VIMS_M;
|
|
}
|
|
|
|
//
|
|
// Reconfigure retention.
|
|
//
|
|
HWREG(PRCM_BASE + PRCM_O_RAMRETEN) = ui32Retention;
|
|
}
|
|
//! @}
|
|
//! \\addtogroup smph_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Acquire a semaphore
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
SMPHAcquire(uint32_t ui32Semaphore)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Semaphore == SMPH_0) ||
|
|
(ui32Semaphore == SMPH_1) ||
|
|
(ui32Semaphore == SMPH_2) ||
|
|
(ui32Semaphore == SMPH_3) ||
|
|
(ui32Semaphore == SMPH_4) ||
|
|
(ui32Semaphore == SMPH_5) ||
|
|
(ui32Semaphore == SMPH_6) ||
|
|
(ui32Semaphore == SMPH_7) ||
|
|
(ui32Semaphore == SMPH_8) ||
|
|
(ui32Semaphore == SMPH_9) ||
|
|
(ui32Semaphore == SMPH_10) ||
|
|
(ui32Semaphore == SMPH_11) ||
|
|
(ui32Semaphore == SMPH_12) ||
|
|
(ui32Semaphore == SMPH_13) ||
|
|
(ui32Semaphore == SMPH_14) ||
|
|
(ui32Semaphore == SMPH_15) ||
|
|
(ui32Semaphore == SMPH_16) ||
|
|
(ui32Semaphore == SMPH_17) ||
|
|
(ui32Semaphore == SMPH_18) ||
|
|
(ui32Semaphore == SMPH_19) ||
|
|
(ui32Semaphore == SMPH_20) ||
|
|
(ui32Semaphore == SMPH_21) ||
|
|
(ui32Semaphore == SMPH_22) ||
|
|
(ui32Semaphore == SMPH_23) ||
|
|
(ui32Semaphore == SMPH_24) ||
|
|
(ui32Semaphore == SMPH_25) ||
|
|
(ui32Semaphore == SMPH_26) ||
|
|
(ui32Semaphore == SMPH_27) ||
|
|
(ui32Semaphore == SMPH_28) ||
|
|
(ui32Semaphore == SMPH_29) ||
|
|
(ui32Semaphore == SMPH_30) ||
|
|
(ui32Semaphore == SMPH_31));
|
|
|
|
//
|
|
// Wait for semaphore to be release such that it can be claimed
|
|
// Semaphore register reads 1 when lock was acquired otherwise 0
|
|
// (i.e. SMPH_CLAIMED).
|
|
//
|
|
while(HWREG(SMPH_BASE + SMPH_O_SMPH0 + 4 * ui32Semaphore) ==
|
|
SMPH_CLAIMED)
|
|
{
|
|
}
|
|
}
|
|
//! @}
|
|
//! \\addtogroup spis_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
// This is the mapping between an TX Fifo index and the corresponding
|
|
// register.
|
|
//
|
|
//*****************************************************************************
|
|
static const uint32_t g_pui32SPISTxFifo[] =
|
|
{
|
|
SPIS_O_TXFMEM0, SPIS_O_TXFMEM1, SPIS_O_TXFMEM2, SPIS_O_TXFMEM3, SPIS_O_TXFMEM4,
|
|
SPIS_O_TXFMEM5, SPIS_O_TXFMEM6, SPIS_O_TXFMEM7, SPIS_O_TXFMEM8, SPIS_O_TXFMEM9,
|
|
SPIS_O_TXFMEM10, SPIS_O_TXFMEM11, SPIS_O_TXFMEM12, SPIS_O_TXFMEM13,
|
|
SPIS_O_TXFMEM14, SPIS_O_TXFMEM15
|
|
};
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// This is the mapping between an RX Fifo index and the corresponding
|
|
// register.
|
|
//
|
|
//*****************************************************************************
|
|
static const uint32_t g_pui32SPISRxFifo[] =
|
|
{
|
|
SPIS_O_RXFMEM0, SPIS_O_RXFMEM1, SPIS_O_RXFMEM2, SPIS_O_RXFMEM3, SPIS_O_RXFMEM4,
|
|
SPIS_O_RXFMEM5, SPIS_O_RXFMEM6, SPIS_O_RXFMEM7, SPIS_O_RXFMEM8, SPIS_O_RXFMEM9,
|
|
SPIS_O_RXFMEM10, SPIS_O_RXFMEM11, SPIS_O_RXFMEM12, SPIS_O_RXFMEM13,
|
|
SPIS_O_RXFMEM14, SPIS_O_RXFMEM15
|
|
};
|
|
//*****************************************************************************
|
|
//
|
|
//! Puts a data element into the SPIS transmit FIFO
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
SPISDataPut(uint32_t ui32Data)
|
|
{
|
|
//
|
|
// Wait until there is space.
|
|
//
|
|
while(HWREG(SPIS_BASE + SPIS_O_TXFSTAT) & SPIS_TXFSTAT_FULL)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Write the data to the SPIS Tx Fifo.
|
|
//
|
|
HWREG(SPIS_BASE + SPIS_O_TXFPUSH) = ui32Data;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get a specific value in the Tx Fifo
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
SPISTxGetValue(uint32_t ui32Index)
|
|
{
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32Index < TX_FIFO_SIZE);
|
|
|
|
//
|
|
// Find the correct register.
|
|
//
|
|
ui32Reg = g_pui32SPISTxFifo[ui32Index];
|
|
|
|
//
|
|
// Return the value of the TX Fifo at the specified index.
|
|
//
|
|
return HWREG(SPIS_BASE + ui32Reg);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets a data element from the SPIS Rx FIFO
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
SPISDataGet(uint32_t *pui32Data)
|
|
{
|
|
//
|
|
// Wait until there is data to be read.
|
|
//
|
|
while(!(HWREG(SPIS_BASE + SPIS_O_RXFSTAT) & SPIS_RXFSTAT_NOT_EMPTY))
|
|
{
|
|
}
|
|
|
|
//
|
|
// Read data from SPIS Rx Fifo.
|
|
//
|
|
*pui32Data = HWREG(SPIS_BASE + SPIS_O_RXFPOP);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get a specific value in the Rx Fifo
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
SPISRxGetValue(uint32_t ui32Index)
|
|
{
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(ui32Index < RX_FIFO_SIZE);
|
|
|
|
//
|
|
// Find the correct register.
|
|
//
|
|
ui32Reg = g_pui32SPISRxFifo[ui32Index];
|
|
|
|
//
|
|
// Return the value of the RX Fifo at the specified index.
|
|
//
|
|
return HWREG(SPIS_BASE + ui32Reg);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets the current interrupt status
|
|
//!
|
|
//! \param bMasked is \b false if the raw interrupt status is required or
|
|
//! \b true if the masked interrupt status is required.
|
|
//!
|
|
//! This function returns the interrupt status for the SPIS module. Either the
|
|
//! raw interrupt status or the status of interrupts that are allowed to
|
|
//! reflect to the processor can be returned.
|
|
//!
|
|
//! \return The current interrupt status consisting of a bitwise OR value
|
|
//! of the available interrupts sources as described in \b SPISIntEnable().
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
SPISIntStatus(bool bMasked)
|
|
{
|
|
uint32_t ui32IntStatus, ui32Tmp;
|
|
|
|
//
|
|
// Return either the interrupt status or the raw interrupt status as
|
|
// requested.
|
|
//
|
|
if(bMasked)
|
|
{
|
|
ui32Tmp = HWREG(SPIS_BASE + SPIS_O_TXFFLAGSCLRN);
|
|
ui32IntStatus = ui32Tmp & HWREG(SPIS_BASE + SPIS_O_TXFFLAGSMASK);
|
|
ui32Tmp = HWREG(SPIS_BASE + SPIS_O_RXFFLAGSCLRN);
|
|
ui32IntStatus |= (ui32Tmp & HWREG(SPIS_BASE + SPIS_O_RXFFLAGSMASK)) << 8;
|
|
ui32Tmp = HWREG(SPIS_BASE + SPIS_O_GPFLAGS);
|
|
ui32IntStatus |= (ui32Tmp & HWREG(SPIS_BASE + SPIS_O_GPFLAGSMASK)) << 16;
|
|
}
|
|
else
|
|
{
|
|
ui32IntStatus = HWREG(SPIS_BASE + SPIS_O_TXFFLAGSCLRN) & SPIS_TX_MASK;
|
|
ui32IntStatus |= (HWREG(SPIS_BASE + SPIS_O_RXFFLAGSCLRN) << 8) & SPIS_RX_MASK;
|
|
ui32IntStatus |= (HWREG(SPIS_BASE + SPIS_O_GPFLAGS) << 16) & SPIS_GP_MASK;
|
|
}
|
|
return ui32IntStatus;
|
|
}
|
|
//! @}
|
|
//! \\addtogroup ssi_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Configures the synchronous serial port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
SSIConfigSetExpClk(uint32_t ui32Base, uint32_t ui32SSIClk,
|
|
uint32_t ui32Protocol, uint32_t ui32Mode,
|
|
uint32_t ui32BitRate, uint32_t ui32DataWidth)
|
|
{
|
|
uint32_t ui32MaxBitRate;
|
|
uint32_t ui32RegVal;
|
|
uint32_t ui32PreDiv;
|
|
uint32_t ui32SCR;
|
|
uint32_t ui32SPH_SPO;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(SSIBaseValid(ui32Base));
|
|
ASSERT((ui32Protocol == SSI_FRF_MOTO_MODE_0) ||
|
|
(ui32Protocol == SSI_FRF_MOTO_MODE_1) ||
|
|
(ui32Protocol == SSI_FRF_MOTO_MODE_2) ||
|
|
(ui32Protocol == SSI_FRF_MOTO_MODE_3) ||
|
|
(ui32Protocol == SSI_FRF_TI) ||
|
|
(ui32Protocol == SSI_FRF_NMW));
|
|
ASSERT((ui32Mode == SSI_MODE_MASTER) ||
|
|
(ui32Mode == SSI_MODE_SLAVE) ||
|
|
(ui32Mode == SSI_MODE_SLAVE_OD));
|
|
ASSERT(((ui32Mode == SSI_MODE_MASTER) && (ui32BitRate <= (ui32SSIClk / 2))) ||
|
|
((ui32Mode != SSI_MODE_MASTER) && (ui32BitRate <= (ui32SSIClk / 12))));
|
|
ASSERT((ui32SSIClk / ui32BitRate) <= (254 * 256));
|
|
ASSERT((ui32DataWidth >= 4) && (ui32DataWidth <= 16));
|
|
|
|
//
|
|
// Set the mode.
|
|
//
|
|
ui32RegVal = (ui32Mode == SSI_MODE_SLAVE_OD) ? SSI_CR1_SOD : 0;
|
|
ui32RegVal |= (ui32Mode == SSI_MODE_MASTER) ? 0 : SSI_CR1_MS;
|
|
HWREG(ui32Base + SSI_O_CR1) = ui32RegVal;
|
|
|
|
//
|
|
// Set the clock predivider.
|
|
//
|
|
ui32MaxBitRate = ui32SSIClk / ui32BitRate;
|
|
ui32PreDiv = 0;
|
|
do
|
|
{
|
|
ui32PreDiv += 2;
|
|
ui32SCR = (ui32MaxBitRate / ui32PreDiv) - 1;
|
|
}
|
|
while(ui32SCR > 255);
|
|
HWREG(ui32Base + SSI_O_CPSR) = ui32PreDiv;
|
|
|
|
//
|
|
// Set protocol and clock rate.
|
|
//
|
|
ui32SPH_SPO = (ui32Protocol & 3) << 6;
|
|
ui32Protocol &= SSI_CR0_FRF_M;
|
|
ui32RegVal = (ui32SCR << 8) | ui32SPH_SPO | ui32Protocol | (ui32DataWidth - 1);
|
|
HWREG(ui32Base + SSI_O_CR0) = ui32RegVal;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Puts a data element into the SSI transmit FIFO
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
SSIDataPut(uint32_t ui32Base, uint32_t ui32Data)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(SSIBaseValid(ui32Base));
|
|
ASSERT((ui32Data & (0xfffffffe << (HWREG(ui32Base + SSI_O_CR0) &
|
|
SSI_CR0_DSS_M))) == 0);
|
|
|
|
//
|
|
// Wait until there is space.
|
|
//
|
|
while(!(HWREG(ui32Base + SSI_O_SR) & SSI_SR_TNF))
|
|
{
|
|
}
|
|
|
|
//
|
|
// Write the data to the SSI.
|
|
//
|
|
HWREG(ui32Base + SSI_O_DR) = ui32Data;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Puts a data element into the SSI transmit FIFO
|
|
//
|
|
//*****************************************************************************
|
|
int32_t
|
|
SSIDataPutNonBlocking(uint32_t ui32Base, uint32_t ui32Data)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(SSIBaseValid(ui32Base));
|
|
ASSERT((ui32Data & (0xfffffffe << (HWREG(ui32Base + SSI_O_CR0) &
|
|
SSI_CR0_DSS_M))) == 0);
|
|
|
|
//
|
|
// Check for space to write.
|
|
//
|
|
if(HWREG(ui32Base + SSI_O_SR) & SSI_SR_TNF)
|
|
{
|
|
HWREG(ui32Base + SSI_O_DR) = ui32Data;
|
|
return(1);
|
|
}
|
|
else
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets a data element from the SSI receive FIFO
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
SSIDataGet(uint32_t ui32Base, uint32_t *pui32Data)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(SSIBaseValid(ui32Base));
|
|
|
|
//
|
|
// Wait until there is data to be read.
|
|
//
|
|
while(!(HWREG(ui32Base + SSI_O_SR) & SSI_SR_RNE))
|
|
{
|
|
}
|
|
|
|
//
|
|
// Read data from SSI.
|
|
//
|
|
*pui32Data = HWREG(ui32Base + SSI_O_DR);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets a data element from the SSI receive FIFO
|
|
//!
|
|
//! \param ui32Base specifies the SSI module base address.
|
|
//! \param pui32Data is a pointer to a storage location for data that was
|
|
//! received over the SSI interface.
|
|
//!
|
|
//! This function gets received data from the receive FIFO of the specified SSI
|
|
//! module and places that data into the location specified by the \e ui32Data
|
|
//! parameter. If there is no data in the FIFO, then this function returns a
|
|
//! zero.
|
|
//!
|
|
//! \note Only the lower N bits of the value written to \e pui32Data contain
|
|
//! valid data, where N is the data width as configured by \sa
|
|
//! SSIConfigSetExpClk(). For example, if the interface is configured for
|
|
//! 8-bit data width, only the lower 8 bits of the value written to \e pui32Data
|
|
//! contain valid data.
|
|
//!
|
|
//! \return Returns the number of elements read from the SSI receive FIFO.
|
|
//
|
|
//*****************************************************************************
|
|
int32_t
|
|
SSIDataGetNonBlocking(uint32_t ui32Base, uint32_t *pui32Data)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(SSIBaseValid(ui32Base));
|
|
|
|
//
|
|
// Check for data to read.
|
|
//
|
|
if(HWREG(ui32Base + SSI_O_SR) & SSI_SR_RNE)
|
|
{
|
|
*pui32Data = HWREG(ui32Base + SSI_O_DR);
|
|
return(1);
|
|
}
|
|
else
|
|
{
|
|
return(0);
|
|
}
|
|
}
|
|
//! @}
|
|
//! \\addtogroup timer_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Configures the timer(s)
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
TimerConfigure(uint32_t ui32Base, uint32_t ui32Config)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(TimerBaseValid(ui32Base));
|
|
ASSERT((ui32Config == TIMER_CFG_ONE_SHOT) ||
|
|
(ui32Config == TIMER_CFG_ONE_SHOT_UP) ||
|
|
(ui32Config == TIMER_CFG_PERIODIC) ||
|
|
(ui32Config == TIMER_CFG_PERIODIC_UP) ||
|
|
(ui32Config == TIMER_CFG_RTC) ||
|
|
((ui32Config & 0xFF000000) == TIMER_CFG_SPLIT_PAIR));
|
|
ASSERT(((ui32Config & 0xFF000000) != TIMER_CFG_SPLIT_PAIR) ||
|
|
((((ui32Config & 0x000000FF) == TIMER_CFG_A_ONE_SHOT) ||
|
|
((ui32Config & 0x000000FF) == TIMER_CFG_A_ONE_SHOT_UP) ||
|
|
((ui32Config & 0x000000FF) == TIMER_CFG_A_PERIODIC) ||
|
|
((ui32Config & 0x000000FF) == TIMER_CFG_A_PERIODIC_UP) ||
|
|
((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_COUNT) ||
|
|
((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_COUNT_UP) ||
|
|
((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_TIME) ||
|
|
((ui32Config & 0x000000FF) == TIMER_CFG_A_CAP_TIME_UP) ||
|
|
((ui32Config & 0x000000FF) == TIMER_CFG_A_PWM)) &&
|
|
(((ui32Config & 0x0000FF00) == TIMER_CFG_B_ONE_SHOT) ||
|
|
((ui32Config & 0x0000FF00) == TIMER_CFG_B_ONE_SHOT_UP) ||
|
|
((ui32Config & 0x0000FF00) == TIMER_CFG_B_PERIODIC) ||
|
|
((ui32Config & 0x0000FF00) == TIMER_CFG_B_PERIODIC_UP) ||
|
|
((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_COUNT) ||
|
|
((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_COUNT_UP) ||
|
|
((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_TIME) ||
|
|
((ui32Config & 0x0000FF00) == TIMER_CFG_B_CAP_TIME_UP) ||
|
|
((ui32Config & 0x0000FF00) == TIMER_CFG_B_PWM))));
|
|
|
|
//
|
|
// Disable the timers.
|
|
//
|
|
HWREG(ui32Base + GPT_O_CTL) &= ~(GPT_CTL_TAEN | GPT_CTL_TBEN);
|
|
|
|
//
|
|
// Set the global timer configuration.
|
|
//
|
|
HWREG(ui32Base + GPT_O_CFG) = ui32Config >> 24;
|
|
|
|
//
|
|
// Set the configuration of the A and B timers. Note that the B timer
|
|
// configuration is ignored by the hardware in 32-bit modes.
|
|
//
|
|
HWREG(ui32Base + GPT_O_TAMR) = (ui32Config & 0xFF) | GPT_TAMR_TAPWMIE;
|
|
HWREG(ui32Base + GPT_O_TBMR) =
|
|
((ui32Config >> 8) & 0xFF) | GPT_TBMR_TBPWMIE;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Controls the output level
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
TimerLevelControl(uint32_t ui32Base, uint32_t ui32Timer, bool bInvert)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(TimerBaseValid(ui32Base));
|
|
ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
|
|
(ui32Timer == TIMER_BOTH));
|
|
|
|
//
|
|
// Set the output levels as requested.
|
|
//
|
|
ui32Timer &= GPT_CTL_TAPWML | GPT_CTL_TBPWML;
|
|
HWREG(ui32Base + GPT_O_CTL) = (bInvert ?
|
|
(HWREG(ui32Base + GPT_O_CTL) | ui32Timer) :
|
|
(HWREG(ui32Base + GPT_O_CTL) &
|
|
~(ui32Timer)));
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Enables or disables the ADC trigger output
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
TimerTriggerControl(uint32_t ui32Base, uint32_t ui32Timer, bool bEnable)
|
|
{
|
|
uint32_t ui32Val;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(TimerBaseValid(ui32Base));
|
|
ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
|
|
(ui32Timer == TIMER_BOTH));
|
|
|
|
//
|
|
// Determine which bits to set or clear in GPTM_ADCEV.
|
|
//
|
|
ui32Val = (GPT_ADCEV_TATOADCEN | GPT_ADCEV_TBTOADCEN);
|
|
ui32Val &= ui32Timer;
|
|
|
|
//
|
|
// Write the GPTM ADC Event register to enable or disable the trigger.
|
|
// to the ADC.
|
|
//
|
|
HWREG(ui32Base + GPT_O_ADCEV) = (bEnable ?
|
|
(HWREG(ui32Base + GPT_O_ADCEV) | ui32Val) :
|
|
(HWREG(ui32Base + GPT_O_ADCEV) &
|
|
~(ui32Val)));
|
|
|
|
//
|
|
// Set the trigger output as requested.
|
|
// Set the ADC trigger output as requested.
|
|
//
|
|
ui32Timer &= GPT_CTL_TAOTE | GPT_CTL_TBOTE;
|
|
HWREG(ui32Base + GPT_O_CTL) = (bEnable ?
|
|
(HWREG(ui32Base + GPT_O_CTL) | ui32Timer) :
|
|
(HWREG(ui32Base + GPT_O_CTL) &
|
|
~(ui32Timer)));
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Controls the stall handling
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
TimerStallControl(uint32_t ui32Base, uint32_t ui32Timer, bool bStall)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(TimerBaseValid(ui32Base));
|
|
ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
|
|
(ui32Timer == TIMER_BOTH));
|
|
|
|
//
|
|
// Set the stall mode.
|
|
//
|
|
ui32Timer &= GPT_CTL_TASTALL | GPT_CTL_TBSTALL;
|
|
HWREG(ui32Base + GPT_O_CTL) = (bStall ?
|
|
(HWREG(ui32Base + GPT_O_CTL) | ui32Timer) :
|
|
(HWREG(ui32Base + GPT_O_CTL) & ~(ui32Timer)));
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Controls the wait on trigger handling
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
TimerWaitOnTriggerControl(uint32_t ui32Base, uint32_t ui32Timer, bool bWait)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(TimerBaseValid(ui32Base));
|
|
ASSERT((ui32Timer == TIMER_A) || (ui32Timer == TIMER_B) ||
|
|
(ui32Timer == TIMER_BOTH));
|
|
|
|
//
|
|
// Set the wait on trigger mode for timer A.
|
|
//
|
|
if(ui32Timer & TIMER_A)
|
|
{
|
|
if(bWait)
|
|
{
|
|
HWREG(ui32Base + GPT_O_TAMR) |= GPT_TAMR_TAWOT;
|
|
}
|
|
else
|
|
{
|
|
HWREG(ui32Base + GPT_O_TAMR) &= ~(GPT_TAMR_TAWOT);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the wait on trigger mode for timer B.
|
|
//
|
|
if(ui32Timer & TIMER_B)
|
|
{
|
|
if(bWait)
|
|
{
|
|
HWREG(ui32Base + GPT_O_TBMR) |= GPT_TBMR_TBWOT;
|
|
}
|
|
else
|
|
{
|
|
HWREG(ui32Base + GPT_O_TBMR) &= ~(GPT_TBMR_TBWOT);
|
|
}
|
|
}
|
|
}
|
|
//! @}
|
|
//! \\addtogroup trng_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Configure the true random number generator
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
TRNGConfigure(uint32_t ui32MinSamplesPerCycle,
|
|
uint32_t ui32MaxSamplesPerCycle,
|
|
uint32_t ui32ClocksPerSample)
|
|
{
|
|
uint32_t ui32Val;
|
|
|
|
//
|
|
// Make sure the TRNG is disabled.
|
|
//
|
|
ui32Val = HWREG(TRNG_BASE + TRNG_O_CTL) & ~TRNG_CTL_TRNG_EN;
|
|
HWREG(TRNG_BASE + TRNG_O_CTL) = ui32Val;
|
|
|
|
//
|
|
// Configure the startup number of samples.
|
|
//
|
|
ui32Val &= ~TRNG_CTL_STARTUP_CYCLES_M;
|
|
ui32Val |= ((ui32MaxSamplesPerCycle >> 8) & 0xFFFF) << 16;
|
|
HWREG(TRNG_BASE + TRNG_O_CTL) = ui32Val;
|
|
|
|
//
|
|
// Configure the minimum and maximum number of samples pr generated number
|
|
// and the number of clocks per sample.
|
|
//
|
|
HWREG(TRNG_BASE + TRNG_O_CFG0) =
|
|
(((ui32MaxSamplesPerCycle >> 8) & 0xFFFF) << 16) |
|
|
((ui32ClocksPerSample & 0xFF) << 8) |
|
|
((ui32MinSamplesPerCycle >> 6) & 0xFF);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get a random number from the generator
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
TRNGNumberGet(uint32_t ui32Word)
|
|
{
|
|
uint32_t ui32RandomNumber;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT((ui32Word == TRNG_HI_WORD) ||
|
|
(ui32Word == TRNG_LOW_WORD));
|
|
|
|
//
|
|
// Return the right requested part of the generated number.
|
|
//
|
|
if(ui32Word == TRNG_HI_WORD)
|
|
{
|
|
ui32RandomNumber = HWREG(TRNG_BASE + TRNG_O_OUT1);
|
|
}
|
|
else
|
|
{
|
|
ui32RandomNumber = HWREG(TRNG_BASE + TRNG_O_OUT0);
|
|
}
|
|
|
|
//
|
|
// Initiate generation of new number.
|
|
//
|
|
HWREG(TRNG_BASE + TRNG_O_IRQFLAGCLR) = 0x1;
|
|
|
|
//
|
|
// Return the random number.
|
|
//
|
|
return ui32RandomNumber;
|
|
}
|
|
//! @}
|
|
//! \\addtogroup uart_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets the FIFO level at which interrupts are generated
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
UARTFIFOLevelGet(uint32_t ui32Base, uint32_t *pui32TxLevel,
|
|
uint32_t *pui32RxLevel)
|
|
{
|
|
uint32_t ui32Temp;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(UARTBaseValid(ui32Base));
|
|
|
|
//
|
|
// Read the FIFO level register.
|
|
//
|
|
ui32Temp = HWREG(ui32Base + UART_O_IFLS);
|
|
|
|
//
|
|
// Extract the transmit and receive FIFO levels.
|
|
//
|
|
*pui32TxLevel = ui32Temp & UART_IFLS_TXSEL_M;
|
|
*pui32RxLevel = ui32Temp & UART_IFLS_RXSEL_M;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the configuration of a UART
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
UARTConfigSetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk,
|
|
uint32_t ui32Baud, uint32_t ui32Config)
|
|
{
|
|
uint32_t ui32Div;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(UARTBaseValid(ui32Base));
|
|
ASSERT(ui32Baud != 0);
|
|
|
|
//
|
|
// Stop the UART.
|
|
//
|
|
UARTDisable(ui32Base);
|
|
|
|
//
|
|
// Compute the fractional baud rate divider.
|
|
//
|
|
ui32Div = (((ui32UARTClk * 8) / ui32Baud) + 1) / 2;
|
|
|
|
//
|
|
// Set the baud rate.
|
|
//
|
|
HWREG(ui32Base + UART_O_IBRD) = ui32Div / 64;
|
|
HWREG(ui32Base + UART_O_FBRD) = ui32Div % 64;
|
|
|
|
//
|
|
// Set parity, data length, and number of stop bits.
|
|
//
|
|
HWREG(ui32Base + UART_O_LCRH) = ui32Config;
|
|
|
|
//
|
|
// Clear the flags register.
|
|
//
|
|
HWREG(ui32Base + UART_O_FR) = 0;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets the current configuration of a UART
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
UARTConfigGetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk,
|
|
uint32_t *pui32Baud, uint32_t *pui32Config)
|
|
{
|
|
uint32_t ui32Int, ui32Frac;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(UARTBaseValid(ui32Base));
|
|
|
|
//
|
|
// Compute the baud rate.
|
|
//
|
|
ui32Int = HWREG(ui32Base + UART_O_IBRD);
|
|
ui32Frac = HWREG(ui32Base + UART_O_FBRD);
|
|
*pui32Baud = (ui32UARTClk * 4) / ((64 * ui32Int) + ui32Frac);
|
|
|
|
//
|
|
// Get the parity, data length, and number of stop bits.
|
|
//
|
|
*pui32Config = (HWREG(ui32Base + UART_O_LCRH) &
|
|
(UART_LCRH_SPS | UART_LCRH_WLEN_M | UART_LCRH_STP2 |
|
|
UART_LCRH_EPS | UART_LCRH_PEN));
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Disables transmitting and receiving
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
UARTDisable(uint32_t ui32Base)
|
|
{
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(UARTBaseValid(ui32Base));
|
|
|
|
//
|
|
// Wait for end of TX.
|
|
//
|
|
while(HWREG(ui32Base + UART_O_FR) & UART_FR_BUSY)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Disable the FIFO.
|
|
//
|
|
HWREG(ui32Base + UART_O_LCRH) &= ~(UART_LCRH_FEN);
|
|
|
|
//
|
|
// Disable the UART.
|
|
//
|
|
HWREG(ui32Base + UART_O_CTL) &= ~(UART_CTL_UARTEN | UART_CTL_TXE |
|
|
UART_CTL_RXE);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Receives a character from the specified port
|
|
//
|
|
//*****************************************************************************
|
|
int32_t
|
|
UARTCharGetNonBlocking(uint32_t ui32Base)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(UARTBaseValid(ui32Base));
|
|
|
|
//
|
|
// See if there are any characters in the receive FIFO.
|
|
//
|
|
if(!(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE))
|
|
{
|
|
//
|
|
// Read and return the next character.
|
|
//
|
|
return(HWREG(ui32Base + UART_O_DR));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// There are no characters, so return a failure.
|
|
//
|
|
return(-1);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Waits for a character from the specified port
|
|
//
|
|
//*****************************************************************************
|
|
int32_t
|
|
UARTCharGet(uint32_t ui32Base)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(UARTBaseValid(ui32Base));
|
|
|
|
//
|
|
// Wait until a char is available.
|
|
//
|
|
while(HWREG(ui32Base + UART_O_FR) & UART_FR_RXFE)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Now get the character.
|
|
//
|
|
return(HWREG(ui32Base + UART_O_DR));
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Sends a character to the specified port
|
|
//
|
|
//*****************************************************************************
|
|
bool
|
|
UARTCharPutNonBlocking(uint32_t ui32Base, uint8_t ui8Data)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(UARTBaseValid(ui32Base));
|
|
|
|
//
|
|
// See if there is space in the transmit FIFO.
|
|
//
|
|
if(!(HWREG(ui32Base + UART_O_FR) & UART_FR_TXFF))
|
|
{
|
|
//
|
|
// Write this character to the transmit FIFO.
|
|
//
|
|
HWREG(ui32Base + UART_O_DR) = ui8Data;
|
|
|
|
//
|
|
// Success.
|
|
//
|
|
return(true);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// There is no space in the transmit FIFO, so return a failure.
|
|
//
|
|
return(false);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Waits to send a character from the specified port
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
UARTCharPut(uint32_t ui32Base, uint8_t ui8Data)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(UARTBaseValid(ui32Base));
|
|
|
|
//
|
|
// Wait until space is available.
|
|
//
|
|
while(HWREG(ui32Base + UART_O_FR) & UART_FR_TXFF)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Send the char.
|
|
//
|
|
HWREG(ui32Base + UART_O_DR) = ui8Data;
|
|
}
|
|
//! @}
|
|
//! \\addtogroup udma_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Enables attributes of a uDMA channel
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
uDMAChannelAttributeEnable(uint32_t ui32Base, uint32_t ui32ChannelNum,
|
|
uint32_t ui32Attr)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(uDMABaseValid(ui32Base));
|
|
ASSERT(ui32ChannelNum < UDMA_NUM_CHANNELS);
|
|
ASSERT((ui32Attr & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
|
|
UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)) == 0);
|
|
|
|
//
|
|
// Set the useburst bit for this channel if set in ui32Attr.
|
|
//
|
|
if(ui32Attr & UDMA_ATTR_USEBURST)
|
|
{
|
|
HWREG(ui32Base + UDMA_O_SETBURST) = 1 << ui32ChannelNum;
|
|
}
|
|
|
|
//
|
|
// Set the alternate control select bit for this channel,
|
|
// if set in ui32Attr.
|
|
//
|
|
if(ui32Attr & UDMA_ATTR_ALTSELECT)
|
|
{
|
|
HWREG(ui32Base + UDMA_O_SETCHNLPRIALT) = 1 << ui32ChannelNum;
|
|
}
|
|
|
|
//
|
|
// Set the high priority bit for this channel, if set in ui32Attr.
|
|
//
|
|
if(ui32Attr & UDMA_ATTR_HIGH_PRIORITY)
|
|
{
|
|
HWREG(ui32Base + UDMA_O_SETCHNLPRIORITY) = 1 << ui32ChannelNum;
|
|
}
|
|
|
|
//
|
|
// Set the request mask bit for this channel, if set in ui32Attr.
|
|
//
|
|
if(ui32Attr & UDMA_ATTR_REQMASK)
|
|
{
|
|
HWREG(ui32Base + UDMA_O_SETREQMASK) = 1 << ui32ChannelNum;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Disables attributes of an uDMA channel
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
uDMAChannelAttributeDisable(uint32_t ui32Base, uint32_t ui32ChannelNum,
|
|
uint32_t ui32Attr)
|
|
{
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(uDMABaseValid(ui32Base));
|
|
ASSERT(ui32ChannelNum < UDMA_NUM_CHANNELS);
|
|
ASSERT((ui32Attr & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
|
|
UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)) == 0);
|
|
|
|
//
|
|
// Clear the useburst bit for this channel if set in ui32Attr.
|
|
//
|
|
if(ui32Attr & UDMA_ATTR_USEBURST)
|
|
{
|
|
HWREG(ui32Base + UDMA_O_CLEARBURST) = 1 << ui32ChannelNum;
|
|
}
|
|
|
|
//
|
|
// Clear the alternate control select bit for this channel, if set in
|
|
// ululAttr.
|
|
//
|
|
if(ui32Attr & UDMA_ATTR_ALTSELECT)
|
|
{
|
|
HWREG(ui32Base + UDMA_O_CLEARCHNLPRIALT) = 1 << ui32ChannelNum;
|
|
}
|
|
|
|
//
|
|
// Clear the high priority bit for this channel, if set in ui32Attr.
|
|
//
|
|
if(ui32Attr & UDMA_ATTR_HIGH_PRIORITY)
|
|
{
|
|
HWREG(ui32Base + UDMA_O_CLEARCHNLPRIORITY) = 1 << ui32ChannelNum;
|
|
}
|
|
|
|
//
|
|
// Clear the request mask bit for this channel, if set in ui32Attr.
|
|
//
|
|
if(ui32Attr & UDMA_ATTR_REQMASK)
|
|
{
|
|
HWREG(ui32Base + UDMA_O_CLEARREQMASK) = 1 << ui32ChannelNum;
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets the enabled attributes of a uDMA channel
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
uDMAChannelAttributeGet(uint32_t ui32Base, uint32_t ui32ChannelNum)
|
|
{
|
|
uint32_t ui32Attr = 0;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(uDMABaseValid(ui32Base));
|
|
ASSERT(ui32ChannelNum < UDMA_NUM_CHANNELS);
|
|
|
|
//
|
|
// Check to see if useburst bit is set for this channel.
|
|
//
|
|
if(HWREG(ui32Base + UDMA_O_SETBURST) & (1 << ui32ChannelNum))
|
|
{
|
|
ui32Attr |= UDMA_ATTR_USEBURST;
|
|
}
|
|
|
|
//
|
|
// Check to see if the alternate control bit is set for this channel.
|
|
//
|
|
if(HWREG(ui32Base + UDMA_O_SETCHNLPRIALT) & (1 << ui32ChannelNum))
|
|
{
|
|
ui32Attr |= UDMA_ATTR_ALTSELECT;
|
|
}
|
|
|
|
//
|
|
// Check to see if the high priority bit is set for this channel.
|
|
//
|
|
if(HWREG(ui32Base + UDMA_O_SETCHNLPRIORITY) & (1 << ui32ChannelNum))
|
|
{
|
|
ui32Attr |= UDMA_ATTR_HIGH_PRIORITY;
|
|
}
|
|
|
|
//
|
|
// Check to see if the request mask bit is set for this channel.
|
|
//
|
|
if(HWREG(ui32Base + UDMA_O_SETREQMASK) & (1 << ui32ChannelNum))
|
|
{
|
|
ui32Attr |= UDMA_ATTR_REQMASK;
|
|
}
|
|
|
|
//
|
|
// Return the configuration flags.
|
|
//
|
|
return(ui32Attr);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the control parameters for a uDMA channel control structure
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
uDMAChannelControlSet(uint32_t ui32Base, uint32_t ui32ChannelStructIndex,
|
|
uint32_t ui32Control)
|
|
{
|
|
tDMAControlTable *pControlTable;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(uDMABaseValid(ui32Base));
|
|
ASSERT(ui32ChannelStructIndex < (UDMA_NUM_CHANNELS * 2));
|
|
ASSERT(HWREG(ui32Base + UDMA_O_CTRL) != 0);
|
|
|
|
//
|
|
// Get the base address of the control table.
|
|
//
|
|
pControlTable = (tDMAControlTable *)HWREG(ui32Base + UDMA_O_CTRL);
|
|
|
|
//
|
|
// Get the current control word value and mask off the fields to be
|
|
// changed, then OR in the new settings.
|
|
//
|
|
pControlTable[ui32ChannelStructIndex].ui32Control =
|
|
((pControlTable[ui32ChannelStructIndex].ui32Control &
|
|
~(UDMA_DST_INC_M |
|
|
UDMA_SRC_INC_M |
|
|
UDMA_SIZE_M |
|
|
UDMA_ARB_M |
|
|
UDMA_NEXT_USEBURST)) |
|
|
ui32Control);
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets the transfer parameters for a uDMA channel control structure
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
uDMAChannelTransferSet(uint32_t ui32Base, uint32_t ui32ChannelStructIndex,
|
|
uint32_t ui32Mode, void *pvSrcAddr, void *pvDstAddr,
|
|
uint32_t ui32TransferSize)
|
|
{
|
|
tDMAControlTable *pControlTable;
|
|
uint32_t ui32Control;
|
|
uint32_t ui32Inc;
|
|
uint32_t ui32BufferBytes;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(uDMABaseValid(ui32Base));
|
|
ASSERT(ui32ChannelStructIndex < (UDMA_NUM_CHANNELS * 2));
|
|
ASSERT(HWREG(ui32Base + UDMA_O_CTRL) != 0);
|
|
ASSERT(ui32Mode <= UDMA_MODE_PER_SCATTER_GATHER);
|
|
ASSERT((uint32_t)pvSrcAddr >= SRAM_BASE);
|
|
ASSERT((uint32_t)pvDstAddr >= SRAM_BASE);
|
|
ASSERT((ui32TransferSize != 0) && (ui32TransferSize <= UDMA_XFER_SIZE_MAX));
|
|
|
|
//
|
|
// Get the base address of the control table.
|
|
//
|
|
pControlTable = (tDMAControlTable *)HWREG(ui32Base + UDMA_O_CTRL);
|
|
|
|
//
|
|
// Get the current control word value and mask off the mode and size
|
|
// fields.
|
|
//
|
|
ui32Control = (pControlTable[ui32ChannelStructIndex].ui32Control &
|
|
~(UDMA_XFER_SIZE_M | UDMA_MODE_M));
|
|
|
|
//
|
|
// Adjust the mode if the alt control structure is selected.
|
|
//
|
|
if(ui32ChannelStructIndex & UDMA_ALT_SELECT)
|
|
{
|
|
if((ui32Mode == UDMA_MODE_MEM_SCATTER_GATHER) ||
|
|
(ui32Mode == UDMA_MODE_PER_SCATTER_GATHER))
|
|
{
|
|
ui32Mode |= UDMA_MODE_ALT_SELECT;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the transfer size and mode in the control word (but don't write the
|
|
// control word yet as it could kick off a transfer).
|
|
//
|
|
ui32Control |= ui32Mode | ((ui32TransferSize - 1) << UDMA_XFER_SIZE_S);
|
|
|
|
//
|
|
// Get the address increment value for the source, from the control word.
|
|
//
|
|
ui32Inc = (ui32Control & UDMA_SRC_INC_M);
|
|
|
|
//
|
|
// Compute the ending source address of the transfer. If the source
|
|
// increment is set to none, then the ending address is the same as the
|
|
// beginning.
|
|
//
|
|
if(ui32Inc != UDMA_SRC_INC_NONE)
|
|
{
|
|
ui32Inc = ui32Inc >> UDMA_SRC_INC_S;
|
|
ui32BufferBytes = ui32TransferSize << ui32Inc;
|
|
pvSrcAddr = (void *)((uint32_t)pvSrcAddr + ui32BufferBytes - 1);
|
|
}
|
|
|
|
//
|
|
// Load the source ending address into the control block.
|
|
//
|
|
pControlTable[ui32ChannelStructIndex].pvSrcEndAddr = pvSrcAddr;
|
|
|
|
//
|
|
// Get the address increment value for the destination, from the control
|
|
// word.
|
|
//
|
|
ui32Inc = ui32Control & UDMA_DST_INC_M;
|
|
|
|
//
|
|
// Compute the ending destination address of the transfer. If the
|
|
// destination increment is set to none, then the ending address is the
|
|
// same as the beginning.
|
|
//
|
|
if(ui32Inc != UDMA_DST_INC_NONE)
|
|
{
|
|
//
|
|
// There is a special case if this is setting up a scatter-gather
|
|
// transfer. The destination pointer needs to point to the end of
|
|
// the alternate structure for this channel instead of calculating
|
|
// the end of the buffer in the normal way.
|
|
//
|
|
if((ui32Mode == UDMA_MODE_MEM_SCATTER_GATHER) ||
|
|
(ui32Mode == UDMA_MODE_PER_SCATTER_GATHER))
|
|
{
|
|
pvDstAddr =
|
|
(void *)&pControlTable[ui32ChannelStructIndex |
|
|
UDMA_ALT_SELECT].ui32Spare;
|
|
}
|
|
//
|
|
// Not a scatter-gather transfer, calculate end pointer normally.
|
|
//
|
|
else
|
|
{
|
|
ui32Inc = ui32Inc >> UDMA_DST_INC_S;
|
|
ui32BufferBytes = ui32TransferSize << ui32Inc;
|
|
pvDstAddr = (void *)((uint32_t)pvDstAddr + ui32BufferBytes - 1);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Load the destination ending address into the control block.
|
|
//
|
|
pControlTable[ui32ChannelStructIndex].pvDstEndAddr = pvDstAddr;
|
|
|
|
//
|
|
// Write the new control word value.
|
|
//
|
|
pControlTable[ui32ChannelStructIndex].ui32Control = ui32Control;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Configures a uDMA channel for scatter-gather mode
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
uDMAChannelScatterGatherSet(uint32_t ui32Base, uint32_t ui32ChannelNum,
|
|
uint32_t ui32TaskCount, void *pvTaskList,
|
|
uint32_t ui32IsPeriphSG)
|
|
{
|
|
tDMAControlTable *pControlTable;
|
|
tDMAControlTable *pTaskTable;
|
|
|
|
//
|
|
// Check the parameters.
|
|
//
|
|
ASSERT(uDMABaseValid(ui32Base));
|
|
ASSERT(ui32ChannelNum < UDMA_NUM_CHANNELS);
|
|
ASSERT(HWREG(ui32Base + UDMA_O_CTRL) != 0);
|
|
ASSERT(pvTaskList != 0);
|
|
ASSERT(ui32TaskCount <= UDMA_XFER_SIZE_MAX);
|
|
ASSERT(ui32TaskCount != 0);
|
|
|
|
//
|
|
// Get the base address of the control table.
|
|
//
|
|
pControlTable = (tDMAControlTable *)HWREG(ui32Base + UDMA_O_CTRL);
|
|
|
|
//
|
|
// Get a handy pointer to the task list.
|
|
//
|
|
pTaskTable = (tDMAControlTable *)pvTaskList;
|
|
|
|
//
|
|
// Compute the ending address for the source pointer. This will be the
|
|
// last element of the last task in the task table.
|
|
//
|
|
pControlTable[ui32ChannelNum].pvSrcEndAddr =
|
|
&pTaskTable[ui32TaskCount - 1].ui32Spare;
|
|
|
|
//
|
|
// Compute the ending address for the destination pointer. This will be
|
|
// the end of the alternate structure for this channel.
|
|
//
|
|
pControlTable[ui32ChannelNum].pvDstEndAddr =
|
|
&pControlTable[ui32ChannelNum | UDMA_ALT_SELECT].ui32Spare;
|
|
|
|
//
|
|
// Compute the control word. Most configurable items are fixed for
|
|
// scatter-gather. Item and increment sizes are all 32-bit and arb
|
|
// size must be 4. The count is the number of items in the task list
|
|
// times 4 (4 words per task).
|
|
//
|
|
pControlTable[ui32ChannelNum].ui32Control =
|
|
(UDMA_DST_INC_32 | UDMA_SRC_INC_32 |
|
|
UDMA_SIZE_32 | UDMA_ARB_4 |
|
|
(((ui32TaskCount * 4) - 1) << UDMA_XFER_SIZE_S) |
|
|
(ui32IsPeriphSG ? UDMA_MODE_PER_SCATTER_GATHER :
|
|
UDMA_MODE_MEM_SCATTER_GATHER));
|
|
|
|
//
|
|
// Scatter-gather operations can leave the alt bit set. So if doing
|
|
// back to back scatter-gather transfers, the second attempt may not
|
|
// work correctly because the alt bit is set. Therefore, clear the
|
|
// alt bit here to ensure that it is always cleared before a new SG
|
|
// transfer is started.
|
|
//
|
|
HWREG(ui32Base + UDMA_O_CLEARCHNLPRIORITY) = 1 << ui32ChannelNum;
|
|
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets the current transfer size for a uDMA channel control structure
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
uDMAChannelSizeGet(uint32_t ui32Base, uint32_t ui32ChannelStructIndex)
|
|
{
|
|
tDMAControlTable *pControlTable;
|
|
uint32_t ui32Control;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(uDMABaseValid(ui32Base));
|
|
ASSERT(ui32ChannelStructIndex < (UDMA_NUM_CHANNELS * 2));
|
|
ASSERT(HWREG(ui32Base + UDMA_O_CTRL) != 0);
|
|
|
|
//
|
|
// Get the base address of the control table.
|
|
//
|
|
pControlTable = (tDMAControlTable *)HWREG(ui32Base + UDMA_O_CTRL);
|
|
|
|
//
|
|
// Get the current control word value and mask off all but the size field
|
|
// and the mode field.
|
|
//
|
|
ui32Control = (pControlTable[ui32ChannelStructIndex].ui32Control &
|
|
(UDMA_XFER_SIZE_M | UDMA_MODE_M));
|
|
|
|
//
|
|
// If the size field and mode field are 0 then the transfer is finished
|
|
// and there are no more items to transfer.
|
|
//
|
|
if(ui32Control == 0)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
//
|
|
// Otherwise, if either the size field or more field is non-zero, then
|
|
// not all the items have been transferred.
|
|
//
|
|
else
|
|
{
|
|
//
|
|
// Shift the size field and add one, then return to user.
|
|
//
|
|
return((ui32Control >> UDMA_XFER_SIZE_S) + 1);
|
|
}
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Gets the transfer mode for a uDMA channel control structure
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
uDMAChannelModeGet(uint32_t ui32Base, uint32_t ui32ChannelStructIndex)
|
|
{
|
|
tDMAControlTable *pControlTable;
|
|
uint32_t ui32Control;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(uDMABaseValid(ui32Base));
|
|
ASSERT(ui32ChannelStructIndex < (UDMA_NUM_CHANNELS * 2));
|
|
ASSERT(HWREG(ui32Base + UDMA_O_CTRL) != 0);
|
|
|
|
//
|
|
// Get the base address of the control table.
|
|
//
|
|
pControlTable = (tDMAControlTable *)HWREG(ui32Base + UDMA_O_CTRL);
|
|
|
|
//
|
|
// Get the current control word value and mask off all but the mode field.
|
|
//
|
|
ui32Control = (pControlTable[ui32ChannelStructIndex].ui32Control &
|
|
UDMA_MODE_M);
|
|
|
|
//
|
|
// Check if scatter/gather mode, and if so, mask off the alt bit.
|
|
//
|
|
if(((ui32Control & ~UDMA_MODE_ALT_SELECT) == UDMA_MODE_MEM_SCATTER_GATHER) ||
|
|
((ui32Control & ~UDMA_MODE_ALT_SELECT) == UDMA_MODE_PER_SCATTER_GATHER))
|
|
{
|
|
ui32Control &= ~UDMA_MODE_ALT_SELECT;
|
|
}
|
|
|
|
//
|
|
// Return the mode to the caller.
|
|
//
|
|
return(ui32Control);
|
|
}
|
|
//! @}
|
|
//! \\addtogroup vims_api
|
|
//! @{
|
|
//*****************************************************************************
|
|
//
|
|
//! Configures the VIMS.
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
VIMSConfigure(uint32_t ui32Base, bool bRoundRobin, bool bPrefetch)
|
|
{
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(VIMSBaseValid(ui32Base));
|
|
|
|
ui32Reg = HWREG(ui32Base + VIMS_O_CTL);
|
|
ui32Reg &= ~(VIMS_CTL_PREF_EN | VIMS_CTL_ARB_CFG);
|
|
if(bRoundRobin)
|
|
{
|
|
ui32Reg |= VIMS_CTL_ARB_CFG;
|
|
}
|
|
if(bPrefetch)
|
|
{
|
|
ui32Reg |= VIMS_CTL_PREF_EN;
|
|
}
|
|
|
|
//
|
|
// Set the Arbitration and prefetch mode.
|
|
//
|
|
HWREG(ui32Base + VIMS_O_CTL) = ui32Reg;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Set the operational mode of the VIMS
|
|
//
|
|
//*****************************************************************************
|
|
void
|
|
VIMSModeSet(uint32_t ui32Base, uint32_t ui32Mode)
|
|
{
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(VIMSBaseValid(ui32Base));
|
|
|
|
ASSERT((ui32Mode == VIMS_MODE_INVALIDATE) ||
|
|
(ui32Mode == VIMS_MODE_DISABLED) ||
|
|
(ui32Mode == VIMS_MODE_ENABLED) ||
|
|
(ui32Mode == VIMS_MODE_OFF) ||
|
|
(ui32Mode == VIMS_MODE_SPLIT));
|
|
|
|
//
|
|
// Set the mode.
|
|
//
|
|
ui32Reg = HWREG(ui32Base + VIMS_O_CTL);
|
|
ui32Reg &= ~VIMS_CTL_MODE_M;
|
|
ui32Reg |= (ui32Mode & VIMS_CTL_MODE_M);
|
|
|
|
HWREG(ui32Base + VIMS_O_CTL) = ui32Reg;
|
|
}
|
|
//*****************************************************************************
|
|
//
|
|
//! Get the current operational mode of the VIMS.
|
|
//
|
|
//*****************************************************************************
|
|
uint32_t
|
|
VIMSModeGet(uint32_t ui32Base)
|
|
{
|
|
uint32_t ui32Reg;
|
|
|
|
//
|
|
// Check the arguments.
|
|
//
|
|
ASSERT(VIMSBaseValid(ui32Base));
|
|
|
|
ui32Reg = HWREG(ui32Base + VIMS_O_STAT);
|
|
if(ui32Reg & VIMS_STAT_INV)
|
|
{
|
|
return (VIMS_MODE_INVALIDATE);
|
|
}
|
|
else
|
|
{
|
|
return (ui32Reg & VIMS_STAT_MODE_M);
|
|
}
|
|
}
|
|
//! @}
|