OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [services/] [modem.c] - Rev 566

Go to most recent revision | Compare with Previous | Blame | View Log

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

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.