static void test_value(OptsVisitorFixture *f, gconstpointer test_data) { uint64_t magic, bitval; intList *i64; uint64List *u64; uint16List *u16; expect_ok(f, test_data); magic = 0; for (i64 = f->userdef->i64; i64 != NULL; i64 = i64->next) { g_assert(-16 <= i64->value && i64->value < 64-16); bitval = 1ull << (i64->value + 16); g_assert((magic & bitval) == 0); magic |= bitval; } g_assert(magic == 0xDEADBEEF); magic = 0; for (u64 = f->userdef->u64; u64 != NULL; u64 = u64->next) { g_assert(u64->value < 64); bitval = 1ull << u64->value; g_assert((magic & bitval) == 0); magic |= bitval; } g_assert(magic == 0xBADC0FFEE0DDF00DULL); magic = 0; for (u16 = f->userdef->u16; u16 != NULL; u16 = u16->next) { g_assert(u16->value < 64); bitval = 1ull << u16->value; g_assert((magic & bitval) == 0); magic |= bitval; } g_assert(magic == 0xD15EA5E); }
int main(int argc,char **argv) { if ((argc<3|| argc>4) ||(argc==4&&strcasecmp(argv[3],"force"))) { fprintf(stderr,"usage: flash900 <firmware> <serial port> [force]\n"); exit(-1); } int fd=open(argv[2],O_RDWR); if (fd==-1) { fprintf(stderr,"Could not open serial port '%s'\n",argv[2]); exit(-1); } if (set_nonblock(fd)) { fprintf(stderr,"Could not set serial port '%s' non-blocking\n",argv[2]); exit(-1); } int speeds[8]={230400,115200,57600,38400,19200,9600,2400,1200}; int speed_count=8; printf("Trying to get command mode...\n"); int i; for(i=0;i<speed_count;i++) { // set port speed and non-blocking, and disable CTSRTS if (setup_serial_port(fd,speeds[i])) { fprintf(stderr,"Could not setup serial port '%s'\n",argv[2]); exit(-1); } int last_char = 0; // Make sure we have left command mode and bootloader mode // 0 = $30 = bootloader reboot command unsigned char cmd[260]; bzero(&cmd[0],260); printf("Checking if stuck in bootloader\n"); // Make sure there is no command in progress with the boot loader write(fd,cmd,260); // Try to sync with bootloader if it is already running cmd[0]=GET_DEVICE; cmd[1]=EOC; write(fd,cmd,2); unsigned char bootloaderdetect[4]={0x43,0x91,0x12,0x10}; int state=0; long long timeout=gettime_ms()+1250; while(gettime_ms()<timeout) { unsigned char buffer[2]; int r=read(fd,buffer,1); if (r==1) { // printf(" read %02X\n",buffer[0]); if (buffer[0]==bootloaderdetect[state]) state++; else state=0; if (state==4) { printf("Looks like we are in the bootloader already\n"); break; } } } if (state==4) printf("Detected RFD900 is already in bootloader\n"); else { printf("Trying to switch to AT command mode\n"); write(fd,"\b\b\b\b\b\b\b\b\b\b\b\b\r",14); // give it time to process the above, so that the first character of ATO // doesn't get eaten. usleep(10000); write(fd,"ATO\r",4); // sleep(2); // allow 2 sec to reboot if it was in bootloader mode already // now try to get to AT command mode sleep(1); write(fd,"+++",3); // now wait for upto 1.2 seconds for "OK" timeout=gettime_ms()+1200; state=0; while(gettime_ms()<timeout) { char buffer[1]; int r=read(fd,buffer,1); if (r==1) { // printf(" read %02X\n",buffer[0]); if ((buffer[0]=='K') && (last_char == 'O')) state=2; else state=0; last_char = buffer[0]; if (state==2) break; } else usleep(10000); } if (state==2) { // try AT&UPDATE or ATS1=115\rAT&W\rATZ if the modem isn't already on 115200bps printf("Switching to boot loader...\n"); char *cmd="AT&UPDATE\r\n"; if (speeds[i]==115200) { write(fd,cmd,strlen(cmd)); } else { char *cmd="ATS1=115\r\n"; write(fd,cmd,strlen(cmd)); sleep(1); cmd="AT&W\r\n"; write(fd,cmd,strlen(cmd)); sleep(1); cmd="ATZ\r\n"; write(fd,cmd,strlen(cmd)); sleep(1); // Go back to looking for modem at 115200 printf("Changing modem from %d to 115200bps\n", speeds[i]); i=-1; continue; } // then switch to 115200 regardless of the speed we were at, // since the bootloader always talks 115200 setup_serial_port(fd,115200); // give time to switch to boot loader // and consume any characters that arrive in the meantime timeout=gettime_ms()+1500; while(gettime_ms()<timeout) { unsigned char buffer[2]; int r=read(fd,(char *)buffer,1); // fprintf(stderr,"Read %02X from bootloader.\n",buffer[0]); if (r!=1) usleep(100000); else { // printf(" read %02X\n",buffer[0]); } } state=4; } } if (state==4) { // got command mode (probably) printf("Got OK at %d\n",speeds[i]); // ask for board ID unsigned char cmd[1024]; cmd[0]=GET_DEVICE; cmd[1]=EOC; write(fd,cmd,2); int id = next_char(fd); int freq = next_char(fd); expect_insync(fd); expect_ok(fd); char filename[1024]; snprintf(filename,1024,"%s-%02X-%02X.ihx",argv[1],id,freq); printf("Board id = $%02x, freq = $%02x : Will load firmware from '%s'\n", id,freq,filename); ihex_recordset_t *ihex=ihex_rs_from_file(filename); if (!ihex) { fprintf(stderr,"Could not read intelhex from file '%s'\n",filename); // Reboot radio write(fd,"0",1); exit(-2); } printf("Read %d IHEX records from firmware file\n",ihex->ihrs_count); // Sort IHEX records into ascending address order so that when we flash // them we don't mess things up by writing the flash data in the wrong order qsort(ihex->ihrs_records,ihex->ihrs_count,sizeof(ihex_record_t), compare_ihex_record); int i; if (0) for(i=0;i<ihex->ihrs_count;i++) printf("$%04x - $%04x\n", ihex->ihrs_records[i].ihr_address, ihex->ihrs_records[i].ihr_address+ ihex->ihrs_records[i].ihr_length-1); // Reset parameters cmd[0]=PARAM_ERASE; cmd[1]=EOC; write(fd,cmd,2); expect_insync(fd); expect_ok(fd); printf("Erased parameters.\n"); // Program all parts of the firmware and verify that that got written printf("Checking if the radio already has this version of firmware...\n"); int fail=0; if (argc==3) { // read flash and compare with ihex records unsigned char buffer[65536]; printf("Bulk reading from flash...\n"); read_64kb_flash(fd,buffer); printf("Read all 64KB flash. Now verifying...\n"); int i; for(i=0;i<ihex->ihrs_count;i++) if (ihex->ihrs_records[i].ihr_type==0x00) { if (fail) break; if (memcmp(&buffer[ihex->ihrs_records[i].ihr_address], ihex->ihrs_records[i].ihr_data, ihex->ihrs_records[i].ihr_length)) fail=1; } } if ((argc==4)||fail) { printf("\nFirmware differs: erasing and flashing...\n"); // Erase ROM printf("Erasing flash.\n"); cmd[0]=CHIP_ERASE; cmd[1]=EOC; write(fd,cmd,2); expect_insync(fd); expect_ok(fd); // Write ROM printf("Flash erased, now writing new firmware.\n"); write_or_verify_flash(fd,ihex,1); } // Reboot radio write(fd,"0",1); break; } else { printf("Modem doesn't seem to be at %dbps\n",speeds[i]); } } return 0; }