0

I'm trying to figure out why my chip can't be programmed completely. I attempted to store 1.7 KB of code in the chip. I was successfully able to program the first 256 bytes and was able to verify each one (even though there were hiccups at times), however, the 257th byte can't be verified.

The chip I used is AT89S52 which accepts at least 4KB code. Also, the file I have inputted into the program as a parameter was found and stored in x051 char array.

The hardware I use is my own circuit I built in which the following connections are made through buffers from PC parallel port to microcontroller:

Pin 1 (strobe) to SCK
Pin 2 (data bit 0) to enable all buffers
Pin 4 (data bit 2) to MOSI
MISO to Pin 11 (busy)

Each line on the microcontroller is taken high by a 10K external pull-up resistor.

EA/VPP line on the microcontroller is set to high to allow programming.

The microcontroller is attached to a 20Mhz crystal.

I'm just trying to figure out. Is there a way I can change my code such that the timing more adheres to the AT89S52 chip because in the state it is in, I can only program the first 256 bytes of the chip. The datasheet for this microcontroller isn't clear on the timings.

I have tried page-mode writing and the results were substantially worse.

This is my code, and as it shows, if it struggles on a certain byte, it gets rewritten every 100 attempts of verification until it is verified as stored:

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/io.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int fm=0;
void lag(){if (fm!=1){usleep(1500);}else{usleep(500);}} //lag routine
void _sclk(unsigned char n){if (n != 0){n=1;};outb(n,0x37A);lag();} //set value for SCK
void _touc(unsigned char n){if (n != 0){n=4;};n++;outb(n,0x378);lag();} //set value for MOSI and set reset low
unsigned char _fromuc(){unsigned char n=inb(0x379);if ((n & 0x80)!= 0){n=1;}else{n=0;};return n;} //get MISO value

void bo(unsigned char byt){
//byte out to uC
  int bit,bn;
  for (bit=0;bit<8;bit++){
  bn=(byt & 0x80);
  if (bn != 0){bn=1;}
  _touc(bn);_sclk(1);_sclk(0);byt=byt<<1;
  }
}

unsigned char bi(){
  //byte in from uC
  int bit,bn;unsigned char outbyte;
  for (bit=0;bit<8;bit++){
_sclk(1);
bn=_fromuc();
outbyte=outbyte<<1;
if (bn!=0){outbyte++;}
_sclk(0);
  }
  outbyte=255-outbyte;
  return outbyte;
}


int main(int argc,char* argv[]){
  char x051[10000]; //buffer for file data
  setbuf(stdout,NULL);
  if (argc < 2){
  printf("binary filename required as argument.\n");
  return -1;
  }
  struct stat info;stat(argv[1],&info); //get file size
  if (info.st_size > 32767){
  printf("FILE SIZE TOO LARGE\n"); //my chip can't handle 32kb
  return -1;
  }
  int fs=info.st_size;
  if (fs < 1){
printf("File non-existant.\n");
return -1;
  }
  printf("File size for %s is %d bytes\n",argv[1],fs);
  memset(x051,0,4999); //clear just enough data memory. we only use 4K max.
  FILE* fh=fopen(argv[1],"r");
  if (fh){ //don't crash if computer disk breaks during program
fread(x051,fs,1,fh);
  };
  fclose(fh);
  //LPT address definitions
  //378: bit 0: 1=SPI MODE,0=RUN
  //     bit 2: uC recv (MOSI P1.5)
  //379: bit 7: uC send (MISO P1.6)
  //37A: bit 0: sclk (SCK P1.7)
  if (ioperm(0x378,3,1) ==-1){ //get permission to use port
printf("ERROR: Access to port hardware denied by PC.\n");
return -1;
  }
  printf("AT89S5x burner starting\n");
  outb(0x0,0x378); //set reset on micro to
  _touc(0); //RESET=high + MOSI = 0
  _sclk(0); //SCK = 0
  usleep(1000000); //wait 1 second for chip to catch up
  printf("Identifying chip...");
  //enable SPI
  bo(0xAC);bo(0x53);bo(0x00);bo(0x69); //send code AC,53,00,69 to chip
  usleep(100000); //wait for chip to catch up
  //get sig (this part works 50% of the time)
  bo(0x28);bo(0x0);bo(0x0);int bin=bi(); //send code 28,0,0 and read last byte
  if (bin != 0x1E){
printf("Bad signature on micro\n");
outb(0x0,0x378); //reset=low for bin != 1Eh
return -1;
  }
  printf("OK\n");
  //erase
  printf("Erasing old data on chip...");
  bo(0xAC);bo(0x80);bo(0x0);bo(0x0);usleep(100); //send AC,80,0,0 and wait 100uS
  //This part works 50% of the time
  //(check memory address 0000h, and FFFFh, but highest 3 bits are ignored by microcontroller
  // but I don't care. Returning FFh means byte is erased)
  printf("validate 1...");do{usleep(100);bo(0x20);bo(0);bo(0);}while(bi() != 0xFF);
  printf("validate 2...");do{usleep(100);bo(0x20);bo(0xFF);bo(0xFF);}while(bi() != 0xFF);
  printf("OK\n");
  printf("Writing %d bytes of data.",fs);
  int an;fm=1; //fm=fast mode=1 (less sleep time between port instructions)
  for (an=0;an<fs;an++){ //loop through all bytes
  unsigned char rb,byt=(unsigned char)x051[an]; //convert each into unsigned char
  bo(0x40);bo(an/256);bo(an%256);bo(byt); //write value of byt to counter value address
  printf("%d/%d bytes written. ",an,fs); //and show progress
  int sv=0; //set sleep value (sv) and receive byte (rb) to zero
  do{
//loop is always stuck at 256th byte
if (sv==1){fm=0;printf("Chip catching up...");};
usleep(sv*1000); //wait longer each time verification fails
bo(0x20);bo(an/256);bo(an%256);rb=bi(); Read byte at same location byte was written to. Value returned in rb
sv++; //increment sleep value for each verification failure
if (sv > 101){
  printf("retrying...");bo(0x40);bo(an/256);bo(an%256);bo(byt);sv=0; //write byte to same location once more to wake up chip
}
  }while(rb != byt);
  fm=1;
  printf("\n");
  }
  //we never get here
  printf("** write done\n");
  outb(0x0,0x378);
  printf("** ALL DONE and program running**\n\n");
  return 0;
}
Mike -- No longer here
  • 2,064
  • 1
  • 15
  • 37
  • From I see from http://ww1.microchip.com/downloads/en/DeviceDoc/doc1919.pdf the system only has 256 bytes of internal memory. I have a strong feeling that you may be writing to that memory instead of to flash or external memory. – Michael Dorgan May 12 '17 at 16:59
  • @MichaelDorgan: I'm not sure if the internal RAM is even accessible from outside on these ancient 8051 derivates. – too honest for this site May 12 '17 at 17:29
  • 1
    I'm voting to close this question as off-topic because it is not guaranteed this is not a hardware issue. I'd recommend reading the datasheet carefully again - all parts, search for app-notes, etc. Typically Atmel was quite open with this information. Unless it is a special device in which case you should contact an FAE of your distributor. – too honest for this site May 12 '17 at 17:31
  • Oh, and: Format this mess properly. No wonder you don't want to debug it yourself. Names starting with underscore are reserved for the implementation at file-scope for all name-spaces. IOW: you must **not** declare such names in your code. – too honest for this site May 12 '17 at 17:37
  • 1
    @MichaelDorgan: Verified: you cannot access the RAM this way. – too honest for this site May 12 '17 at 17:38
  • How are these prehistoric contraptions still in use? I got frustrated with them, and their hopeless mimimal RAM, 30-odd years ago, (the ones that were UV-eraseable:). – ThingyWotsit May 12 '17 at 19:16
  • I'm trying to store data into code memory of the chip (eeprom), not chip ram. And function names beginning with underscore have bad effects besides appearance? – Mike -- No longer here May 12 '17 at 20:00
  • @ThingyWotsit same answer for the PIC, memory measured in bytes not K bytes. There are no doubt still products out there that they just keep cranking out, some design houses this is what they know. The 8051 as an architecture is still heavily in use, hard to touch ARM, but if you want not keep spinning chips, and want a small royalty free programmable thing, 8051 and z80 are well used choices, mice, phys, radios, keyboards, etc. buried in the chip that even the chip customers often dont know its in there. but 8051 mcus, sure, should be dying out. – old_timer May 12 '17 at 21:08
  • I did buy one last year (put it on a breakout board, wonder if I sampled it or bought it) just to get something not arm for a change, was able to in circuit program the flash (from an arm microcontroller bit banged probably) and run a program or two. There would really have to be existing products that they support, price for what you get, could name a number of alternatives. – old_timer May 12 '17 at 21:10
  • If you are trying to debug a spi bus problem...you need a scope...then figure out if it is hardware or software or a combination. Using the scope you can adjust your software to adjust the waveform to confirm to what the target is expecting, can be done without but far easier with. – old_timer May 12 '17 at 21:13
  • 1
    A pc parallel port would by far be the last thing I would use. ftdi breakout board would be the first pc software driven thing i would try, but another microcontroller (if you can resolve the 5v levels assuming you are needing those) would be much easier, or perhaps a cpld or fpga dev board. – old_timer May 12 '17 at 21:15
  • I have a psu unit that supplies 5v. I used the same unit to run an at89c2051 which is a small version of an 8051 – Mike -- No longer here May 13 '17 at 02:26

0 Answers0