Skip to content

Xmodem Loader -ick

February 8, 2017

17-02-08-horrible-xmodemAt close of day today I have a horrible xmodem client and a horrible xmodem sender that work horribly together. I’ve reduced serial speed to 9600 baud once the 1802 is running but i have no idea whether that mattered in the end.  I would much rather be using stolen code but there are just too many moving pieces.  I kind of hope once I debug this i’ll be able to drop back to something pre-made.

//ssxload super simple xmodem loader
//loads a single 32 byte block with checksum from a custom host program
//17-02-08 timeout on initial receives
#include <nstdlib.h>
#include <olduino.h>
#include <cpu1802spd4port7.h>
#include "xloader.h"
unsigned char buff[64];
unsigned char packetno=1;

void main(){
	int chorto='?';
	unsigned int naks=0;
	unsigned char cks=0;
	unsigned int nch=0,i=0, tries=3;
	while (tries-->0 && chorto!=SOH){
		putch(NAK); //send NAK to start
		chorto=getchOrTo(1000);
	}

	while(chorto>0 && chorto!=EOT){
		switch (chorto){
		case SOH:
			nch=0;
			while(nch<35 &chorto>=0){
				chorto=getchorto(500);
				buff[nch++]=chorto;
			}
			if ((buff[0]==packetno)&&(buff[1]==(unsigned char)~packetno)){
				putch(ACK);
				packetno++;
				//naks=0;
			}else{
				putch(NAK);
				//naks++;
			}
			break;
		case EOT:
			putch(ACK);
			break;
		default:
			putch(NAK);
		}
		chorto=getchorto(1000);
	}
	delay(3500);//let python clear out
	dump(buff,35);
	if (chorto<0){
		printf("\ntimeout\n");
	} else{
		printf("\n last rxd %c\n",chorto);
		for (i=2;i<2+32;i++){
			cks+=buff[i];
			//printf("%d %d %d\n",i,buff[i],cks);
		}
		if (buff[2+32]==cks){
			printf("cksum pass\n");
		}else{
			printf("cksum fail read %d calc %d\n",buff[2+32],cks);
		}
	}
	while(1);
}
#include <nstdlib.c>
#include <olduino.c>

 

from __future__ import print_function
import sys
import logging
logging.basicConfig()
import serial
try:
    from cStringIO import StringIO
except:
    from StringIO import StringIO
from time import sleep
import os
if len(sys.argv)>1:
    filename=sys.argv[1]
else:
    filename="test32.txt"
fileSize=os.path.getsize(filename)
print ("File Size is",fileSize)

def xmodem_send(serial, file):
	t=0
	#	t, anim ='|/-\\'
	while 1:
	    if serial.read(1) != 'N':
		t = t + 1
		print ('.')
		if t == 60 : return False
	    else:
		break

	p = 1
	s = file.read(32)
	while s:
	    s = s + '\xFF'*(32 - len(s))
	    chk = 0
	    for c in s:
		chk+=ord(c)
		#print (c,ord(c),chk,chk%256)
	    while 1:
		serial.write('S') #SOH)
		serial.write(chr(p))
		serial.write(chr(255 - p))
		serial.write(s)
		serial.write(chr(chk%256))
		serial.flush()
		print ('checksum is ',chk%256,chr(chk%256))
		answer = serial.read(1)
		if  answer == 'N': continue
		if  answer == 'K': break
		return False
	    s = file.read(32)
	    p = (p + 1)%256
	    print ('.')
	serial.write('T')
	return True

#Main program starts here - define the serial port, set RTS off, then open it
#open the file to be loaded
stream = open(filename,'rb')

port = serial.Serial(parity=serial.PARITY_NONE,
                     bytesize=serial.EIGHTBITS,
                     stopbits=serial.STOPBITS_ONE,timeout=10,xonxoff=0,
                     rtscts=0,dsrdtr=0,baudrate=9600)
port.rts=False
port.port='COM3'
port.open()
port.rts=True
sleep(0.001)
port.rts=False
port.flushInput()
#transfer the file
result=xmodem_send(port, stream)

stream.close()
port.close()

if result:
    print ("\ntransfer successful")
    sleep(.25)
else:
    print ("\ntransfer unsuccessful")
    #x=raw_input("press enter to continue...");

typedef unsigned char uint8_t;
#define SOH  'S' //0x01
#define STX  0x02
#define EOT  'T' //0x04
#define ACK  'K' //0x06
#define NAK  'N' //0x15
#define CAN  0x18
#define CTRLZ 0x1A
uint8_t getch(){
	uint8_t c;
	out(7,0); //request read of the fifo
	c=inp(7);
	return c;//return the data
}
int seravail(){//see if there's data available
	out(7,0x12); //read the fifo depth
	return inp(7);
}
void putch(uint8_t c){ //filter characters for avr passthru
	if (0==c | 0x27==c){//cases that need to be escaped
		out(7,0x27);
	}
	out(7,c);
}
int getchOrTo(unsigned int retries){//get a character or time out
    while(retries>0){
		if (seravail()==0){
			retries--;
		}else{
			return getch();
		}
	}
	return -1; //return -1 for timeout
}
void dump(unsigned char* data, unsigned int len){
	unsigned int row,col;
	printf("dumping %d bytes at %x\n",len,data);
	for (row=0;row<(len+8);row+=8){
		printf("%x ",row);
		for (col=0;col<8;col++){
			printf("%cx ",data[row+col]);
		}
		printf("\n");
	}
}
Advertisements

From → Uncategorized

Leave a Comment

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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: