Skip to content

Xmodem Receiver Working!

February 12, 2017

17-02-12-stamps17-02-12-error-recoveryWell Thank heavens. The problem came down to the AVR missing the trigger signal that the 1802 was writing to the shift register. I knew this was a risk but I didn’t know what the symptoms would be. As it happens, the most common failure was for the AVR to miss a write that was meant to trigger a read from the host serial buffer. The 1802 would get whatever was in the shift register and the character would stay in the buffer so the 1802 would get extra characters in the block. Because I wasn’t doing any error checking the 1802 ended up trying to read an extra block at the end of transmission. I had been gathering everything i needed to do simple error checking but not using it. A little bit of poking at the code and it’s fine now – the server was always ready to re-transmit so no problem there. I think I could cut down the error frequency a lot by using a flag to tell the 1802 rather than in-band signalling but i’m going to leave it for now. It’s good to have a constant stream of errors to exercise the code. In the dos box above you can see the re-transmission of one block of four in a 512 byte file.

In the horrible code below the readblk routine had been storing the block sequence numbers and the checksum and the main routine displayed them at the end. I changed it to calculate its own checksum and verify that along with the block numbers. The main routine just had to check the return code before ACK-ing the block. There’s an explicit check for the SOH character as well now although it just ignores other characters until it finds one. All of that stuff can come out now along with the places where i had stuck in seq/req sequences to help me trace things with the logic analyzer.


//ssxload super simple xmodem loader
//17-02-08 timeout on initial receives
//17-02-09 no timeouts, single start ack, no error checking
//17-02-09 header read moved into main
//17-02-12 block level error checking and NAK
#include <nstdlib.h>
#include <olduino.h>
#include <cpu1802spd4port7.h>
#include "xloader.h"
#define blocksize 128
unsigned char target[1024];
unsigned char blkno, hdr[256],bseq[256],iseq[256],ciseq[256],csum[256],calcsum[256],valid[256];
int readblk(unsigned char * where){//read a block
	unsigned int cnt=blocksize;
	unsigned char ch,calcchk=0,rc=0;
	ch=readch(); //read the checksum
	csum[blkno]=ch; //save it
	if (calcchk!=ch){//check it
	if (bseq[blkno]!=(blkno+1)){
	if (iseq[blkno]!=(254-blkno)){
	return rc;

void main(){
	int ch='?',eot=0;
	unsigned char *t=target;
	unsigned int i;
	unsigned char thishdr;
	asm(" seq\n nop\n req\n");
	putch(NAK); //send NAK to start
	thishdr=readch(); //get the header character
		if (SOH==thishdr){
			if (0==valid[blkno]){

		asm(" seq\n nop\n req\n seq\n nop\n req\n");
		asm(" seq\n nop\n req\n");
//and we're done - god willing

	delay(5000);//let python clear out
	printf("terminating header was %d\n",thishdr);
	printf("number of blocks %d\n",blkno);
	printf("bb hh:bn/in c:i r:cs c:cs valid?\n");
	for (i=0;i<blkno;i++){
		printf("%cx %cx:%cx/%cx c:%cx r:%cx c:%cx %d\n",i,hdr[i],bseq[i],iseq[i],ciseq[i],csum[i],calcsum[i],valid[i]);
#include <nstdlib.c>
#include <olduino.c>


From → Uncategorized

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: