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