📄 flash.c
字号:
/******************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** ++ *** *
* *** + + *** CHIPCON *
* *** + *
* *** + + *** *
* *** ++ *** *
* *** *** *
* ************ *
* ********** *
* *
*******************************************************************************
Filename: flash.c
Target: cc2430
Author: efu
Revised: 30/5-2007
Revision: 1.2
Description:
This example reads data from the UART and stores it in a flash address
space. Both DMA and CPU flash write is used.
NOTE: The flash supports only a limited number of write/erase cycles,
therefore, this function should not be used many times, as this may wear
out the flash page used in this example.
******************************************************************************/
/******************************************************************************
* INCLUDES
*/
#include <stdio.h>
#include <string.h>
#include "app_ex.h"
/******************************************************************************
* CONSTANTS
*/
#define STRING_LENGTH 30
#define TEST_PAGE 31
#define PAGE_SIZE 2048
#define PAGE_TO_ADDR(p) (uint16)p * (uint16)PAGE_SIZE
#define ADDR_TO_PAGE(a) a >> 11
// Due to a bug in IAR this calculation is carried out manually
// PAGE_TO_ADDR;
// PAGE_SIZE * TEST_PAGE = 2048 * 31 = 0xF800
__no_init const char __code testData[ PAGE_SIZE ] @ 0xF800;
/******************************************************************************
* TYPEDEFS
*/
/******************************************************************************
* GLOBAL VARIABLES
*/
volatile DMA_DESC dmaChannel;
/******************************************************************************
* LOCAL VARIABLES
*/
/******************************************************************************
* LOCAL FUNCTIONS
*/
void writeFlashUsingDMA(byte* pSrcAddr, int16 length, word flashAddress, bool erase);
bool flashUnused(byte* data, int16 length);
void initFlash(void);
void flash_main(void);
void printCodeAddress(uint16 addr, uint16 n);
/******************************************************************************
* @fn initFlash
*
* @brief
* Initializes components for use with the Flash application example.
*
* Parameters:
*
* @param void
*
* @return void
*
******************************************************************************/
void initFlash(void)
{
initLcd();
INIT_BUTTON();
INIT_GLED();
INIT_YLED();
// Setting up UART
UART_SETUP(0, 57600, HIGH_STOP);
UTX0IF = 1; // Set UART 0 TX interrupt flag
}
/******************************************************************************
* @fn flash_main
*
* @brief
* Main function.
*
* Parameters:
*
* @param void
*
* @return void
*
******************************************************************************/
#ifdef COMPLETE_APPLICATION
void flash_main(void){
#else
void main(void){
#endif
byte buffer[30];
char inputBuffer[STRING_LENGTH];
int8 pointer = 0;
bool stop = FALSE;
char c;
initFlash();
// Clearing buffers
memset(buffer, 0, sizeof(buffer));
memset(inputBuffer, 0, sizeof(inputBuffer));
lcdUpdate((char*)"This app. req.",(char*)"UART");
// Uart communication
printf((char*)"\nFlash Programming\n");
printf((char*)"Press any key\n");
uartGetkey (); // wait for a key to be pressed or the application to be ended
stop = stopApplication();
while( !stop )
{
printf((char*)"****************************\n");
printf((char*)"d: Write with DMA\n");
printf((char*)"c: Write with CPU\n");
printf((char*)"e: Erase test page\n");
printf((char*)"p: Print the first chars on test page\n");
printf((char*)"ESC: Quit\n");
c = uartGetkey();
switch( c )
{
case 'e':
FLASH_ERASE_PAGE( TEST_PAGE );
printf((char*)"Erased Page: %d\n", TEST_PAGE);
break;
case 'p':
printCodeAddress(PAGE_TO_ADDR(TEST_PAGE), 20);
break;
case 'd':
printf("Input text:\n");
memset(inputBuffer, 0, STRING_LENGTH);
pointer = 0;
do
{
c = getkey();
// Add typed data to buffer.
if (pointer < STRING_LENGTH-1)
{
U0DBUF = c;
inputBuffer[pointer] = c;
pointer++;
}
}while( c != ENTER );
writeFlashUsingDMA((byte*) &inputBuffer, STRING_LENGTH, PAGE_TO_ADDR(TEST_PAGE), TRUE);
printf((char*)"Updated Page: %d\n", TEST_PAGE);
break;
case 'c':
printf("Input text:\n");
memset(inputBuffer, 0, STRING_LENGTH);
pointer = 0;
do
{
c = getkey();
// Add typed data to buffer.
if (pointer < STRING_LENGTH-1)
{
U0DBUF = c;
inputBuffer[pointer] = c;
pointer++;
}
}while( c != ENTER );
INT_GLOBAL_ENABLE(INT_OFF);
halFlashWritePage((byte*) &inputBuffer, buffer, TEST_PAGE);
INT_GLOBAL_ENABLE(INT_ON);
printf((char*)"Updated Page: %d\n", TEST_PAGE);
break;
case ESC:
printf((char*)"Exit\n");
stop = TRUE;
}
}
}
/******************************************************************************
* @fn writeFlashUsingDMA
*
* @brief
* Writes data to flash using DMA. Erases the page in advance if told to.
*
* Parameters:
*
* @param byte* pSrcAddr
* The start of the data to be written to flash.
*
* int16 length
* The number of bytes to be written to flash.
*
* word flashAddress
* The address in flash the data is to be written to.
*
* bool erase
* Indicating whether the flash is to be erased or not.
*
* @return void
*
******************************************************************************/
void writeFlashUsingDMA(byte* pSrcAddr, int16 length, word flashAddress, bool erase)
{
INT_GLOBAL_ENABLE(INT_OFF);
// Setting up the flash address,
// erasing the page if required.
SET_WORD(FADDRH, FADDRL, (uint16)(flashAddress >> 2));
if( erase ){
FLASH_ERASE_PAGE( ADDR_TO_PAGE( flashAddress ) );
}
// Making sure a multiplum of 4 bytes is transferred.
while(length & 0x0003) length++;
// Setting up the DMA
SET_WORD(dmaChannel.SRCADDRH, dmaChannel.SRCADDRL, pSrcAddr); // The start address of the segment
SET_WORD(dmaChannel.DESTADDRH, dmaChannel.DESTADDRL, &X_FWDATA); // Input of the AES module
SET_WORD(dmaChannel.LENH, dmaChannel.LENL, length); // Setting the length of the transfer (bytes)
dmaChannel.VLEN = VLEN_USE_LEN; // Using the length field
dmaChannel.PRIORITY = PRI_HIGH; // High priority
dmaChannel.M8 = M8_USE_8_BITS; // Transferring all 8 bits in each byte.
dmaChannel.IRQMASK = FALSE; // The DMA complete interrupt flag is set at completion.
dmaChannel.DESTINC = DESTINC_0; // The destination address is constant
dmaChannel.SRCINC = SRCINC_1; // The address for data fetch is inremented by 1 byte
dmaChannel.TRIG = DMATRIG_FLASH; // Setting the FLASH module to generate the DMA trigger
dmaChannel.TMODE = TMODE_SINGLE; // A single byte is transferred each time.
dmaChannel.WORDSIZE = WORDSIZE_BYTE; // Set to count bytes
// Clearing all DMA complete flags and arming the channel
DMA_SET_ADDR_DESC0(&dmaChannel);
DMA_ABORT_CHANNEL(0);
DMAIRQ = ~DMA_CHANNEL_0;
DMA_ARM_CHANNEL(0);
// Set correct timing
SET_FLASH_WRITE_TIME();
// Starting to write
halFlashDmaTrigger();
// Waiting for the DMA to finish.
while(!(DMAIRQ & DMA_CHANNEL_0));
DMAIRQ = ~DMA_CHANNEL_0;
}
/******************************************************************************
* @fn printCodeAddress
*
* @brief
* Checks whether the given flash area is uninitialized (0xFF).
*
* Parameters:
*
* @param uint16 addr
* The start of the data to be print
*
* int16 n
* The number of bytes to print
*
* @return void
*
******************************************************************************/
void printCodeAddress(uint16 addr, uint16 n)
{
byte c;
byte __code *codePtn;
for( codePtn = (__code byte *)addr; (uint16)codePtn < addr + n; codePtn++ )
{
c = *codePtn;
// printing oncy chars, this due to problems with printing non-char to HyperTerminal
if( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
printf("%c ", *codePtn);
}
printf("\n");
}
/******************************************************************************
* @fn flashUnused
*
* @brief
* Checks whether the given flash area is uninitialized (0xFF).
*
* Parameters:
*
* @param byte* data
* The start of the data to be investigated.
*
* int16 length
* The number of bytes to be insvestigated.
*
* @return bool
* Indicating if flash was unused (TRUE) or not (FALSE).
*
******************************************************************************/
bool flashUnused(byte* data, int16 length)
{
uint16 i;
bool rtn;
rtn = TRUE;
for( i = 0; i < length; i++)
{
if( data[i] != 0xFF )
{
rtn = FALSE;
break;
}
}
return rtn;
}
/******************************************************************************
* @fn flash_init
*
* @brief
* Initializes the Flash application example.
*
* Parameters:
*
* @param APPLICATION *a
* Main application
*
* @return void
*
******************************************************************************/
#ifdef COMPLETE_APPLICATION
void flash_init(APPLICATION *a)
{
a->menuText = (char*)"Flash Writing";
a->description = (char*)"57600 8-N-1";
a->main_func = flash_main;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -