#include "common.h"
|
#include "common.h"
|
#include "support.h"
|
#include "support.h"
|
#include "net.h"
|
#include "net.h"
|
#include "uart.h"
|
#include "uart.h"
|
#include "spr-defs.h"
|
#include "spr-defs.h"
|
#include "flash.h"
|
#include "flash.h"
|
|
|
#define SOH 0x01
|
#define SOH 0x01
|
#define STX 0x02
|
#define STX 0x02
|
#define EOT 0x04
|
#define EOT 0x04
|
#define ACK 0x06
|
#define ACK 0x06
|
#define NAK 0x15
|
#define NAK 0x15
|
#define CAN 0x18
|
#define CAN 0x18
|
#define C 0x43
|
#define C 0x43
|
|
|
#define CPMEOF 0x1A
|
#define CPMEOF 0x1A
|
|
|
#define RETRY 10
|
#define RETRY 10
|
#define TIMEOUT 3
|
#define TIMEOUT 3
|
|
|
/* update CRC */
|
/* update CRC */
|
unsigned short
|
unsigned short updcrc(register int c, register unsigned int crc)
|
updcrc(register int c, register unsigned int crc)
|
|
{
|
{
|
register int count;
|
register int count;
|
|
|
for (count=8; --count>=0;) {
|
for (count = 8; --count >= 0;) {
|
if (crc & 0x8000) {
|
if (crc & 0x8000) {
|
crc <<= 1;
|
crc <<= 1;
|
crc += (((c<<=1) & 0400) != 0);
|
crc += (((c <<= 1) & 0400) != 0);
|
crc ^= 0x1021;
|
crc ^= 0x1021;
|
}
|
} else {
|
else {
|
|
crc <<= 1;
|
crc <<= 1;
|
crc += (((c<<=1) & 0400) != 0);
|
crc += (((c <<= 1) & 0400) != 0);
|
}
|
}
|
}
|
}
|
return crc;
|
return crc;
|
}
|
}
|
|
|
|
|
static thand_f *mTimeHandler;
|
static thand_f *mTimeHandler;
|
static unsigned long mTimeValue;
|
static unsigned long mTimeValue;
|
static int mTimeoutCount;
|
static int mTimeoutCount;
|
|
|
static unsigned long src_addr;
|
static unsigned long src_addr;
|
|
|
unsigned int length;
|
unsigned int length;
|
unsigned int modemMode = 0, bLen = 128;
|
unsigned int modemMode = 0, bLen = 128;
|
unsigned short mycrc;
|
unsigned short mycrc;
|
unsigned long bno = 0;
|
unsigned long bno = 0;
|
|
|
static void mStartTimeout(void);
|
static void mStartTimeout(void);
|
|
|
void
|
void mSetTimeout(int iv, thand_f * f)
|
mSetTimeout(int iv, thand_f *f)
|
|
{
|
{
|
if(iv == 0)
|
if (iv == 0)
|
mTimeHandler = (thand_f *)0;
|
mTimeHandler = (thand_f *) 0;
|
else {
|
else {
|
mTimeHandler = f;
|
mTimeHandler = f;
|
mTimeValue = get_timer(0) + iv;
|
mTimeValue = get_timer(0) + iv;
|
}
|
}
|
}
|
}
|
|
|
static void
|
static void mStartTimeout(void)
|
mStartTimeout(void)
|
|
{
|
{
|
if(++mTimeoutCount >= RETRY) {
|
if (++mTimeoutCount >= RETRY) {
|
printf("...retry counter exceeded, quitting...\n");
|
printf("...retry counter exceeded, quitting...\n");
|
return;
|
return;
|
} else {
|
} else {
|
printf(".");
|
printf(".");
|
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mStartTimeout);
|
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mStartTimeout);
|
uart_putc(C);
|
uart_putc(C);
|
|
|
}
|
}
|
}
|
}
|
|
|
static void
|
static void mReceiveTimeout(void)
|
mReceiveTimeout(void)
|
|
{
|
{
|
if(++mTimeoutCount >= RETRY) {
|
if (++mTimeoutCount >= RETRY) {
|
uart_putc(NAK);
|
uart_putc(NAK);
|
printf("...");
|
printf("...");
|
return;
|
return;
|
} else {
|
} else {
|
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mReceiveTimeout);
|
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mReceiveTimeout);
|
uart_putc(NAK);
|
uart_putc(NAK);
|
}
|
}
|
}
|
}
|
|
|
int
|
int getBlock(unsigned char t)
|
getBlock(unsigned char t)
|
|
{
|
{
|
unsigned int i = 0, j = 0;
|
unsigned int i = 0, j = 0;
|
unsigned char mybuf[133];
|
unsigned char mybuf[133];
|
unsigned char bNo, nBno;
|
unsigned char bNo, nBno;
|
unsigned long dst_addr;
|
unsigned long dst_addr;
|
|
|
unsigned char flags;
|
unsigned char flags;
|
flags = UART_LSR_FE | UART_LSR_PE | UART_LSR_OE | UART_LSR_BI; /*frame,parity,overrun errors */
|
flags = UART_LSR_FE | UART_LSR_PE | UART_LSR_OE | UART_LSR_BI; /*frame,parity,overrun errors */
|
|
|
mycrc = 0;
|
mycrc = 0;
|
|
|
switch(t) {
|
switch (t) {
|
case SOH:
|
case SOH:
|
for(i = 0; i < 132; i++) {
|
for (i = 0; i < 132; i++) {
|
if((REG8(UART_BASE + UART_LSR) & flags) == flags) {
|
if ((REG8(UART_BASE + UART_LSR) & flags) == flags) {
|
uart_putc(CAN);
|
uart_putc(CAN);
|
}
|
}
|
mybuf[i] = uart_getc();
|
mybuf[i] = uart_getc();
|
}
|
}
|
|
|
bNo = mybuf[0]; /* packet id */
|
bNo = mybuf[0]; /* packet id */
|
nBno = mybuf[1]; /* neg. packet id */
|
nBno = mybuf[1]; /* neg. packet id */
|
|
|
if((bNo == 0x00) && (nBno == 0xff) && (bno == 0)) { /* start block */
|
if ((bNo == 0x00) && (nBno == 0xff) && (bno == 0)) { /* start block */
|
modemMode = 2; /* ymodem */
|
modemMode = 2; /* ymodem */
|
uart_putc(ACK);
|
uart_putc(ACK);
|
uart_putc(C);
|
uart_putc(C);
|
return 1;
|
return 1;
|
}
|
} else if ((0xff - bNo) == nBno) { /* data block */
|
else if((0xff-bNo) == nBno) { /* data block */
|
|
for(i = 2, j = 0; i < 130; i++, j++) {
|
for(i = 2, j = 0; i < 130; i++, j++) {
|
length++;
|
length++;
|
mycrc = updcrc(mybuf[i], mycrc);
|
mycrc = updcrc(mybuf[i], mycrc);
|
dst_addr = src_addr+(bno*0x8000)+((bNo-1)*0x80)+j;
|
dst_addr =
|
|
src_addr + (bno * 0x8000) +
|
|
((bNo - 1) * 0x80) + j;
|
REG8(dst_addr) = mybuf[i];
|
REG8(dst_addr) = mybuf[i];
|
}
|
}
|
|
|
mycrc = updcrc(mybuf[130], mycrc);
|
mycrc = updcrc(mybuf[130], mycrc);
|
mycrc = updcrc(mybuf[131], mycrc);
|
mycrc = updcrc(mybuf[131], mycrc);
|
|
|
if(mycrc == 0) /* CRC match! */ {
|
if (mycrc == 0) { /* CRC match! */
|
uart_putc(ACK);
|
uart_putc(ACK);
|
for(i=0;i < 128; i+=4) {
|
for (i = 0; i < 128; i += 4) {
|
/* for(j=0; j<4; j++) {
|
/* for(j=0; j<4; j++) {
|
tmp = tmp << 8;
|
tmp = tmp << 8;
|
tmp |= mybuf[i+j+2];
|
tmp |= mybuf[i+j+2];
|
}
|
}
|
dst_addr = src_addr+(bno*0x8000)+((bNo-1)*128)+i;
|
dst_addr = src_addr+(bno*0x8000)+((bNo-1)*128)+i;
|
fl_word_program(dst_addr, tmp);*/
|
fl_word_program(dst_addr, tmp); */
|
}
|
}
|
if(bNo == 0xff)
|
if (bNo == 0xff)
|
bno++;
|
bno++;
|
return 1;
|
return 1;
|
}
|
} else {
|
else {
|
|
uart_putc(NAK);
|
uart_putc(NAK);
|
return -1;
|
return -1;
|
}
|
}
|
}
|
} else { /* packet id didn't match neg packet id! */
|
else { /* packet id didn't match neg packet id! */
|
|
uart_putc(NAK);
|
uart_putc(NAK);
|
return -1;
|
return -1;
|
}
|
}
|
return 1;
|
return 1;
|
break;
|
break;
|
case EOT:
|
case EOT:
|
if(modemMode == 2) {/* ymodem */
|
if (modemMode == 2) { /* ymodem */
|
uart_putc(NAK);
|
uart_putc(NAK);
|
if(uart_getc() == EOT) {
|
if (uart_getc() == EOT) {
|
uart_putc(ACK);
|
uart_putc(ACK);
|
uart_putc(C);
|
uart_putc(C);
|
}
|
} else
|
else
|
|
uart_putc(ACK);
|
uart_putc(ACK);
|
} else /* zmodem */
|
} else /* zmodem */
|
uart_putc(ACK);
|
uart_putc(ACK);
|
|
|
return 0;
|
return 0;
|
break;
|
break;
|
default:
|
default:
|
/* Unknown header */
|
/* Unknown header */
|
uart_putc(NAK);
|
uart_putc(NAK);
|
return -1;
|
return -1;
|
}
|
}
|
}
|
}
|
|
|
int
|
int mGetData(unsigned long saddr)
|
mGetData(unsigned long saddr)
|
|
{
|
{
|
int retval = 1;
|
int retval = 1;
|
unsigned char c;
|
unsigned char c;
|
|
|
length = 0;
|
length = 0;
|
src_addr = saddr;
|
src_addr = saddr;
|
modemMode = 1;
|
modemMode = 1;
|
bno = 0;
|
bno = 0;
|
|
|
printf("src_addr: 0x%lx\n", src_addr);
|
printf("src_addr: 0x%lx\n", src_addr);
|
if(fl_init() != 0) {
|
if (fl_init() != 0) {
|
printf("Flash init failed!\n");
|
printf("Flash init failed!\n");
|
return(-1);
|
return (-1);
|
}
|
}
|
|
|
#if 0
|
#if 0
|
printf("Unlocking flash...");
|
printf("Unlocking flash...");
|
for (i = 0, c = FLASH_BASE_ADDR; i < (FLASH_SIZE / FLASH_BLOCK_SIZE);
|
for (i = 0, c = FLASH_BASE_ADDR; i < (FLASH_SIZE / FLASH_BLOCK_SIZE);
|
i++, c += FLASH_BLOCK_SIZE)
|
i++, c += FLASH_BLOCK_SIZE)
|
if (fl_unlock_one_block (c)) return 1;
|
if (fl_unlock_one_block(c))
|
|
return 1;
|
printf("done\n");
|
printf("done\n");
|
|
|
printf("Erasing flash...");
|
printf("Erasing flash...");
|
for (i = 0, c = FLASH_BASE_ADDR; i < (FLASH_SIZE / FLASH_BLOCK_SIZE);
|
for (i = 0, c = FLASH_BASE_ADDR; i < (FLASH_SIZE / FLASH_BLOCK_SIZE);
|
i++, c += FLASH_BLOCK_SIZE)
|
i++, c += FLASH_BLOCK_SIZE)
|
if (fl_block_erase (c)) return 1;
|
if (fl_block_erase(c))
|
|
return 1;
|
printf ("done\n");
|
printf ("done\n");
|
#endif
|
#endif
|
printf("Waiting...");
|
printf("Waiting...");
|
|
|
mTimeoutCount = 0;
|
mTimeoutCount = 0;
|
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mStartTimeout);
|
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mStartTimeout);
|
|
|
while(1) {
|
while (1) {
|
if(mTimeHandler && (get_timer(0) > mTimeValue)) {
|
if (mTimeHandler && (get_timer(0) > mTimeValue)) {
|
thand_f *x;
|
thand_f *x;
|
x = mTimeHandler;
|
x = mTimeHandler;
|
mTimeHandler = (thand_f *)0;
|
mTimeHandler = (thand_f *) 0;
|
(*x)();
|
(*x) ();
|
}
|
}
|
c = uart_testc();
|
c = uart_testc();
|
if(c != 0)
|
if (c != 0)
|
break;
|
break;
|
}
|
}
|
|
|
while(retval != 0) {
|
while (retval != 0) {
|
retval = getBlock(c);
|
retval = getBlock(c);
|
if(retval != 0)
|
if (retval != 0)
|
c = uart_getc();
|
c = uart_getc();
|
}
|
}
|
|
|
if(modemMode == 2) {
|
if (modemMode == 2) {
|
c = uart_getc();
|
c = uart_getc();
|
retval = getBlock(c); /* last 'dummy' block for YModem */
|
retval = getBlock(c); /* last 'dummy' block for YModem */
|
printf("... protocol: YModem, ");
|
printf("... protocol: YModem, ");
|
}
|
} else
|
else
|
|
printf("... protocol: ZModem, ");
|
printf("... protocol: ZModem, ");
|
return length;
|
return length;
|
}
|
}
|
|
|