?? cal_ldr.c
字號:
/***************************************************************************
* This code and information is provided "as is" without warranty of any *
* kind, either expressed or implied, including but not limited to the *
* implied warranties of merchantability and/or fitness for a particular *
* purpose. *
* *
* Copyright (C) 2006 Teridian SemiConductor, Corporation. *
* All Rights Reserved. *
* *
***************************************************************************/
//**************************************************************************
// DESCRIPTION: 71M6521B Calibration Loader.
//
// AUTHOR: MTF
//
// HISTORY: See end of file.
//**************************************************************************
// File: Cal_ldr.C
//
//**************************************************************************
#include "options.h" // Has the serial configurations etc.
#if CAL_LDR
#include "ce.h" //
#include "calibration.h"//
#include "eeprom.h" //
#include "io.h" //
#include "library.h" //
#include "main.h" //
#include "oscope.h" //
#include "rtc.h" //
#include "meter.h" //
#include "sfrs.h" //
#include "cal_ldr.h" // Include Loader (80515).
#define ERR_MSG_MAX 10
#define XON 0x11
#define XOFF 0x13
// local compilation flags
#define SER_ERROR 0
#define CE_PARMS_DBG CONSTANTS_DBG
#define VERIFY_DBG 1
#define SFR_ACCESS 0
/*** External functions used within this module ***/
// Check includes.
/*** External variables used within this module ***/
// None.
/*** Public functions declared within this module ***/
// None.
/*** Public variables declared within this module ***/
// None.
/*** Private functions declared within this module ***/
static bool GetHeader (void);
static bool GetChksum (void);
/*** Private variables declared within this module ***/
#define sbf 32
static uint8x_t NV_Data[ sbf ];
static uint8x_t * data pData;
static uint8_16_t data Addr;
static uint8_t data ByteCnt, RecTyp, ChkSum;
static uint8_t data err_cnt, tick;
//===========================================================================//
#if CE_PARMS_DBG
// Make CE defaults visible to the AMD-51 ICE.
// Note, if this code is enabled, overlap errors occur in the link,
// but they do not cause defective operation.
#define ce_parms_visible() get_ce_parms ()
#else
#define ce_parms_visible()
#endif
#if SER_ERROR
static bool err_cnt_chk (void)
{
return (err_cnt < ERR_MSG_MAX);
}
static void Bad (void)
{
start_tx_rslt ("Error @ Addr. ");
putc (':');
snd_hex (ByteCnt);
snd_hex (Addr.c[ HI ]);
snd_hex (Addr.c[ LO ]);
putc (' ');
snd_hex (RecTyp);
err_cnt++;
if (!err_cnt_chk ())
start_tx_rslt (". . . \r\nToo many errors\r\n");
}
#endif
static void parse_header()
{
uint8_t c;
#if !CLI
putc (XON); // Crude XON/XOFF protocol when no buffering
#endif
do {
c = getc ();
if (c == '\r') // receive a 'CR', do something to prove it's alive
putc('*');
} while (c != ':' && !io_timeout);
if (!io_timeout)
{
ByteCnt = rcv_hex ();
Addr.c[ HI ] = rcv_hex ();
Addr.c[ LO ] = rcv_hex ();
RecTyp = rcv_hex ();
ChkSum = ByteCnt + Addr.c[ HI ] + Addr.c[ LO ] + RecTyp;
/* if (DATA_REC == RecTyp) RecTyp = WRITE_CE_REC; */
#if SER_ERROR
if (ByteCnt > sbf)
{
Bad();
start_tx_rslt(". byte count > 32\r\n");
ByteCnt = sbf;
}
#endif
}
}
#if SER_ERROR
static void Bad_Record()
{
Bad ();
if (!err_cnt_chk ())
start_tx_rslt (". Bad checksum\r\n");
}
#endif
static void GetData(void)
{
uint8_t d, n;
pData = NV_Data - 1;
for(n = ByteCnt; n != 0 && !io_timeout; --n)
{
d = rcv_hex ();
if (!io_timeout)
{
*(++pData) = d; /* Store data byte. */
ChkSum += d; /* Update checksum. */
}
}
}
static void Write(void)
{
switch(RecTyp)
{
default:
break;
case WRITE_CE_REC:
case DATA_REC:
memcpy_cex ((int32x_t *) (Addr.i),
(int32x_t *) NV_Data, ByteCnt / sizeof (int32_t));
break;
case WRITE_MPU_REC:
memcpy_xx ((uint8x_t *) Addr.i, NV_Data, ByteCnt);
break;
#if REAL_TIME_DATE
case WRITE_RTC_REC:
/* Set new current time. */
memcpy_xx ((uint8x_t *) Addr.i, NV_Data, ByteCnt);
RTClk_Write ();
break;
#endif
#if SFR_ACCESS
case WRITE_SFR_REC:
{
uint8_t n;
pData = NV_Data - 1;
for(n = ByteCnt; n != 0; --n)
{
SFR_Write (Addr.c[ LO ]++, *++pData);
}
}
break;
#endif
}
}
static void Read(void)
{
switch(RecTyp)
{
default:
break;
case READ_CE_REC:
memcpy_xce ((int32x_t *) NV_Data,
(int32x_t *) (Addr.i), ByteCnt / sizeof (int32_t));
break;
case READ_MPU_REC:
memcpy_xx (NV_Data, (uint8x_t *) Addr.i, ByteCnt);
break;
case READ_CODE_REC:
memcpy_xr (NV_Data, (uint8r_t *) Addr.i, ByteCnt);
break;
#if REAL_TIME_DATE
case READ_RTC_REC:
/* Read new current time. */
RTClk_Read ();
memcpy_xx (NV_Data, (uint8x_t *) Addr.i, ByteCnt);
break;
#endif
#if SFR_ACCESS
case READ_SFR_REC:
{
uint8_t n;
pData = NV_Data - 1;
for(n = ByteCnt; n != 0; --n)
{
*++pData = SFR_Read (Addr.c[ LO ]++);
}
}
break;
#endif
}
}
static void PutData()
{
uint8_t d, n;
pData = NV_Data;
for(n = ByteCnt; n != 0; --n)
{
d = *(pData++);
snd_hex (d);
ChkSum += d; /* Update checksum. */
}
}
static void PutHeader(void)
{
snd_crlf ();
putc (':');
ChkSum = ByteCnt;
snd_hex (ByteCnt);
putc (' ');
ChkSum += Addr.c[ HI ];
snd_hex (Addr.c[ HI ]);
ChkSum += Addr.c[ LO ];
snd_hex (Addr.c[ LO ]);
putc (' ');
ChkSum += RecTyp - 1;
snd_hex (RecTyp - 1);
putc (' ');
}
static void PutChksum(void)
{
putc (' ');
snd_hex ( -ChkSum );
}
//===========================================================================//
void cal_ldr (void)
{
#if SER_ERROR
err_cnt = 0;
#endif
io_timeout = FALSE; // restart timeouts
while (GetHeader ()) // Look for ":ccaaaa0x.."
{
if (READ == (RecTyp & RWB))
{
if (GetChksum ())
{
Read ();
PutHeader();
PutData();
PutChksum();
}
}
else // if (WRITE == (RecTyp & RWB)).
{
GetData(); // Look for "..dd..ddss[<cr>][<lf>]"
if (GetChksum ())
Write ();
}
}
rcv_hex (); // Flush EOF record checksum byte.
if (!io_timeout) // do -not- save during a timeout
{
cal_save (); // Preserve calibration values.
#if VERIFY_DBG
cal_restore (); // Verify non-volatile write.
#endif
}
snd_crlf (); // indicate exit of mode in a harmless way
io_timeout = FALSE; // restart timeouts
}
bool GetHeader (void)
{
do
{ // Process '00' thru '09' type records.
parse_header ();
} while ((RecTyp > MAX_REC) && !io_timeout);
return ((EOF_REC != RecTyp) && !io_timeout);
}
bool GetChksum (void)
{
uint8_t cs;
// snd_crlf ();
cs = rcv_hex ();
#if !CLI
putc (XOFF); // Crude XON/XOFF protocol when no buffering
#endif
if (0xFF == cs)
ChkSum = 0;
else
ChkSum += cs;
if (ChkSum)
{
#if SER_ERROR
if (err_cnt_chk ())
{
Bad_Record (); // Notify of bad checksum.
}
#endif
putc ('?');
return (FALSE);
}
else
{ // OK record.
putc ('!');
return (TRUE);
}
}
/***************************************************************************
* History: *
* $Log: cal_ldr.c,v $
* Revision 1.9 2006/10/10 23:05:51 tvander
* Added "read code" feature to read the software's ID. Protocol timeouts no longer write the configuration to EEPROM.
*
* Revision 1.8 2006/08/16 23:49:27 tvander
* Now echoes CR as * (asterisk), so a user can tell if the serial link is running.
* The CR LF at the end of each record received was causing the status to go off
* the upper edge of the screen. Removed the CR LF in this case.
* An output record now starts with a CR LF sequence, so the records still line up.
*
* Revision 1.7 2006/07/31 18:03:18 tvander
* Fixed timeout logic's itnegration with the CLI
*
* Revision 1.6 2006/07/28 02:45:23 tvander
* Fixed missing XON
*
* Revision 1.5 2006/07/25 00:27:59 tvander
* Added timeout
*
* Revision 1.4 2006/07/19 01:53:08 tvander
* Modified to do XON/XOFF
*
* Revision 1.3 2006/06/06 03:54:55 tvander
* Calibration loader compiles ok when real time clock is disabled.
*
* Revision 1.2 2006/05/27 01:35:04 tvander
* *** empty log message ***
*
* Revision 1.1 2006/05/25 03:24:12 tvander
* Added timeouts to EEPROMs. Tested all three.
* Newly ported calibration loader, compiles without error.
* RTC setting uses a software timer (less code, also frees tmr1)
*
* Revision 1.12 2006/05/19 01:52:22 gmikef
* *** empty log message ***
*
* Revision 1.11 2006/05/17 03:02:23 gmikef
* *** empty log message ***
*
* Revision 1.10 2006/05/12 03:30:41 gmikef
* *** empty log message ***
*
*
* *
* Copyright (C) 2006 Teridian Semiconductor Corp. All Rights Reserved. *
* this program is fully protected by the United States copyright *
* laws and is the property of Teridian Semiconductor Corporation. *
***************************************************************************/
#endif // CAL_LDR
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -