static void ReadTrack(const u8 *time) { unsigned char tmp[3]; struct SubQ *subq; u16 crc; tmp[0] = itob(time[0]); tmp[1] = itob(time[1]); tmp[2] = itob(time[2]); if (memcmp(cdr.Prev, tmp, 3) == 0) return; CDR_LOG("ReadTrack *** %02x:%02x:%02x\n", tmp[0], tmp[1], tmp[2]); cdr.RErr = CDR_readTrack(tmp); memcpy(cdr.Prev, tmp, 3); //senquack - PPF patch file support; not yet added (TODO?) #if 0 if (CheckSBI(time)) return; #endif subq = (struct SubQ *)CDR_getBufferSub(); if (subq != NULL && cdr.CurTrack == 1) { crc = calcCrc((u8 *)subq + 12, 10); if (crc == (((u16)subq->CRC[0] << 8) | subq->CRC[1])) { cdr.subq.Track = subq->TrackNumber; cdr.subq.Index = subq->IndexNumber; memcpy(cdr.subq.Relative, subq->TrackRelativeAddress, 3); memcpy(cdr.subq.Absolute, subq->AbsoluteAddress, 3); } else { CDR_LOG_I("subq bad crc @%02x:%02x:%02x\n", tmp[0], tmp[1], tmp[2]); } } else { generate_subq(time); } CDR_LOG(" -> %02x,%02x %02x:%02x:%02x %02x:%02x:%02x\n", cdr.subq.Track, cdr.subq.Index, cdr.subq.Relative[0], cdr.subq.Relative[1], cdr.subq.Relative[2], cdr.subq.Absolute[0], cdr.subq.Absolute[1], cdr.subq.Absolute[2]); }
uint8_t fileParser_parseNextBlock(unsigned long filesize) { switch(fileParser_parseState) { case INFO_HEADER: { //--- read info header --- struct InfoHeader *tmpHeader; tmpHeader = (struct InfoHeader *) &sd_buffer[0]; infoHeader = *tmpHeader; if( (infoHeader.headerId[0] != 'S') || (infoHeader.headerId[1] != 'P') || (infoHeader.headerId[2] != 'F') || (infoHeader.headerId[3] != 'I') ) { //header not right -> abort lcd_clear(); lcd_home(); lcd_string("header error"); while(1); return 0; } fileParser_bytesRead += 512; if ((fileParser_bytesRead) >= filesize ) { lcd_setcursor(0,2); lcd_string("EOF error"); while(1); } fileParser_parseState = AVR_DATA; } break; case AVR_DATA: { //--- read avr code --- //program data into flash (512 bytes data to 4 pages a 128 bytes -> mega32 SPM_PAGESIZE = 128 //program data into flash (512 bytes data to 2 pages a 256 bytes -> mega644 SPM_PAGESIZE = 256 for(int i=0; (i<(512/SPM_PAGESIZE)) && (fileParser_bytesRead < (infoHeader.avrCodeSize + 512)); i++ ) { boot_program_page(fileParser_pagesWritten,(uint8_t *)&sd_buffer[0+i*SPM_PAGESIZE]); fileParser_bytesRead += SPM_PAGESIZE; fileParser_pagesWritten+=SPM_PAGESIZE; } //increment the byte counter //fileParser_bytesRead += 512 if ((fileParser_bytesRead) >= filesize ) { return 0; } //check if AVR code end is reached if(fileParser_bytesRead >= (infoHeader.avrCodeSize + 512) ) { //reset cortex chip lcd_home(); lcd_string("updating...(1/2)"); lcd_setcursor(0,2); lcd_command(LCD_CURSOR_ON); fileParser_resetCortex(); //initialize the cortex bootloader //try 10 times to give the cortex some time to boot and answer int i=0; for(;;) { uart_tx(INIT_BOOTLOADER); _delay_ms(1000); //if received data is available #ifdef MEGA32 if( (UCSRA & (1<<RXC)) ) #else if( (UCSR0A & (1<<RXC0)) ) #endif { uint8_t data = uart_rxWait(); if(data == ACK) { //bootloader successfully initialized //it is now waiting for commands break; } } dout_updateOutputs(); } //check if init is ok (ACK received) if(i>=10) { //an error occured //could not initialize bootloader lcd_home(); lcd_string("mainboard error"); while(1); return 0; } //now we can send the cortex bootloader commands and data fileParser_parseState = CORTEX_DATA; //give the cortex time to erase the flash lcd_home(); lcd_string("updating...(2/2)"); return 1; } } break; case CORTEX_DATA: //--- read cortex code --- //we have 512 bytes of data //data is 32 bit unsigned int //we increment with 4 because in each run we send out 4 bytes => 1 32 bit int message for(int i=0;i<512;i+=4) { uint16_t crc; // send the address crc = calcCrc(WRITE_ADDRESS,(uint8_t*)&addressCounter); //send next address packet until ACK received do { uart_tx(WRITE_ADDRESS); //lcd_home(); //lcd_string("cmd"); uart_tx(addressCounter>>24); uart_tx(addressCounter>>16); uart_tx(addressCounter>>8); uart_tx(addressCounter); //send calculated CRC uart_tx(crc>>8); uart_tx(crc&0xff); } while (uart_checkAck()!=ACK); //calc crc for data block crc = calcCrc(WRITE_DATA,&sd_buffer[i]); //send next data packet until ACK received do { //send command uart_tx(WRITE_DATA); //after the command, send the 4 data bytes uart_tx(sd_buffer[i+3]); uart_tx(sd_buffer[i+2]); uart_tx(sd_buffer[i+1]); uart_tx(sd_buffer[i]); //send calculated CRC uart_tx(crc>>8); uart_tx(crc&0xff); } while (uart_checkAck()!=ACK); //transfer succeeded addressCounter++; } dout_updateOutputs(); fileParser_bytesRead+=512; //send cortex bootloader data if ((fileParser_bytesRead) >= filesize ) { lcd_clear(); lcd_home(); lcd_string("success!"); lcd_setcursor(0,2); lcd_string("please reboot..."); lcd_command(LCD_CURSOR_OFF); uart_tx(END_BOOTLOADER); while(1); return 0; } break; } return 1; }