void __init loki_sas_init(void) { writel(0x8300f707, DDR_REG(0x1424)); platform_device_register(&loki_sas); }
__attribute__((__noreturn__)) void main(void) { #if (FLASHEND > 0xFFFFUL) unsigned long flash_address = 0; #else unsigned int flash_address = 0; #endif #if SPM_PAGESIZE > 128 unsigned int x=0, y=0; #else unsigned char x=0, y=0; #endif unsigned char high_byte_buffer = 0, low_byte_buffer = 0, packet_resend_required = 0; unsigned char packet_number = 0, error_counter = 0, memory_full = 0; unsigned int received_bytes = 0, address_buffer = 0, eeprom_address = 0, crc16 = 0, crc_buffer = 0; EXTRA_STARTUP_COMMANDS(); ENABLE_LEVEL_PIN(); UART_TIMEOUT_ENABLE(); sget_char(); // Dummy receive used as a 200 ms delay as the UART is not yet enabled. if( ((PIN_REG(CHECK_LEVEL_PORT) & (1 << CHECK_LEVEL_PIN))) ){ EXTRA_EXIT_COMMANDS(); asm("jmp 0x0000"); } /* Initialization commands */ // Setup the UART _UCSRA_ = 0; // Enable the UART to receive/transmit and enable UART pins _UCSRB_ = ( (1 << _RXEN_)|(1 << _TXEN_) ); // Set UART to receive and transmit 8 bits per character, 1 stop bit with no parity. _UCSRC_ = ( USEURSEL | (1 << _UCSZ1_) | (1 << _UCSZ0_) ); // Set baudrate. _UBRRH_ = BAUDREG/256; _UBRRL_ = BAUDREG%256; // Turn on the pull up resistor of the UART rx pin. DDR_REG(UART_PORT) &= (~(1<<UART_RX_PIN)); PORT_REG(UART_PORT) |= (1<<UART_RX_PIN); // Make the UART Txd pin an output. DDR_REG(UART_PORT) |= (1<<UART_TX_PIN); // Enable the LED indication. ENABLE_LED(); #if INTIALIZATION_DELAY > 0 sget_char(); #endif /* MAIN BOOTLOADER LOOP */ while(1) { // START THE STANDARD 128 BYTE PACKET X MODEM CRC FILE DOWNLOAD // I tried to follow the crc X modem protocol as faithfully as i could LED_ON(); flash_address = 0; eeprom_address = 0; packet_number = 0; error_counter = 0; received_bytes = 0; memory_to_write = 0; memory_full = 0; UART_TIMEOUT_DISABLE(); //Disable uart receive timeout. receive_at_command(); sput_str("START THE X MODEM TRANSFER\r\n"); UART_TIMEOUT_ENABLE(); //Enable the UART timeout. do{ sput_char(XMODEM_NCG); }while(sget_char() != XMODEM_SOH); // DOWNLOAD AND VERIFY ONE PACKET AT A TIME UNTILL THE BUFFER IS FULL. The buffer is equal to SPM_PAGESIZE. /*------------------------------------------------------------------------------------------------------*/ do{ crc16 = 0; #if BOOTLOADER_SAVE_CODE_SIZE == 1 sget_char(); sget_char(); #elif BOOTLOADER_SAVE_CODE_SIZE == 0 packet_number++; packet_resend_required = 0; high_byte_buffer = sget_char(); //get X modem packet number low_byte_buffer = sget_char(); // Examine the packet number. if( (high_byte_buffer + low_byte_buffer) != 255 ) { packet_resend_required = (1<<2); } if( high_byte_buffer == (packet_number-1) ) { packet_resend_required |= (1<<1); } if(high_byte_buffer != packet_number) { packet_resend_required |= (1<<0); } #endif // Now receive the packet data and perform the crc16 check. for(x = X_MODEM_PACKET_LENGTH; x > 0; x--) { x_buffer[received_bytes] = sget_char(); crc16 = ( crc16 ^ ((unsigned int)x_buffer[received_bytes] << 8) ); for(y = 8; y > 0; y--) { crc_buffer = crc16 << 1; if(crc16 & 0x8000) { crc_buffer = crc_buffer ^ 0x1021; } crc16 = crc_buffer; } received_bytes++; } high_byte_buffer = sget_char(); //get X modem CRC16 low_byte_buffer = sget_char(); #if BOOTLOADER_SAVE_CODE_SIZE == 0 if( (high_byte_buffer != (crc16 / 256))||(low_byte_buffer != (crc16 % 256)) ){ packet_resend_required |= (1<<3); } // Now we must see if the packet was received ok or if not, what went wrong. if(packet_resend_required > 0) { error_counter++; packet_number--; // Packet number is decremented. received_bytes -= X_MODEM_PACKET_LENGTH; if( packet_resend_required >= (1<<2) ) { sput_char(XMODEM_NAK); }else if(packet_resend_required >= (1<<1) ) { sput_char(XMODEM_ACK); }else{ goto XMODEM_FAILED; } // end of "if( packet_resend_required >= (1<<2) )" statement. #elif BOOTLOADER_SAVE_CODE_SIZE == 1 if( (high_byte_buffer != (crc16 / 256))||(low_byte_buffer != (crc16 % 256)) ) { goto XMODEM_FAILED; #endif }else{ // "if(packet_resend_required > 0)" statement. if(memory_to_write == 1) { x = 0; while( received_bytes >= SPM_PAGESIZE ) { if(flash_address <= (BOOTLOADER_MEM_START-SPM_PAGESIZE) ) { address_buffer = x; // Store the x_buffer position for the verification process. y=0; do{ boot_page_fill_safe( y, x_buffer[x] | (x_buffer[x+1] << 8) ); x+=2; //BYTE COUNTER UP TO "received_bytes" y+=2; //BYTE COUNTER UP TO SPM_PAGESIZE }while(y < SPM_PAGESIZE); boot_page_erase_safe(flash_address); //erase one Flash page boot_page_write_safe(flash_address); //write buffer to one Flash page boot_rww_enable_safe(); y=0; do{ if( pgm_read_byte(flash_address+y) != x_buffer[address_buffer+y] ){ goto XMODEM_FAILED; } y++; }while(y < SPM_PAGESIZE); flash_address += SPM_PAGESIZE; received_bytes -= SPM_PAGESIZE; }else{ memory_full = 1; goto XMODEM_FAILED; } } }else if(memory_to_write == 2) { for(x=0; x < X_MODEM_PACKET_LENGTH; x++) { if(eeprom_address <= E2END) { eeprom_write_byte((unsigned char*)eeprom_address, x_buffer[x]); if(eeprom_read_byte((unsigned char*)eeprom_address) != x_buffer[x]){ goto XMODEM_FAILED; } eeprom_address++; }else{ memory_full = 1; } } received_bytes = 0; } sput_char(XMODEM_ACK); //error_counter =0; }// end of "if(packet_resend_required > 0){...}else{...}" statement if(error_counter >= 10){ goto XMODEM_FAILED; } //Standard X modem max errors is 10, abort update. }while(sget_char() != XMODEM_EOT); // End of do{}while loop /*----------------------------------------------------------------------------------------------------------*/ // The flash or Eeprom is written so it is time to exit. // exit the X modem transfer. sput_char(XMODEM_NAK); if(sget_char() == XMODEM_EOT) { sput_char(XMODEM_ACK); error_counter = 0; } else{ // If the transfer failed send the X modem cancel character 10 times as per X modem specifications. XMODEM_FAILED: y=0; do{ sput_char(XMODEM_CAN); y++; }while( y<10); error_counter = 1; } _UCSRB_ &= (~ (1 << _RXEN_)); UART_TIMEOUT_1S(); sget_char(); //dummy receive. It is used as delay. _UCSRB_ |= (1 << _RXEN_); if(memory_full) { sput_str("Error memory full"); }else if(error_counter) { sput_str(error_message); }else{ sput_str(update_success_message); } //(*((void(*)(void))(BOOTLOADER_MEM_START)))(); } // END of while(1) main loop. }