//##### 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); } } //! @}