char *xmodemReceive(int fnbr) { unsigned char xbuff[X_BUF_SIZE]; unsigned char *p; unsigned char trychar = NAK; //'C'; unsigned char packetno = 1; int i, c; int retry, retrans = MAXRETRANS; // first establish communication with the remote while(1) { for( retry = 0; retry < 16; ++retry) { if(trychar) MMputchar(trychar); if ((c = _inbyte((DLY_1S)<<1)) >= 0) { switch (c) { case SOH: goto start_recv; case EOT: flushinput(); MMputchar(ACK); return ""; // no more data case CAN: flushinput(); MMputchar(ACK); return "Cancelled by remote"; break; default: break; } } } flushinput(); MMputchar(CAN); MMputchar(CAN); MMputchar(CAN); return "Remote did not respond"; // no sync start_recv: trychar = 0; p = xbuff; *p++ = SOH; for (i = 0; i < (X_BLOCK_SIZE+3); ++i) { if ((c = _inbyte(DLY_1S)) < 0) goto reject; *p++ = c; } if (xbuff[1] == (unsigned char)(~xbuff[2]) && (xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno-1) && check(&xbuff[3], X_BLOCK_SIZE)) { if (xbuff[1] == packetno) { for(i = 0 ; i < X_BLOCK_SIZE ; i++) MMfputc(xbuff[i + 3], fnbr); ++packetno; retrans = MAXRETRANS+1; } if (--retrans <= 0) { flushinput(); MMputchar(CAN); MMputchar(CAN); MMputchar(CAN); return "Too many errors in transmission"; } MMputchar(ACK); continue; } reject: flushinput(); MMputchar(NAK); } }
char *xmodemTransmit(int fnbr) { unsigned char xbuff[X_BUF_SIZE]; unsigned char packetno = 1; int i, c, len = 0; int retry; // first establish communication with the remote while(1) { for( retry = 0; retry < 16; ++retry) { if ((c = _inbyte((DLY_1S)<<1)) >= 0) { switch (c) { case NAK: // start sending goto start_trans; case CAN: if ((c = _inbyte(DLY_1S)) == CAN) { MMputchar(ACK); flushinput(); return "Cancelled by remote"; } break; default: break; } } } MMputchar(CAN); MMputchar(CAN); MMputchar(CAN); flushinput(); return "Remote did not respond"; // no sync // send a packet while(1) { start_trans: memset (xbuff, 0, X_BUF_SIZE); // start with an empty buffer xbuff[0] = SOH; // copy the header xbuff[1] = packetno; xbuff[2] = ~packetno; for(len = 0; len < 128 && !MMfeof(fnbr); len++) { xbuff[len + 3] = MMfgetc(fnbr); // copy the data into the packet } if (len > 0) { unsigned char ccks = 0; for (i = 3; i < X_BLOCK_SIZE+3; ++i) { ccks += xbuff[i]; } xbuff[X_BLOCK_SIZE+3] = ccks; // now send the block for (retry = 0; retry < MAXRETRANS && !MMAbort; ++retry) { // send the block for (i = 0; i < X_BLOCK_SIZE+4 && !MMAbort; ++i) { MMputchar(xbuff[i]); } // check the response if ((c = _inbyte(DLY_1S)) >= 0 ) { switch (c) { case ACK: ++packetno; goto start_trans; case CAN: // canceled by remote MMputchar(ACK); flushinput(); return "Cancelled by remote"; break; case NAK: // receiver got a corrupt block default: break; } } } // too many retrys... give up MMputchar(CAN); MMputchar(CAN); MMputchar(CAN); flushinput(); return "Too many errors in transmission"; } // finished sending - send end of text else { for (retry = 0; retry < 10; ++retry) { MMputchar(EOT); if ((c = _inbyte((DLY_1S)<<1)) == ACK) break; } flushinput(); if(c == ACK) return ""; return "Error closing communications"; } } } }
int main ( void ) { int c, esc = 0; char buf [20]; /* current line */ char lbuf [20]; /* last line */ int i = 0; int li = 0; int j; /* Enable the UART FIFO */ *(unsigned int *) ADR_AMBER_UART0_LCRH = 0x10; printf("%cAmber Boot Loader v%s\n", 0xc, AMBER_FPGA_VERSION ); /* 0xc == new page */ /* When ADR_AMBER_TEST_SIM_CTRL is non-zero, its a Verilog simulation. The ADR_AMBER_TEST_SIM_CTRL register is always 0 in the real fpga The register is in vlog/system/test_module.v */ if ( *(unsigned int *) ADR_AMBER_TEST_SIM_CTRL ) { load_run(*(unsigned int *) ADR_AMBER_TEST_SIM_CTRL, 0); } /* Print the instructions */ print_help(); printf("Ready\n> "); /* Loop forever on user input */ while (1) { if ((c = _inbyte (DLY_1S)) >= 0) { /* Escape Sequence ? */ if (c == 0x1b) esc = 1; else if (esc == 1 && c == 0x5b) esc = 2; else if (esc == 2) { esc = 0; if (c == 'A') { /* Erase current line using backspaces */ for (j=0;j<i;j++) _outbyte(0x08); /* print last line and make current line equal to last line */ for (j=0;j<li;j++) _outbyte(buf[j] = lbuf[j]); i = li; } continue; } else esc = 0; /* Character not part of escape sequence so print it and add it to the buffer */ if (!esc) { _outbyte (c); /* Backspace ? */ if (c == 8 && i > 0) { i--; } else { buf[i++] = c; } } /* End of line ? */ if (c == '\r' || i >= 19) { if (i>1) { /* Copy current line buffer to last line buffer */ for (j=0;j<20;j++) lbuf[j] = buf[j]; li = i-1; } buf[i] = 0; i = 0; /* Process line */ printf("\n"); parse( buf ); printf("> "); } } } }