0

I've been working on building an AVR powered EEPROM programmer, running on an ATmega1284. I've been trying to write a rather simple program in C that will send the bytes of the hex file over the to AVR, so they can be programmed into the EEPROM. However, although my program does send bytes over a direct USB connection, to my Arduino, it doesn't seem to want to send bytes over the CP2102 device, and so I am unable to send data to my programmer.

For some reason, however, the Arduino IDE's serial monitor seems to work fine sending data over the CP2102. The programmer receives the data just fine. Obviously though this can't be a solution, since the serial monitor has no way of sending mass data, hence the need for this program. Does anyone know how I'm supposed to interface with this CP2102 device? I've tried using normal USB code, and have looked at the Linux CP2102 driver on Torvalds' GitHub, but couldn't extrapolate anything useful. My current program uses the code from the accepted answer here, running on Linux Mint 18, compiled with gcc. My implementation of it is as follows:

void main(int argc, char *argv[]) { //file, port
portname = argv[2];
printf("Programming EEPROM...\n");
char* fileBytes = readFileBytes(argv[1]);
int fd = open(argv[2], O_RDWR);
if (fd < 0)
{
    printf("error %d opening %s: %s", errno, portname, strerror (errno));
    return;
}
set_interface_attribs (fd, B57600, 0);
set_blocking (fd, 0);
for(int i = 0; i < len; i++){
    char byte = fileBytes[i];
    printf("%02x\n", byte);//TODO remove
    write(fd, byte, 1);
    char buf[1];
    buf[0] = (int)NULL;
    while(buf[0] == NULL){
        read(fd, buf, 1);
    }
    char b = buf[0];
    if(b == 0x0f){
        printf("ERROR REPORTED BY PROGRAMMER, EXITING\n");
        exit(1);
    }else if(b == 0x0e){
        printf("Byte good, continuing...\n");//TODO remove
    }else{
        printf("Unknown byte received: %02x\n", b);
        exit(1);
    }
}
printf("Transmission finished.\n");
usleep(20000); //wait 20ms (or maybe a tiny bit more)
write(fd, 0x0d, 1);
usleep(500); //wait for slow ass avr
char buf[1];
buf[0] = (int)NULL;
read(fd, buf, 1);
if(buf[0] == 0x0d){
    printf("Programmer acknowledge. All good!\n");
}
printf("EEPROM programming successful. Exiting...\n");
}
  • 1
    What framework or library are you using for the serial communication? How do you find out the length of the file (and what is `len`)? Also note that [the `main` function](https://en.cppreference.com/w/c/language/main_function) *must* return an `int`. And that `NULL` is for null *pointers* and not generally "data unavailable". Lastly, *always* check for errors from *all* functions that can return an error (like e.g .`read` and `write`). – Some programmer dude Jan 10 '19 at 05:12
  • @Someprogrammerdude len is the length of the file, gotten from ftell on a file. the NULL is a bit of a bodge to dodge a compiler warning. i will also take that advice into account in the program, thank you – CrafterOfWorlds Jan 10 '19 at 06:59
  • *"My current program uses the code from the accepted answer here"* -- That code is not POSIX compliant. Use at your own risk. Writing and reading just a byte per syscall is horribly inefficient. You should not have to sleep before calling read(). – sawdust Jan 10 '19 at 08:38

0 Answers0