home *** CD-ROM | disk | FTP | other *** search
- /* DLCMD.C -- Commands for DSP CARD 4 downloader
- *
- * Copyright (C) by Alef Null 1992, 1993, 1994
- * Author(s): Jarkko Vuori, OH2LNS
- * Modification(s):
- */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <string.h>
- #include <time.h>
- #include <signal.h>
- #include "utils.h"
- #include "dl.h"
-
-
- #define RETRIES 3
-
-
- static int port = 1;
-
- typedef enum {
- PGM_FLASH, // commands to DSP CARD
- CHG_PGM,
- READ_FLASH,
- LOAD_GO,
-
- ACK, // responses
- BAD_CRC,
- NO_FLASH,
- ERASE_ERR,
- PGM_ERR,
- NO_PGM,
- } CardCommand;
-
- const unsigned long wakeUp = 314159265; // special wake-up sequence
- const unsigned char flag = 0x7e; // msgblock flag byte (01111110)
-
-
- /*
- * Wait (max 3s) for a character from the serial port
- *
- * returns -1 if there is no character
- */
- static int WaitSerial(void) {
- unsigned long start;
- int c;
-
- #define BIOS_TIMER (volatile unsigned long far *)(0x46c)
-
- /* wait until timer changes its state */
- start = *BIOS_TIMER;
- while (start+54L != *BIOS_TIMER) // 54.9ms*54=3s
- if ((c = ReadSerial()) != -1)
- return (c);
-
- return (-1);
- }
-
- /*
- * Wait for ACK from the DSP CARD 4
- */
- static Bool waitAck(char *errortext[]) {
- static char *errtxt[] = {
- "Bad CRC",
- "No FLASH EPROM chip on the board",
- "FLASH EPROM erase error",
- "FLASH EPROM program error",
- "No such program"
- };
- static char unknownerr[80];
- int c;
-
- if ((c = WaitSerial()) == -1) {
- *errortext = "No response from the DSP CARD 4";
- return (False);
- }
- if (c != ACK) {
- if (c >= BAD_CRC && c < BAD_CRC+sizeof(errtxt)/sizeof(char *))
- *errortext = errtxt[c-BAD_CRC];
- else {
- sprintf(unknownerr, "Unknown error code %d from the DSP CARD 4", c);
- *errortext = unknownerr;
- }
-
- return (False);
- }
-
- return (True);
- }
-
- /*
- * Reset DSP CARD 4 and give a command to it
- */
- static Bool giveCommand(CardCommand cmd) {
- int retryCount = 0;
- char *errortext;
-
- /* first wake up DSP CARD */
- while (retryCount++ < RETRIES) {
- while (ReadSerial() != -1); // flush any garbage before possible ack
- WriteSerial((int)(wakeUp >> 24)); WriteSerial((int)(wakeUp >> 16)); WriteSerial((int)(wakeUp >> 8)); WriteSerial((int)wakeUp);
- if (!waitAck(&errortext))
- continue;
-
- /* then send given command */
- WriteSerial(cmd);
- if (waitAck(&errortext))
- return (True);
- }
-
- fprintf(stderr, "%s\n", errortext);
- return (False);
- }
-
- /*
- * Send one datablock to the DSP CARD 4
- */
- static Bool sendBlock(BLKHEADER *pHeader, long huge *data) {
- struct msgblk {
- unsigned char flag; // preamble
- BLKHEADER header; // standard data block header
- unsigned char data; // data itself (continues after this block)
- } *msg;
- unsigned msglen, check;
- int retryCount = 0;
- char *errortext;
-
- /* first calculate the lenght of messageblock */
- msglen = sizeof(struct msgblk)-sizeof(unsigned char)+3*pHeader->len+sizeof(unsigned);
-
- /* then setup message block */
- if ((msg = (struct msgblk *)malloc(msglen)) != NULL) {
- register long huge *sp;
- register unsigned char *dp;
-
- msg->flag = flag;
- msg->header = *pHeader;
- /* copy the data itself (24-bit words to bytes) */
- for (sp = data, dp = &msg->data; sp < &data[pHeader->len]; sp++) {
- *dp++ = (unsigned char)(*sp >> 16);
- *dp++ = (unsigned char)(*sp >> 8);
- *dp++ = (unsigned char)*sp;
- }
- /* convert message block to big-endian format */
- swab((char *)&msg->header.address, (char *)&msg->header.address, sizeof(unsigned)); swab((char *)&msg->header.len, (char *)&msg->header.len, sizeof(unsigned));
- /* finally calculate the checkword */
- check = ~crc((unsigned char *)msg, msglen-sizeof(unsigned));
-
- /* then send it */
- while (retryCount++ < RETRIES) {
- for (dp = (unsigned char *)msg; dp < (unsigned char *)msg+msglen-sizeof(unsigned); dp++)
- WriteSerial(*dp);
- WriteSerial(check); WriteSerial(check >> 8);
-
- /* then wait for ACK */
- if (waitAck(&errortext)) {
- free(msg);
- return (True);
- }
- }
-
- fprintf(stderr, "%s\n", errortext);
- free(msg);
- }
-
- return (False);
- }
-
- Bool cdecl setport(FILE *files[], int numArg) {
- port = numArg;
-
- return (True);
- }
-
- Bool cdecl loadandgo(FILE *files[]) {
- static BLKHEADER termBlk = { p, 0, 0 };
- Bool fResult = True;
-
- /* we manipulate interrupt vectors in serial port handler, so ignore ctrl-c */
- signal(SIGINT, (void (cdecl *)())SIG_IGN);
- if (!OpenSerial(port, 9600)) {
- fResult = False; goto endload;
- }
-
- /* then download it to the DSP CARD 4 */
- if (!giveCommand(LOAD_GO) || !ReadBlocks(files[0], sendBlock)) {
- fResult = False; goto endload;
- }
-
- /* finally start the program execution (by sending len=0 datablock) */
- if (!sendBlock(&termBlk, NULL))
- fResult = False;
-
- endload:
- CloseSerial();
- signal(SIGINT, SIG_DFL);
-
- return (fResult);
- }
-