Added Software projects

git-svn-id: file:///srv/dev-disk-by-uuid-17e88007-4d0c-45e0-8757-cacfcc458630/repositories/svn/Diplomarbeit@55 9fe90eed-be63-e94b-8204-d34ff4c2ff93
This commit is contained in:
Matthias
2008-12-23 10:34:08 +00:00
parent ee5a771818
commit 373a8c32b2
348 changed files with 86781 additions and 0 deletions
+620
View File
@@ -0,0 +1,620 @@
/* ---------------------------------------------------------------------------
* IspProtocol.c - v0.1 (c) 2008 Micro-key bv
* ---------------------------------------------------------------------------
* Micro-key bv
* Industrieweg 28, 9804 TG Noordhorn
* Postbus 92, 9800 AB Zuidhorn
* The Netherlands
* Tel: +31 594 503020
* Fax: +31 594 505825
* Email: support@microkey.nl
* Web: www.microkey.nl
* ---------------------------------------------------------------------------
* Description:
* ---------------------------------------------------------------------------
* Version(s): 0.1, Feb 13, 2008, FSc
* Creation.
* ---------------------------------------------------------------------------
*/
/* ---------------------------------------------------------------------------
* System include files
* ---------------------------------------------------------------------------
*/
/* ---------------------------------------------------------------------------
* Application include files
* ---------------------------------------------------------------------------
*/
#include "types.h"
#include "IspProtocol.h"
#include "InternalFlash.h"
#include "Crc.h"
#include "Leds.h"
#include "appImage.h"
/* ---------------------------------------------------------------------------
* Local constant and macro definitions
* ---------------------------------------------------------------------------
*/
#define MAX_ADMINS (4)
#define START_BYTE (0xAA)
#define MAX_PAYLOAD_SIZE (80)
#define MSGID_ACKNOWLEDGE (0x01)
#define MSGID_UNLOCK (0x02)
#define MSGID_ERASEBLOCK (0x03)
#define MSGID_PROGRAMFLASH (0x04)
#define MSGID_VERIFYFLASH (0x05)
#define MSGID_FINISHPROGRAMMING (0x06)
#define MSGID_STARTPROGRAM (0x07)
#define APP_FLASH_START_ADDR (0x00005000)
#define APP_FLASH_END_ADDR (0x0007DFFF)
#define APP_FLASH_START_SECTOR (5)
#define APP_FLASH_END_SECTOR (27)
#define APP_IMAGE_LENGTH_OFFS 0x0008
#define APP_IMAGE_CRC_OFFS 0x000C
#define PROGRAM_BLOCK_SIZE (256)
#define INVALID_ADDRESS (0xFFFFFFFF)
/* ---------------------------------------------------------------------------
* Global variable definitions
* ---------------------------------------------------------------------------
*/
/* ---------------------------------------------------------------------------
* Local variable definitions
* ---------------------------------------------------------------------------
*/
typedef enum
{
IDLE,
MESSAGE_ID,
PAYLOAD_SIZE,
PAYLOAD,
CRC
} t_isp_decodestatus;
typedef struct t_ISP_MESSAGE {
UINT8 messageId;
UINT8 payloadSize;
UINT8 payload[MAX_PAYLOAD_SIZE];
UINT16 crc;
} t_isp_message;
typedef struct t_ISP_ADMIN {
t_isp_decodestatus status;
UINT8 rxIndex;
UINT16 rxCrc;
t_isp_message rxMessage;
t_isp_ack_callback ackCallback;
} t_isp_admin;
static t_isp_admin ispAdmins[MAX_ADMINS];
static UINT8 lastReservedAdmin = 0;
static UINT32 maxProgrammedAddress = 0;
static UINT32 startAddress = INVALID_ADDRESS;
static UINT8 verifyBlock[PROGRAM_BLOCK_SIZE] __attribute__((aligned(PROGRAM_BLOCK_SIZE)));
static UINT8 programBlock[PROGRAM_BLOCK_SIZE] __attribute__((aligned(PROGRAM_BLOCK_SIZE)));
static UINT8 programFirstBlock[PROGRAM_BLOCK_SIZE] __attribute__((aligned(PROGRAM_BLOCK_SIZE)));
/* ---------------------------------------------------------------------------
* Local function definitions
* ---------------------------------------------------------------------------
*/
void sendAcknowledge(t_isp_admin *handle, t_isp_responses response);
BOOLEAN ValidMessageId( UINT8 messageId);
void handleMessage(t_isp_admin *admin);
void handleUnlockMessage(t_isp_admin *admin);
void handleEraseBlockMessage(t_isp_admin *admin);
void handleStartProgram(t_isp_admin *admin);
void handleFinishProgramming(t_isp_admin *admin);
void handleVerifyFlashMessage(t_isp_admin *admin);
void handleProgramFlashMessage(t_isp_admin *admin);
iflashresult fillProgramBlock( UINT32 address, UINT8 size, UINT8 *data);
iflashresult programFlash();
void resetRamBlock( UINT32 address );
iflashresult StoreCrcAndLength( UINT32 imageSize );
/** \brief Initialises a instance of the ISP-protocol handler.
*
* For each communication port, one ISP-protocol handler must be initialised.
*
* \param ackCallback Callback-function used for parent to send acknowledge
* \returns handle Handle for this ISP-protocol handler.
*/
int ispInitProtocol(t_isp_ack_callback ackCallback )
{
int result;
if (lastReservedAdmin < MAX_ADMINS)
{
ispAdmins[lastReservedAdmin].status = IDLE;
ispAdmins[lastReservedAdmin].ackCallback = ackCallback;
result = lastReservedAdmin;
lastReservedAdmin++;
}
else
{
result = -1;
}
return result;
}
/** \brief Does the protocol handling by parsing each byte received on the communication port.
*
* \param handle Handle for the ISP-protocol handler
* \param byte The received byte on the communication port
*/
void ispHandleRxByte( int handle, UINT8 byte )
{
t_isp_admin *admin = &(ispAdmins[handle]);
switch( admin->status )
{
case(IDLE):
if (byte == START_BYTE)
{
admin->status = MESSAGE_ID;
}
break;
case(MESSAGE_ID):
if (ValidMessageId(byte) == TRUE )
{
// Determine Payload-size
admin->rxCrc = crcCalc(&byte, 1, 0);
admin->rxMessage.messageId = byte;
admin->status = PAYLOAD_SIZE;
}
else
{
sendAcknowledge( admin, ISP_INVALID_MESSAGE_ID );
admin->status = IDLE;
}
break;
case(PAYLOAD_SIZE):
// Determine Payload-size
if (byte <=MAX_PAYLOAD_SIZE)
{
admin->rxMessage.payloadSize = byte;
admin->rxCrc = crcCalc(&byte, 1, admin->rxCrc);
admin->rxIndex = 0;
if (byte > 0)
{
admin->status = PAYLOAD;
}
else
{
admin->status = CRC;
}
}
else
{
sendAcknowledge( admin, ISP_PAYLOAD_TOO_LARGE );
admin->status = IDLE;
}
break;
case(PAYLOAD):
admin->rxMessage.payload[ admin->rxIndex ] = byte;
admin->rxCrc = crcCalc(&byte, 1, admin->rxCrc);
admin->rxIndex++;
if (admin->rxIndex >= admin->rxMessage.payloadSize)
{
admin->rxIndex = 0;
admin->status = CRC;
}
break;
case(CRC):
// Receive and check CRC
if (admin->rxIndex == 0)
{
admin->rxMessage.crc = (byte << 8);
}
else
{
admin->rxMessage.crc |= (byte & 0x00FF);
}
admin->rxIndex++;
if (admin->rxIndex >= 2)
{
if (admin->rxCrc == admin->rxMessage.crc)
{
/* Crc was succesfully checked */
handleMessage(admin);
}
else
{
sendAcknowledge( admin, ISP_RECV_BAD_CRC );
}
admin->status = IDLE;
}
break;
default:
admin->status = IDLE;
break;
}
}
void handleMessage(t_isp_admin *admin)
{
switch( admin->rxMessage.messageId )
{
case(MSGID_UNLOCK):
//sendAcknowledge( admin, ISP_CMD_SUCCESS);
handleUnlockMessage( admin );
break;
case(MSGID_ERASEBLOCK):
handleEraseBlockMessage( admin );
break;
case(MSGID_PROGRAMFLASH):
handleProgramFlashMessage( admin );
break;
case(MSGID_VERIFYFLASH):
handleVerifyFlashMessage( admin );
break;
case(MSGID_FINISHPROGRAMMING):
handleFinishProgramming( admin );
break;
case(MSGID_STARTPROGRAM):
handleStartProgram( admin );
break;
default:
sendAcknowledge( admin, ISP_INVALID_MESSAGE_ID);
break;
}
}
BOOLEAN ValidMessageId( UINT8 messageId)
{
if ((messageId >= 0x01) && (messageId <= 0x07))
{
return TRUE;
}
else
{
return FALSE;
}
}
void sendAcknowledge(t_isp_admin *handle, t_isp_responses response)
{
handle->ackCallback( response );
}
void handleUnlockMessage(t_isp_admin *admin)
{
iflashresult unlockResult = ISP_CMD_SUCCESS;
maxProgrammedAddress = 0;
unlockResult =iflashPrepare( APP_FLASH_START_SECTOR, APP_FLASH_END_SECTOR);
admin->ackCallback( (t_isp_responses)unlockResult );
}
void handleEraseBlockMessage(t_isp_admin *admin)
{
iflashresult result;
UINT8 blockNr;
// Extract block nr from message
blockNr = admin->rxMessage.payload[0];
if ( ( blockNr >= APP_FLASH_START_SECTOR)
&& ( blockNr <= APP_FLASH_END_SECTOR))
{
result = iflashErase( blockNr );
}
else
{
result = ISP_INVALID_SECTOR;
}
admin->ackCallback( (t_isp_responses)result );
}
void handleProgramFlashMessage(t_isp_admin *admin)
{
iflashresult result;
UINT32 address;
UINT8 size;
UINT8 *data;
UINT8 index = 0;
// Extract address, datalength & data from message
address = ispGet32bit(admin->rxMessage.payload, &index);
size = ispGet8bit(admin->rxMessage.payload, &index);
data = &(admin->rxMessage.payload[index]);
if (maxProgrammedAddress < address) maxProgrammedAddress = address;
if ( (address >= APP_FLASH_START_ADDR)
&& (address <= APP_FLASH_END_ADDR)
)
{
result = fillProgramBlock(address, size, data );
}
else
{
result = ISP_DST_ADDR_ERROR;
}
admin->ackCallback( (t_isp_responses)result );
}
void handleVerifyFlashMessage(t_isp_admin *admin)
{
iflashresult result;
UINT32 address;
UINT8 size;
UINT8 index = 0;
UINT8 bufferIdx;
// Extract address, datalength & data from message
address = ispGet32bit(admin->rxMessage.payload, &index);
size = ispGet8bit(admin->rxMessage.payload, &index);
for (bufferIdx = 0; bufferIdx < size; bufferIdx++)
{
verifyBlock[bufferIdx] = ispGet8bit(admin->rxMessage.payload, &index);
}
// Make size dividable by 4
size = size - (size % 4);
if ((size >= 4) && (address != APP_FLASH_START_ADDR))
{
result = iflashVerify( address, size, verifyBlock );
}
else
{
result = ISP_CMD_SUCCESS;
}
admin->ackCallback( (t_isp_responses)result );
}
void handleFinishProgramming(t_isp_admin *admin)
{
iflashresult result;
UINT32 imageSize;
// Program remaining block on flash
fillProgramBlock(0, 0, 0 );
// Calculate image length
imageSize = maxProgrammedAddress - APP_FLASH_START_ADDR;
// Calculate and store Crc & imageSize on flash
result = StoreCrcAndLength( imageSize );
admin->ackCallback( (t_isp_responses)result );
}
void handleStartProgram(t_isp_admin *admin)
{
//if (appiValidAppImageAvail() == TRUE)
{
ledSet( LED1, 0 );
ledSet( LED0, 0 );
appiJumpToAppImage();
}
//else
//{
// admin->ackCallback( ISP_BUSY );
//}
}
void ispAdd16bit(UINT8 *payloadlocation, UINT16 data)
{
UINT8 index = 0;
payloadlocation[index] = (UINT8)(data >> 8);
index++;
payloadlocation[index] = (UINT8)(data & 0x00FF);
}
void ispAdd32bit(UINT8 *payloadlocation, UINT32 data)
{
UINT8 index = 0;
payloadlocation[index] = (UINT8)(data >> 24);
index++;
payloadlocation[index] = (UINT8)(data >> 16);
index++;
payloadlocation[index] = (UINT8)(data >> 8);
index++;
payloadlocation[index] = (UINT8)(data & 0xFF);
}
UINT8 ispGet8bit(UINT8 *payload, UINT8 *payloadIndex)
{
UINT8 result;
result = (UINT8)payload[*payloadIndex];
(*payloadIndex)++;
return result;
}
UINT16 ispGet16bit(UINT8 *payload, UINT8 *payloadIndex)
{
UINT16 result;
result = ((UINT16)payload[*payloadIndex]) << 8;
(*payloadIndex)++;
result += ((UINT16)payload[*payloadIndex] & 0x00FF);
(*payloadIndex)++;
return result;
}
UINT32 ispGet32bit(UINT8 *payload, UINT8 *payloadIndex)
{
UINT32 result;
result = ((UINT32)payload[*payloadIndex]) << 24;
(*payloadIndex)++;
result += ((UINT32)payload[*payloadIndex]) << 16;
(*payloadIndex)++;
result += ((UINT32)payload[*payloadIndex]) << 8;
(*payloadIndex)++;
result += ((UINT32)payload[*payloadIndex] & 0x000000FF);
(*payloadIndex)++;
return result;
}
iflashresult fillProgramBlock( UINT32 address, UINT8 size, UINT8 *data)
{
UINT32 programIndex;
UINT32 beginIndex;
UINT32 dataIndex;
UINT32 endIndex;
iflashresult result = ISP_CMD_SUCCESS;
if (data == 0)
{
// finish sending last block
if (startAddress > 0)
{
result = programFlash();
}
else
{
result = ISP_CMD_SUCCESS;
}
startAddress = INVALID_ADDRESS;
return result;
}
// Determine startAddress.
if (startAddress == INVALID_ADDRESS)
{
// Make sure address is alligned to 256
resetRamBlock(address - (address % PROGRAM_BLOCK_SIZE));
}
else
{
if (address > (startAddress + PROGRAM_BLOCK_SIZE))
{
result = programFlash();
resetRamBlock( address );
}
}
// Determine endIndex;
if ( (startAddress + PROGRAM_BLOCK_SIZE) > (address + size) )
{
endIndex = (address - startAddress) + size;
}
else
{
endIndex = PROGRAM_BLOCK_SIZE;
}
// Copy data into programblock
dataIndex = 0;
beginIndex = address - startAddress;
for (programIndex = beginIndex; programIndex < endIndex; programIndex++)
{
programBlock[programIndex] = data[dataIndex];
dataIndex++;
}
// if program block is full, program it
if (dataIndex < size)
{
result = programFlash();
resetRamBlock( startAddress + PROGRAM_BLOCK_SIZE );
// Copy rest in new block
endIndex = size - dataIndex;
for (programIndex = 0; programIndex < endIndex; programIndex++)
{
programBlock[programIndex] = data[dataIndex];
dataIndex++;
}
}
else
{
if ((startAddress + PROGRAM_BLOCK_SIZE) == (address + size))
{
result = programFlash();
resetRamBlock( INVALID_ADDRESS );
}
}
return result;
}
void resetRamBlock( UINT32 address )
{
UINT32 programIndex;
startAddress = address;
for (programIndex = 0; programIndex < PROGRAM_BLOCK_SIZE; programIndex++)
{
programBlock[programIndex] = 0x00;
}
}
iflashresult programFlash()
{
UINT16 index;
if (startAddress != APP_FLASH_START_ADDR)
{
iflashPrepare( APP_FLASH_START_SECTOR, APP_FLASH_END_SECTOR);
return iflashProgram( startAddress, PROGRAM_BLOCK_SIZE, programBlock );
}
else
{
// keep copy of first block, programmed later at FinishedProgramming
for (index = 0; index < PROGRAM_BLOCK_SIZE; index++)
{
programFirstBlock[index] = programBlock[index];
}
return ISP_CMD_SUCCESS;
}
}
iflashresult StoreCrcAndLength( UINT32 imageSize )
{
static UINT16 crc = 0;
static UINT8 *image = 0;
// Calculate Crc over part before Length & CRC
crc = crcCalc(programFirstBlock, APP_IMAGE_LENGTH_OFFS, crc);
// Calculate Crc over part after Length & CRC in first program block
image = (UINT8 *)(programFirstBlock + APP_IMAGE_CRC_OFFS + 4);
crc = crcCalc(image, PROGRAM_BLOCK_SIZE - (APP_IMAGE_CRC_OFFS + 4), crc);
// Calculate Crc over rest of image already programmed
image = (UINT8 *)(APP_FLASH_START_ADDR + PROGRAM_BLOCK_SIZE);
crc = crcCalc(image, imageSize - PROGRAM_BLOCK_SIZE, crc);
// Fill in Length & CRC
ispAdd32bit(programFirstBlock + APP_IMAGE_LENGTH_OFFS, imageSize);
ispAdd16bit(programFirstBlock + APP_IMAGE_CRC_OFFS, crc);
// Program first block on flash
iflashPrepare( APP_FLASH_START_SECTOR, APP_FLASH_START_SECTOR);
return iflashProgram( APP_FLASH_START_ADDR, PROGRAM_BLOCK_SIZE, programFirstBlock );
}