//############################################################################# // // FILE: device.c // // TITLE: Device setup for examples. // //############################################################################# // // // $Copyright: // Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# // // Included Files // #include "device.h" #ifdef CMDTOOL #include "device_cmd.h" #endif //***************************************************************************** // // Function to initialize the device. Primarily initializes system control to a // known state by disabling the watchdog, setting up the SYSCLKOUT frequency, // and enabling the clocks to the peripherals. // //***************************************************************************** void Device_init(void) { // // Disable the watchdog // SysCtl_disableWatchdog(); #ifdef CMDTOOL CMD_init(); #endif #ifdef _FLASH #ifndef CMDTOOL // // Copy time critical code and flash setup code to RAM. This includes the // following functions: InitFlash(); // // The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart symbols // are created by the linker. Refer to the device .cmd file. // memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); #endif // // Call Flash Initialization to setup flash waitstates. This function must // reside in RAM. // Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, DEVICE_FLASH_WAITSTATES); #endif #ifdef CPU1 // // Verify the crystal frequency. // Note: This check can be removed if you are not using XTAL as the PLL // source // if( ((DEVICE_SETCLOCK_CFG & SYSCTL_OSCSRC_M) == SYSCTL_OSCSRC_XTAL) || ((DEVICE_SETCLOCK_CFG & SYSCTL_OSCSRC_M) == SYSCTL_OSCSRC_XTAL_SE)) { if(!Device_verifyXTAL(DEVICE_OSCSRC_FREQ / 1000000)) { // // The actual XTAL frequency does not match DEVICE_OSCSRC_FREQ!! // Please check the XTAL frequency used. // // By default, the Device_init function assumes 25MHz XTAL. // If a 20MHz crystal is used, please add a predefined symbol // "USE_20MHZ_XTAL" in your CCS project. // If a different XTAL is used, please update the DEVICE_SETCLOCK_CFG // macro accordingly. // // Note that the latest F2838x controlCARDs (Rev.B and later) have been // updated to use 25MHz XTAL by default. If you have an older 20MHz XTAL // controlCARD (E1, E2, or Rev.A), refer to the controlCARD // documentation on steps to reconfigure the controlCARD from 20MHz to // 25MHz. // ESTOP0; while(1); } } // // Set up PLL control and clock dividers // SysCtl_setClock(DEVICE_SETCLOCK_CFG); // // Make sure the LSPCLK divider is set to the default (divide by 4) // SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4); // // Set up AUXPLL control and clock dividers needed for CMCLK // SysCtl_setAuxClock(DEVICE_AUXSETCLOCK_CFG); // // Set up CMCLK to use AUXPLL as the clock source and set the // clock divider to 1. // SysCtl_setCMClk(SYSCTL_CMCLKOUT_DIV_1,SYSCTL_SOURCE_AUXPLL); // These asserts will check that the #defines for the clock rates in // device.h match the actual rates that have been configured. If they do // not match, check that the calculations of DEVICE_SYSCLK_FREQ, // DEVICE_LSPCLK_FREQ and DEVICE_AUXCLK_FREQ are accurate. Some // examples will not perform as expected if these are not correct. // ASSERT(SysCtl_getClock(DEVICE_OSCSRC_FREQ) == DEVICE_SYSCLK_FREQ); ASSERT(SysCtl_getLowSpeedClock(DEVICE_OSCSRC_FREQ) == DEVICE_LSPCLK_FREQ); ASSERT(SysCtl_getAuxClock(DEVICE_OSCSRC_FREQ) == DEVICE_AUXCLK_FREQ); #ifndef _FLASH // // Call Device_cal function when run using debugger // This function is called as part of the Boot code. The function is called // in the Device_init function since during debug time resets, the boot code // will not be executed and the gel script will reinitialize all the // registers and the calibrated values will be lost. // Sysctl_deviceCal is a wrapper function for Device_Cal // SysCtl_deviceCal(); #endif #endif // // Turn on all peripherals // Device_enableAllPeripherals(); Device_initGPIO(); } #ifdef CPU1 //***************************************************************************** // // Function to boot CPU2 // Available bootmodes : // - BOOTMODE_BOOT_TO_FLASH_SECTOR0 // - BOOTMODE_BOOT_TO_FLASH_SECTOR4 // - BOOTMODE_BOOT_TO_FLASH_SECTOR8 // - BOOTMODE_BOOT_TO_FLASH_SECTOR13 // - BOOTMODE_BOOT_TO_SECURE_FLASH_SECTOR0 // - BOOTMODE_BOOT_TO_SECURE_FLASH_SECTOR4 // - BOOTMODE_BOOT_TO_SECURE_FLASH_SECTOR8 // - BOOTMODE_BOOT_TO_SECURE_FLASH_SECTOR13 // - BOOTMODE_IPC_MSGRAM_COPY_BOOT_TO_M1RAM // - BOOTMODE_BOOT_TO_M0RAM // - BOOTMODE_BOOT_TO_USEROTP // // Note that while using BOOTMODE_IPC_MSGRAM_COPY_BOOT_TO_M1RAM, // BOOTMODE_IPC_MSGRAM_COPY_LENGTH_xxxW must be ORed with the bootmode parameter // // This function must be called after Device_init function // //***************************************************************************** void Device_bootCPU2(uint32_t bootmode) { // // Configure the CPU1TOCPU2IPCBOOTMODE register // IPC_setBootMode(IPC_CPU1_L_CPU2_R, (BOOT_KEY | CPU2_BOOT_FREQ_200MHZ | bootmode)); // // Set IPC Flag 0 // IPC_setFlagLtoR(IPC_CPU1_L_CPU2_R, IPC_FLAG0); // // Bring CPU2 out of reset. Wait for CPU2 to go out of reset. // SysCtl_controlCPU2Reset(SYSCTL_CORE_DEACTIVE); while(SysCtl_isCPU2Reset() == 0x1U); } //***************************************************************************** // // Function to boot CM // Available bootmodes : // - BOOTMODE_BOOT_TO_FLASH_SECTOR0 // - BOOTMODE_BOOT_TO_FLASH_SECTOR4 // - BOOTMODE_BOOT_TO_FLASH_SECTOR8 // - BOOTMODE_BOOT_TO_FLASH_SECTOR13 // - BOOTMODE_BOOT_TO_SECURE_FLASH_SECTOR0 // - BOOTMODE_BOOT_TO_SECURE_FLASH_SECTOR4 // - BOOTMODE_BOOT_TO_SECURE_FLASH_SECTOR8 // - BOOTMODE_BOOT_TO_SECURE_FLASH_SECTOR13 // - BOOTMODE_IPC_MSGRAM_COPY_BOOT_TO_S0RAM // - BOOTMODE_BOOT_TO_S0RAM // - BOOTMODE_BOOT_TO_USEROTP // // Note that while using BOOTMODE_IPC_MSGRAM_COPY_BOOT_TO_M1RAM, // BOOTMODE_IPC_MSGRAM_COPY_LENGTH_xxxW must be ORed with the bootmode parameter // // This function must be called after Device_init function // //***************************************************************************** void Device_bootCM(uint32_t bootmode) { // // Configure the CPU1TOCMIPCBOOTMODE register // IPC_setBootMode(IPC_CPU1_L_CM_R, (BOOT_KEY | CM_BOOT_FREQ_125MHZ | bootmode)); // // Set IPC Flag 0 // IPC_setFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG0); // // Bring CM out of reset. Wait for CM to go out of reset. // SysCtl_controlCMReset(SYSCTL_CORE_DEACTIVE); while(SysCtl_isCMReset() == 0x1U); } #endif //***************************************************************************** // // Function to turn on all peripherals, enabling reads and writes to the // peripherals' registers. // // Note that to reduce power, unused peripherals should be disabled. // //***************************************************************************** void Device_enableAllPeripherals(void) { SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLA1); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DMA); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER0); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER1); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER2); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CPUBGCRC); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLA1BGCRC); #ifdef CPU1 SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_HRCAL); #endif SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ERAD); #ifdef CPU1 SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EMIF1); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EMIF2); #endif SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM2); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM3); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM4); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM5); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM6); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM7); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM8); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM9); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM10); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM11); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM12); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM13); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM14); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM15); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM16); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP2); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP3); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP4); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP5); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP6); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP7); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP1); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP2); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP3); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD1); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD2); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIA); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIB); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIC); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCID); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIB); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIC); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPID); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_I2CA); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_I2CB); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANA); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANB); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCBSPA); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCBSPB); #ifdef CPU1 SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_USBA); #endif SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCA); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCB); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCC); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCD); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS1); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS2); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS3); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS4); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS5); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS6); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS7); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS8); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DACA); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DACB); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DACC); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB1); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB2); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB3); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB4); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB5); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB6); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB7); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLB8); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_FSITXA); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_FSITXB); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_FSIRXA); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_FSIRXB); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_FSIRXC); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_FSIRXD); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_FSIRXE); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_FSIRXF); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_FSIRXG); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_FSIRXH); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_PMBUSA); #ifdef CPU1 SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DCC0); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DCC1); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DCC2); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAT); SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCANA); #endif } //***************************************************************************** // // Function to disable pin locks on GPIOs. // //***************************************************************************** void Device_initGPIO(void) { // // Disable pin locks. // GPIO_unlockPortConfig(GPIO_PORT_A, 0xFFFFFFFF); GPIO_unlockPortConfig(GPIO_PORT_B, 0xFFFFFFFF); GPIO_unlockPortConfig(GPIO_PORT_C, 0xFFFFFFFF); GPIO_unlockPortConfig(GPIO_PORT_D, 0xFFFFFFFF); GPIO_unlockPortConfig(GPIO_PORT_E, 0xFFFFFFFF); GPIO_unlockPortConfig(GPIO_PORT_F, 0xFFFFFFFF); // // Enable GPIO Pullups // Device_enableUnbondedGPIOPullups(); } //***************************************************************************** // // Function to enable pullups for the unbonded GPIOs on the 176PTP package: // GPIOs Grp Bits // 95-132 C 31 // D 31:0 // E 4:0 // 134-168 E 31:6 // F 8:0 // //***************************************************************************** void Device_enableUnbondedGPIOPullupsFor176Pin(void) { EALLOW; HWREG(GPIOCTRL_BASE + GPIO_O_GPCPUD) = ~0x80000000U; HWREG(GPIOCTRL_BASE + GPIO_O_GPDPUD) = ~0xFFFFFFF7U; HWREG(GPIOCTRL_BASE + GPIO_O_GPEPUD) = ~0xFFFFFFDFU; HWREG(GPIOCTRL_BASE + GPIO_O_GPFPUD) = ~0x000001FFU; EDIS; } //***************************************************************************** // // Function to enable pullups for the unbonded GPIOs on the // 176PTP package. // //***************************************************************************** void Device_enableUnbondedGPIOPullups(void) { // // bits 8-10 have pin count // uint16_t pinCount = ((HWREG(DEVCFG_BASE + SYSCTL_O_PARTIDL) & (uint32_t)SYSCTL_PARTIDL_PIN_COUNT_M) >> SYSCTL_PARTIDL_PIN_COUNT_S); /* * 6 = 176 pin * 7 = 337 pin */ if (pinCount == 6) { Device_enableUnbondedGPIOPullupsFor176Pin(); } else { // // Do nothing - this is 337 pin package // } } //***************************************************************************** // // Function to verify the XTAL frequency // freq is the XTAL frequency in MHz // The function return true if the the actual XTAL frequency matches with the // input value // // Note that this function assumes that the PLL is not already configured and // hence uses SysClk freq = 10MHz for DCC calculation // //***************************************************************************** #ifdef CPU1 bool Device_verifyXTAL(float freq) { // // Use DCC to verify the XTAL frequency using INTOSC2 as reference clock // // // Enable DCC0 clock // SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DCC0); // // Insert atleast 5 cycles delay after enabling the peripheral clock // asm(" RPT #5 || NOP"); // // Configures XTAL as CLKSRC0 and INTOSC2 as CLKSRC1 // Fclk0 = XTAL frequency (input parameter) // Fclk1 = INTOSC2 frequency = 10MHz // // Configuring DCC error tolerance of +/-1% // INTOSC2 can have a variance in frequency of +/-10% // // Assuming PLL is not already configured, SysClk freq = 10MHz // // Note : Update the tolerance and INTOSC2 frequency variance as necessary. // return (DCC_verifyClockFrequency(DCC0_BASE, DCC_COUNT1SRC_INTOSC2, 10.0F, DCC_COUNT0SRC_XTAL, freq, 1.0F, 10.0F, 10.0F)); } #endif //***************************************************************************** // // Error handling function to be called when an ASSERT is violated // //***************************************************************************** void __error__(const char *filename, uint32_t line) { // // An ASSERT condition was evaluated as false. You can use the filename and // line parameters to determine what went wrong. // ESTOP0; }