mirror of
https://github.com/fhgwright/SCSI2SD.git
synced 2025-01-09 04:30:29 +00:00
75f825e6d5
Firmware upgrade and config save/load mostly works. Firmware isn't making use of the new configuration yet.
178 lines
6.1 KiB
C
178 lines
6.1 KiB
C
/*******************************************************************************
|
|
* Copyright 2011-2012, Cypress Semiconductor Corporation. All rights reserved.
|
|
* You may use this file only in accordance with the license, terms, conditions,
|
|
* disclaimers, and limitations in the end user license agreement accompanying
|
|
* the software package with which this file was provided.
|
|
********************************************************************************/
|
|
|
|
#include <string.h>
|
|
#include "cybtldr_parse.h"
|
|
#include "cybtldr_command.h"
|
|
#include "cybtldr_api.h"
|
|
#include "cybtldr_api2.h"
|
|
|
|
unsigned char g_abort;
|
|
|
|
int CyBtldr_RunAction(CyBtldr_Action action, const char* file, CyBtldr_CommunicationsData* comm, CyBtldr_ProgressUpdate* update)
|
|
{
|
|
const unsigned long BL_VER_SUPPORT_VERIFY = 0x010214; /* Support for full flash verify added in v2.20 of cy_boot */
|
|
const unsigned char INVALID_APP = 0xFF;
|
|
|
|
unsigned long blVer = 0;
|
|
unsigned long siliconId = 0;
|
|
unsigned short rowNum = 0;
|
|
unsigned short bufSize = 0;
|
|
unsigned char siliconRev = 0;
|
|
unsigned char chksumtype = SUM_CHECKSUM;
|
|
unsigned char checksum = 0;
|
|
unsigned char checksum2 = 0;
|
|
unsigned char arrayId = 0;
|
|
unsigned char appId;
|
|
unsigned char isValid;
|
|
unsigned char isActive;
|
|
unsigned char buffer[MAX_BUFFER_SIZE];
|
|
char line[MAX_BUFFER_SIZE];
|
|
unsigned int lineLen;
|
|
char * app;
|
|
int err;
|
|
|
|
g_abort = 0;
|
|
|
|
err = CyBtldr_OpenDataFile(file);
|
|
if (CYRET_SUCCESS == err)
|
|
{
|
|
err = CyBtldr_ReadLine(&lineLen, line);
|
|
if (CYRET_SUCCESS == err)
|
|
err = CyBtldr_ParseHeader(lineLen, line, &siliconId, &siliconRev, &chksumtype);
|
|
|
|
if (CYRET_SUCCESS == err)
|
|
{
|
|
CyBtldr_SetCheckSumType(chksumtype);
|
|
err = CyBtldr_StartBootloadOperation(comm, siliconId, siliconRev, &blVer);
|
|
}
|
|
|
|
app = strrchr(file, '_');
|
|
appId = (app != NULL && '.' == app[2])
|
|
? (CyBtldr_FromHex(app[1]) - 1)
|
|
: INVALID_APP;
|
|
|
|
if (CYRET_SUCCESS == err && INVALID_APP != appId)
|
|
{
|
|
/* NB: This block of code will still run for single app if file */
|
|
/* name format follows same as multi app (e.g. myfile_1.cyacd) */
|
|
|
|
/* This will return error if bootloader is for single app */
|
|
err = CyBtldr_GetApplicationStatus(appId, &isValid, &isActive);
|
|
|
|
/* Active app can be verified, but not programmed or erased */
|
|
if (CYRET_SUCCESS == err && VERIFY != action && isActive)
|
|
{
|
|
/* This is multi app */
|
|
err = CYRET_ERR_ACTIVE;
|
|
}
|
|
else if (CYBTLDR_STAT_ERR_CMD == (err ^ (int)CYRET_ERR_BTLDR_MASK))
|
|
{
|
|
/* Single app - restore previous CYRET_SUCCESS */
|
|
err = CYRET_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (CYRET_SUCCESS == err)
|
|
{
|
|
while (CYRET_SUCCESS == err)
|
|
{
|
|
if (g_abort)
|
|
{
|
|
err = CYRET_ABORT;
|
|
break;
|
|
}
|
|
|
|
err = CyBtldr_ReadLine(&lineLen, line);
|
|
if (CYRET_SUCCESS == err)
|
|
err = CyBtldr_ParseRowData(lineLen, line, &arrayId, &rowNum, buffer, &bufSize, &checksum);
|
|
if (CYRET_SUCCESS == err)
|
|
{
|
|
switch (action)
|
|
{
|
|
case ERASE:
|
|
err = CyBtldr_EraseRow(arrayId, rowNum);
|
|
break;
|
|
case PROGRAM:
|
|
err = CyBtldr_ProgramRow(arrayId, rowNum, buffer, bufSize);
|
|
if (CYRET_SUCCESS != err)
|
|
break;
|
|
/* Continue on to verify the row that was programmed */
|
|
case VERIFY:
|
|
checksum2 = (unsigned char)(checksum + arrayId + rowNum + (rowNum >> 8) + bufSize + (bufSize >> 8));
|
|
err = CyBtldr_VerifyRow(arrayId, rowNum, checksum2);
|
|
break;
|
|
}
|
|
if (CYRET_SUCCESS == err && NULL != update)
|
|
update(arrayId, rowNum);
|
|
}
|
|
else if (CYRET_ERR_EOF == err)
|
|
{
|
|
err = CYRET_SUCCESS;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (CYRET_SUCCESS == err)
|
|
{
|
|
/* Set the active application to what was just programmed */
|
|
if (PROGRAM == action && INVALID_APP != appId)
|
|
{
|
|
err = CyBtldr_GetApplicationStatus(appId, &isValid, &isActive);
|
|
|
|
if (CYRET_SUCCESS == err)
|
|
{
|
|
/* If valid set the active application to what was just programmed */
|
|
/* This is multi app */
|
|
err = (0 == isValid)
|
|
? CyBtldr_SetApplicationStatus(appId)
|
|
: CYRET_ERR_CHECKSUM;
|
|
}
|
|
else if (CYBTLDR_STAT_ERR_CMD == (err ^ (int)CYRET_ERR_BTLDR_MASK))
|
|
{
|
|
/* Single app - restore previous CYRET_SUCCESS */
|
|
err = CYRET_SUCCESS;
|
|
}
|
|
}
|
|
|
|
/* Verify that the entire application is valid */
|
|
else if ((PROGRAM == action || VERIFY == action) && (blVer >= BL_VER_SUPPORT_VERIFY))
|
|
err = CyBtldr_VerifyApplication();
|
|
}
|
|
|
|
CyBtldr_EndBootloadOperation();
|
|
}
|
|
else if (CYRET_ERR_COMM_MASK != (CYRET_ERR_COMM_MASK & err))
|
|
CyBtldr_EndBootloadOperation();
|
|
|
|
CyBtldr_CloseDataFile();
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
int CyBtldr_Program(const char* file, CyBtldr_CommunicationsData* comm, CyBtldr_ProgressUpdate* update)
|
|
{
|
|
return CyBtldr_RunAction(PROGRAM, file, comm, update);
|
|
}
|
|
|
|
int CyBtldr_Erase(const char* file, CyBtldr_CommunicationsData* comm, CyBtldr_ProgressUpdate* update)
|
|
{
|
|
return CyBtldr_RunAction(ERASE, file, comm, update);
|
|
}
|
|
|
|
int CyBtldr_Verify(const char* file, CyBtldr_CommunicationsData* comm, CyBtldr_ProgressUpdate* update)
|
|
{
|
|
return CyBtldr_RunAction(VERIFY, file, comm, update);
|
|
}
|
|
|
|
int CyBtldr_Abort(void)
|
|
{
|
|
g_abort = 1;
|
|
return CYRET_SUCCESS;
|
|
}
|