//########################################################################### // // FILE: Example_Flash2833x_API.c // // TITLE: F2833x Flash API Example // // NOTE: This example runs from Flash. First program the example // into flash. The code will then copy the API's to RAM and // modify the flash. // // //########################################################################### // $TI Release: F28335 API Release V1.0 $ // $Release Date: September 14, 2007 $ //########################################################################### /*---- Flash API include file -------------------------------------------------*/ #include "Flash2833x_API_Library.h" /*---- example include file ---------------------------------------------------*/ #include "Example_Flash2833x_API.h" /*---- Standard headers -------------------------------------------------------*/ #include /*--- Callback function. Function specified by defining Flash_CallbackPtr */ void MyCallbackFunction(void); Uint32 MyCallbackCounter; // Just increment a counter in the callback function /*--- Global variables used to interface to the flash routines */ FLASH_ST FlashStatus; /*--------------------------------------------------------------------------- Data/Program Buffer used for testing the flash API functions ---------------------------------------------------------------------------*/ #define WORDS_IN_FLASH_BUFFER 0x100 // Programming data buffer, Words Uint16 Buffer[WORDS_IN_FLASH_BUFFER]; /*--------------------------------------------------------------------------- Sector address info ---------------------------------------------------------------------------*/ typedef struct { Uint16 *StartAddr; Uint16 *EndAddr; } SECTOR; #define OTP_START_ADDR 0x380400 #define OTP_END_ADDR 0x3807FF #if FLASH_F28335 #define FLASH_START_ADDR 0x300000 #define FLASH_END_ADDR 0x33FFFF SECTOR Sector[8] = { (Uint16 *)0x338000,(Uint16 *)0x33FFFF, (Uint16 *)0x330000,(Uint16 *)0x337FFF, (Uint16 *)0x328000,(Uint16 *)0x32FFFF, (Uint16 *)0x320000,(Uint16 *)0x327FFF, (Uint16 *)0x318000,(Uint16 *)0x31FFFF, (Uint16 *)0x310000,(Uint16 *)0x317FFF, (Uint16 *)0x308000,(Uint16 *)0x30FFFF, (Uint16 *)0x300000,(Uint16 *)0x307FFF }; #endif #if FLASH_F28334 #define FLASH_START_ADDR 0x320000 #define FLASH_END_ADDR 0x33FFFF SECTOR Sector[8] = { (Uint16 *)0x33C000,(Uint16 *)0x33FFFF, (Uint16 *)0x338000,(Uint16 *)0x33BFFF, (Uint16 *)0x334000,(Uint16 *)0x337FFF, (Uint16 *)0x330000,(Uint16 *)0x333FFF, (Uint16 *)0x32C000,(Uint16 *)0x32FFFF, (Uint16 *)0x328000,(Uint16 *)0x32BFFF, (Uint16 *)0x324000,(Uint16 *)0x327FFF, (Uint16 *)0x320000,(Uint16 *)0x323FFF }; #endif #if FLASH_F28332 #define FLASH_START_ADDR 0x330000 #define FLASH_END_ADDR 0x33FFFF SECTOR Sector[4] = { (Uint16 *)0x33C000,(Uint16 *)0x33FFFF, (Uint16 *)0x338000,(Uint16 *)0x33BFFF, (Uint16 *)0x334000,(Uint16 *)0x337FFF, (Uint16 *)0x330000,(Uint16 *)0x333FFF }; #endif extern Uint32 Flash_CPUScaleFactor; void main( void ) { /*------------------------------------------------------------------ To use the Flash API, the following steps must be followed: 1. Modify Flash2833x_API_Config.h for your targets operating conditions. 2. Include Flash2833x_API_Library.h in the application. 3. Add the approparite Flash API library to the project. The user's code is responsible for the following: 4. Initalize the PLL to the proper CPU operating frequency. 5. If required, copy the flash API functions into on-chip zero waitstate RAM. 6. Initalize the Flash_CPUScaleFactor variable to SCALE_FACTOR 7. Initalize the callback function pointer or set it to NULL 8. Optional: Run the Toggle test to confirm proper frequency configuration of the API. 9. Optional: Unlock the CSM. 10. Make sure the PLL is not running in limp mode 11. Call the API functions: Flash_Erase(), Flash_Program(), Flash_Verify() The API functions will: Disable the watchdog Check the device PARTID. Disable interrupts during time critical code. Perform the desired operation and return status ------------------------------------------------------------------*/ Uint16 Status; /*------------------------------------------------------------------ Initalize the PLLCR value before calling any of the F2833x Flash API functions. Check to see if the PLL needs to changed PLLCR_VALUE is defined in Example_Flash2833x_API.h 1) Make sure PLL is not in limp mode 2) Disable missing clock detect logic 3) Make the change 4) Wait for the DSP to switch to the PLL clock This wait is performed to ensure that the flash API functions will be executed at the correct frequency. 5) While waiting, feed the watchdog so it will not reset. 6) Re-enable the missing clock detect logic ------------------------------------------------------------------*/ // Assuming PLLSTS[CLKINDIV] = 0 (default on XRSn). If it is not // 0, then the PLLCR cannot be written to. // Make sure the PLL is not running in limp mode if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 1) { if (SysCtrlRegs.PLLCR.bit.DIV != PLLCR_VALUE) { EALLOW; // Before setting PLLCR turn off missing clock detect SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1; SysCtrlRegs.PLLCR.bit.DIV = PLLCR_VALUE; EDIS; // Wait for PLL to lock. // During this time the CPU will switch to OSCCLK/2 until // the PLL is stable. Once the PLL is stable the CPU will // switch to the new PLL value. // // This time-to-lock is monitored by a PLL lock counter. // // The watchdog should be disabled before this loop, or fed within // the loop. EALLOW; SysCtrlRegs.WDCR= 0x0068; EDIS; // Wait for the PLL lock bit to be set. // Note this bit is not available on 281x devices. For those devices // use a software loop to perform the required count. while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1) { } EALLOW; SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0; EDIS; } } // If the PLL is in limp mode, shut the system down else { // Replace this line with a call to an appropriate // SystemShutdown(); function. asm(" ESTOP0"); } /*------------------------------------------------------------------ Unlock the CSM. If the API functions are going to run in unsecured RAM then the CSM must be unlocked in order for the flash API functions to access the flash. If the flash API functions are executed from secure memory (L0-L3) then this step is not required. ------------------------------------------------------------------*/ Status = Example_CsmUnlock(); if(Status != STATUS_SUCCESS) { Example_Error(Status); } /*------------------------------------------------------------------ Copy API Functions into SARAM The flash API functions MUST be run out of internal zero-waitstate SARAM memory. This is required for the algos to execute at the proper CPU frequency. If the algos are already in SARAM then this step can be skipped. DO NOT run the algos from Flash DO NOT run the algos from external memory ------------------------------------------------------------------*/ // Copy the Flash API functions to SARAM Example_MemCopy(&Flash28_API_LoadStart, &Flash28_API_LoadEnd, &Flash28_API_RunStart); // We must also copy required user interface functions to RAM. Example_MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart); /*------------------------------------------------------------------ Initalize Flash_CPUScaleFactor. Flash_CPUScaleFactor is a 32-bit global variable that the flash API functions use to scale software delays. This scale factor must be initalized to SCALE_FACTOR by the user's code prior to calling any of the Flash API functions. This initalization is VITAL to the proper operation of the flash API functions. SCALE_FACTOR is defined in Example_Flash2833x_API.h as #define SCALE_FACTOR 1048576.0L*( (200L/CPU_RATE) ) This value is calculated during the compile based on the CPU rate, in nanoseconds, at which the algorithums will be run. ------------------------------------------------------------------*/ Flash_CPUScaleFactor = SCALE_FACTOR; /*------------------------------------------------------------------ Initalize Flash_CallbackPtr. Flash_CallbackPtr is a pointer to a function. The API uses this pointer to invoke a callback function during the API operations. If this function is not going to be used, set the pointer to NULL NULL is defined in . ------------------------------------------------------------------*/ Flash_CallbackPtr = &MyCallbackFunction; MyCallbackCounter = 0; // Increment this counter in the callback function // Jump to SARAM and call the Flash API functions Example_CallFlashAPI(); } /*------------------------------------------------------------------ Example_CallFlashAPI This function will interface to the flash API. Parameters: Return Value: Notes: This function will be executed from SARAM -----------------------------------------------------------------*/ #pragma CODE_SECTION(Example_CallFlashAPI,"ramfuncs"); void Example_CallFlashAPI(void) { Uint16 i; Uint16 Status; Uint16 *Flash_ptr; // Pointer to a location in flash Uint32 Length; // Number of 16-bit values to be programmed float32 Version; // Version of the API in floating point Uint16 VersionHex; // Version of the API in decimal encoded hex /*------------------------------------------------------------------ Toggle Test The toggle test is run to verify the frequency configuration of the API functions. The selected pin will toggle at 10kHz (100uS cycle time) if the API is configured correctly. Example_ToggleTest() supports common output pins. Other pins can be used by modifying the Example_ToggleTest() function or calling the Flash_ToggleTest() function directly. Select a pin that makes sense for the hardware platform being used. This test will run forever and not return, thus only run this test to confirm frequency configuration and not during normal API use. ------------------------------------------------------------------*/ // Example: Toggle GPIO0 // Example_ToggleTest(0); // Example: Toggle GPIO10 // Example_ToggleTest(10); // Example: Toggle GPIO15 // Example_ToggleTest(15); // Example: Toggle GPIO31 // Example_ToggleTest(31); // Example: Toggle GPIO34 Example_ToggleTest(34); /*------------------------------------------------------------------ Check the version of the API Flash_APIVersion() returns the version in floating point. FlashAPIVersionHex() returns the version as a decimal encoded hex. FlashAPIVersionHex() can be used to avoid processing issues associated with floating point values. ------------------------------------------------------------------*/ VersionHex = Flash_APIVersionHex(); if(VersionHex != 0x0210) { // Unexpected API version // Make a decision based on this info. asm(" ESTOP0"); } Version = Flash_APIVersion(); if(Version != (float32)2.10) { // Unexpected API version // Make a decision based on this info. asm(" ESTOP0"); } /*------------------------------------------------------------------ Before programming make sure the sectors are Erased. ------------------------------------------------------------------*/ // Example: Erase Sector B,C // Sectors A and D have the example code so leave them // programmed. // SECTORB, SECTORC are defined in Flash2833x_API_Library.h Status = Flash_Erase((SECTORB|SECTORC),&FlashStatus); if(Status != STATUS_SUCCESS) { Example_Error(Status); } /*------------------------------------------------------------------ Program Flash Examples ------------------------------------------------------------------*/ // A buffer can be supplied to the program function. Each word is // programmed until the whole buffer is programmed or a problem is // found. If the buffer goes outside of the range of OTP or Flash // then nothing is done and an error is returned. // Example: Program 0x400 values in Flash Sector B // In this case just fill a buffer with data to program into the flash. for(i=0;i (Uint16)34) { asm(" ESTOP0"); // Stop here. Invalid option. for(;;); } // Pins GPIO16-GPIO31 else if(PinNumber >= 32) { EALLOW; mask = ~( ((Uint32)1 << (PinNumber-16)*2) | ((Uint32)1 << (PinNumber-32)*2+1) ); GpioCtrlRegs.GPBMUX1.all &= mask; GpioCtrlRegs.GPBDIR.all = GpioCtrlRegs.GPADIR.all | ((Uint32)1 << (PinNumber-32) ); Flash_ToggleTest(&GpioDataRegs.GPBTOGGLE.all, ((Uint32)1 << PinNumber) ); EDIS; } // Pins GPIO16-GPIO31 else if(PinNumber >= 16) { EALLOW; mask = ~( ((Uint32)1 << (PinNumber-16)*2) | ((Uint32)1 << (PinNumber-16)*2+1) ); GpioCtrlRegs.GPAMUX2.all &= mask; GpioCtrlRegs.GPADIR.all = GpioCtrlRegs.GPADIR.all | ((Uint32)1 << PinNumber); Flash_ToggleTest(&GpioDataRegs.GPATOGGLE.all, ((Uint32)1 << PinNumber) ); EDIS; } // Pins GPIO0-GPIO15 else { EALLOW; mask = ~( ((Uint32)1 << PinNumber*2) | ((Uint32)1 << PinNumber*2+1 )); GpioCtrlRegs.GPAMUX1.all &= mask; GpioCtrlRegs.GPADIR.all = GpioCtrlRegs.GPADIR.all | ((Uint32)1 << PinNumber); EDIS; Flash_ToggleTest(&GpioDataRegs.GPATOGGLE.all, ((Uint32)1 << PinNumber) ); } } /*------------------------------------------------------------------ Simple memory copy routine to move code out of flash into SARAM -----------------------------------------------------------------*/ void Example_MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr) { while(SourceAddr < SourceEndAddr) { *DestAddr++ = *SourceAddr++; } return; } /*------------------------------------------------------------------ For this example, if an error is found just stop here -----------------------------------------------------------------*/ #pragma CODE_SECTION(Example_Error,"ramfuncs"); void Example_Error(Uint16 Status) { // Error code will be in the AL register. asm(" ESTOP0"); asm(" SB 0, UNC"); } /*------------------------------------------------------------------ For this example, once we are done just stop here -----------------------------------------------------------------*/ #pragma CODE_SECTION(Example_Done,"ramfuncs"); void Example_Done(void) { asm(" ESTOP0"); asm(" SB 0, UNC"); } /*------------------------------------------------------------------ Callback function - must be executed from outside flash/OTP -----------------------------------------------------------------*/ #pragma CODE_SECTION(MyCallbackFunction,"ramfuncs"); void MyCallbackFunction(void) { // Toggle pin, service external watchdog etc MyCallbackCounter++; asm(" NOP"); }