Skip to content

Turtles! All The Way Down!

January 24, 2017

I’ve been working on a way to use an 1806 in the olduino.  The 1806 lacks a load mode so I need a boot loader in ROM.  Hoping to continue using avrdude on the windows host, I’m porting the AVRISP loader program that currently runs in the onboard AVR to run on the 1802. This gets really trippy because that AVR code is still in the loop with the same datastream flowing through it but it won’t notice as long as I don’t reset the processors.

The code is a hopeless spaghetti mishmash at the moment but if i can get it to work I’m sure i can whittle it down.

void avrisp() {
  uint8_t data, low, high, gc;
  uint8_t ch =inp(7);    //cout<<"<"<<_HEX(ch)<<" ";
  switch (ch) {
  case '?': //debug
    doitall();
    break;
  case '!': //run
    printf("!=run\n");
    run1802();
    break;
  case '0': // signon
    empty_reply();
    break;
  case '1':
    gc=inp(7);
    if (gc == CRC_EOP) {
      out (7,STK_INSYNC);
      printf("AVR ISP");
      out(7,(char) STK_OK);
    }
    break;
  case 'A':
    gc=inp(7);
    get_version(gc);
    break;
  case 'B':
    readbytes(20);
    set_parameters();
    empty_reply();
    break;
  case 'E': // extended parameters - ignore for now
    readbytes(5);
    empty_reply();
    break;

  case 'P':
    start_pmode();
    empty_reply();
    break;
  case 'U':
    here = inp(7) + 256 * inp(7);
    sethere_1802();
    //cout<<"here="<<_HEX(here);
    empty_reply();
    break;

  case 0x60: //STK_PROG_FLASH
    low = inp(7);
    high = inp(7);
    empty_reply();
    break;
  case 0x61: //STK_PROG_DATA
    data = inp(7);
    empty_reply();
    break;

  case 0x64: //STK_PROG_PAGE
    program_page();
    break;

  case 0x74: //STK_READ_PAGE
    read_page();
    break;

  case 'V':
    universal();
    break;
  case 'Q':
    error=0;
    end_pmode();
    empty_reply();
    //run1802();
    break;

  case 0x75: //STK_READ_SIGN
    read_signature();
    break;

  // expecting a command, not CRC_EOP
  // this is how we can get back in sync
  case CRC_EOP:
    out(7,(char) STK_NOSYNC);
    break;

  // anything else we will return STK_UNKNOWN
  default:
    if (CRC_EOP == inp(7))
      out(7,(char)STK_UNKNOWN);
    else
      out(7,(char)STK_NOSYNC);
  }
}
void run1802(){
	printf("RUN1802 from 1802land\n");
	while(1);
}
void domeall(){
 }

void doitall(){
	printf("DOING IT ALL  in 1802land\n");
	while(1);
}
void sethere_1802(){
 here=0;
}
uint8_t read_byte_1802() {//I'm hoping here is set to the memory address
  return mem1802[here];
}
char read_page_1802(int length) {//first try
  int x;
  for (x = 0; x < length; x+=1) {
    out(7,'*'); //wasSerial.print((char) read_byte_1802());
  	here++;
  }
  return STK_OK;
}
void write_byte_1802(char data){ //write a byte to the 1802
	mem1802[here]=data;
}

uint8_t write_flash_1802(int length) {
  int x = 0;
  while (x < length) {
    write_byte_1802(buff[x++]); //we can only write bytes sequentially from address 0
  	here++;
  }
  return STK_OK;
}

void empty_reply() {
  char gc=getch();
  if (CRC_EOP == gc) {
    out(7,(char)STK_INSYNC);
    out(7,(char)STK_OK);
  }
  else {
    out(7,(char)STK_NOSYNC);
  }
}

void breply(uint8_t b) {
  if (CRC_EOP == getch()) {
    out(7,(char)STK_INSYNC);
    out(7,(char)b);
    out(7,(char)STK_OK);
  }
  else {
    out(7,(char)STK_NOSYNC);
  }
}

void get_version(uint8_t c) {
  switch(c) {
  case 0x80:
    breply(HWVER);
    break;
  case 0x81:
    breply(SWMAJ);
    break;
  case 0x82:
    breply(SWMIN);
    break;
  case 0x93:
    breply('S'); // serial programmer
    break;
  default:
    breply(0);
  }
}

void set_parameters() {
  // call this after reading paramter packet into buff[]
  param.devicecode = buff[0];
  param.revision = buff[1];
  param.progtype = buff[2];
  param.parmode = buff[3];
  param.polling = buff[4];
  param.selftimed = buff[5];
  param.lockbytes = buff[6];
  param.fusebytes = buff[7];
  param.flashpoll = buff[8];
  // ignore buff[9] (= buff[8])
  //getch(); // discard second value

  // WARNING: not sure about the byte order of the following
  // following are 16 bits (big endian)
  param.eeprompoll = beget16(&buff[10]);
  param.pagesize = beget16(&buff[12]);
  param.eepromsize = beget16(&buff[14]);

  // 32 bits flashsize (big endian)
  param.flashsize = buff[16] * 0x01000000
    + buff[17] * 0x00010000
    + buff[18] * 0x00000100
    + buff[19];

}


uint8_t write_flash(int length) {
  write_flash_1802(length);
  return STK_OK;
}

void program_page() {
  char result = (char) STK_FAILED;
  char memtype;
  int x;
  int length = 256 * getch() + getch(); //gets length 1-256
  if (length > 256) {
      out(7,(char) STK_FAILED);
      return;
  }
  memtype = getch();
  for (x = 0; x < length; x++) {
    buff[x] = getch();
  }
  if (CRC_EOP == getch()) {
    out(7,(char) STK_INSYNC);
    if (memtype == 'F') result = (char)write_flash(length);
    out(7,(char)result);
  }
  else {
    out(7,(char) STK_NOSYNC);
  }
}

void read_signature() {
  if (CRC_EOP != getch()) {
    out(7,(char) STK_NOSYNC);
    return;
  }
  out(7,(char) STK_INSYNC);
  #define sig_high 0x1e //dummy (code for part ATMEGA644P
  #define sig_middle 0x96 //device
  #define sig_low 0x0A //signature
  out(7,(char) sig_high);
  out(7,(char) sig_middle);
  out(7,(char) sig_low);
  out(7,(char) STK_OK);
}
void universal() {//15-01-13 this is being used to retrieve the signature
  int w;
  uint8_t ch;

  for (w = 0; w < 4; w++) { //take the data
    buff[w] = getch();
  }
  if ((buff[0]==0x30)  && (buff[2]==0x00)){
    breply(sig_high);
  }
  else if ((buff[0]==0x30)  && (buff[2]==0x01)){
     breply(sig_middle);
  }
  else if ((buff[0]==0x30)  && (buff[2]==0x02)){
    breply(sig_low);
  }
  else{
    breply(STK_FAILED); //see if this gets a rise out of avrdude
  }
}
//////////////////////////////////////////
//////////////////////////////////////////



void read_page() {
  char result = (char)STK_FAILED;
  int length = 256 * getch() + getch();
  char memtype = getch();
  //cout<<"reading "<<length<<" bytes of "<<memtype<<" ";
  if (CRC_EOP != getch()) {
    out(7,(char) STK_NOSYNC);
    return;
  }
  out(7,(char) STK_INSYNC);
  if (memtype == 'F') result = read_page_1802(length);
  out(7,(char)result);
  return;
}

////////////////////////////////////
////////////////////////////////////

/*
   bootloader application level test
*/
typedef unsigned char uint8_t;
uint8_t buff[256];
int error=0;
int pmode=0;
int here; // address for reading and writing, set by 'U' command
uint8_t rxfifolvl;
uint8_t buff[256]; // global block storage

#define beget16(addr) (*addr * 256 + *(addr+1) )
typedef struct param {
  uint8_t devicecode;
  uint8_t revision;
  uint8_t progtype;
  uint8_t parmode;
  uint8_t polling;
  uint8_t selftimed;
  uint8_t lockbytes;
  uint8_t fusebytes;
  int flashpoll;
  int eeprompoll;
  int pagesize;
  int eepromsize;
  int flashsize;
}
parameter;

parameter param;
#define HWVER 2
#define SWMAJ 5
#define SWMIN 0

// STK Definitions
#define STK_OK 0x10
#define STK_FAILED 0x11
#define STK_UNKNOWN 0x12
#define STK_INSYNC 0x14
#define STK_NOSYNC 0x15
#define CRC_EOP 0x20 //ok it is a space...
uint8_t getch(){
	return inp(7);
}
void start_pmode_1802() {
  pmode = 1;
}

void end_pmode_1802() {
  pmode = 0;
}
void start_pmode() {
  start_pmode_1802();
  pmode = 1;
}
void end_pmode() {
  end_pmode_1802();
  pmode = 0;
}
void readbytes(int n) {
  int x;
  for (x = 0; x < n; x++) {
    buff[x] = getch(); //was Serial.read();
  }
}
char read_page_1802(int length);
uint8_t write_flash_1802(int length);
/*
   bootloader application level test
*/
#include <nstdlib.h>
#include <olduino.h>
#include <cpu1802spd4port7.h>
#define putc(x) out(7,x)
#include "loader1.h"
unsigned char mem1802[4096]; //memory space
int seravail(){//see if there's data available
	out(7,0x12); rxfifolvl=inp(7); //read the fifo depth
	return rxfifolvl;
}
#include "morecode.c"
#include "io1802.c"
#include "avrisp.c"

void main(){
	uint8_t char1802=0x55;
	int ttl=200; //approx 2 sec window
	while(ttl>0){
		if (seravail()){ //data available
			avrisp();
			ttl=200;
		}
	}
	run1802(); //does not return
}

void mainaswas(){
	unsigned char rxfifolvl;
	unsigned int cycle, retries=200,gotchars=0;
	unsigned int i;
	unsigned char hostdata[256];
	while(retries>0){
		setqon(); //show i'm waiting
		out(7,0x12); rxfifolvl=inp(7); //read the fifo depth
		retries=200;
		while (0==rxfifolvl && retries>0){//wait looking for data
			delay(10); //wait a bit
			out(7,0x12); rxfifolvl=inp(7); //read the fifo depth
			retries--;
		}
		printf("rxfifolvl returned %d, retries=%d, gotchars=%d\n",rxfifolvl,retries,gotchars);
		while (rxfifolvl>0){
			out(7,0x00); hostdata[gotchars]=inp(7); //read the fifo data
			gotchars++;rxfifolvl--;
		}
	}

	if (gotchars>0){
		cycle=100;//fast blink for success
	}else{
		cycle=1000;//slow blink for timeout
	}

	printf("rxfifolvl is %d, retries=%d, gotchars=%d\n",rxfifolvl,retries,gotchars);
	for (i=0; i<gotchars;i++){
		out(7,hostdata[i]);
	}
	out (7,'\n');
	while(1){
		setqoff();
		delay(cycle);
		setqon();
		delay(cycle);
	}
}
#include <nstdlib.c>
#include <olduino.c>

 

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: