📄 bootloader.c
字号:
rg.tim.cnt1_ld = save; // Reset the timer load value } result = S_RETRY; error = E_OVF; // Buffer should now be empty break; } if (error != E_NONE) break; // Expect packet number c = readchar(); if (c < 0) // Timeout { result = S_RETRY; error = E_TIMEOUT; break; } i = c; // Save received packet number // Expect complement of packet number c = readchar(); if (c < 0) // Timeout { result = S_RETRY; error = E_TIMEOUT; break; } // Check the packet number - must be in sequence if (i != packet_num) // Packet number not in sequence { result = S_RETRY; error = E_PKT1; break; } if ((c + packet_num) != 255) // Packet complement incorrect { result = S_RETRY; error = E_PKT2; break; } // Packet number checking complete, now get data crc = 0; // Reset the packet CRC for (i = 0; i < packet_len; i++) { c = readchar(); if (c < 0) { result = S_RETRY; error = E_TIMEOUT; break; } *ptr++ = (unsigned char) c; // Update the current CRC total crc = Update_crc(crc, c); } if (error != E_NONE) break; // Read the transmitted CRC value // Expect high byte then low byte c = readchar(); if (c < 0) { result = S_RETRY; error = E_TIMEOUT; break; } i = c << 8; // Save received CRC high byte c = readchar(); if (c < 0) { result = S_RETRY; error = E_TIMEOUT; break; } i |= c; // Add received CRC low byte // Compare received CRC to calculated CRC, send NAK if not equal if (i != crc) { result = S_RETRY; error = E_CRC; break; } // If CRC correct, set flag for next iteration ack_flag = TRUE; retries = 0; // Reset packet retries done = TRUE; } while (FALSE); // Only ever go though this loop once if (result == S_RETRY) { // Something is wrong, retry if (!start_flag) // Check that we aren't waiting { // for the transmission to start packet_num--; // Reset packet number to previous packet retries++; // Count retry if (retries > retry_max) // Max retries exceeded.. { txchar(CAN); // CAN - Request cancel txchar(CAN); // Needs to be sent twice brk(); result = S_MAXRETRY; done = TRUE; } else { txchar(NAK); // NAK - resend packet } } } } while (done == FALSE); return (result);}/******************************************************************************NAME CalcCrcSYNOPSIS unsigned long CalcCrc(unsigned short *ptr, unsigned long count)FUNCTION Calculates a 32Bit CRC value for the specified block of dataRETURNS 32bit CRC result******************************************************************************/unsigned long CalcCrc(unsigned short *ptr, unsigned long count){ register unsigned long crc = 0; register int i; if (count >= 2) { crc = (unsigned long)(*ptr++) << 16; crc |= (unsigned long)(*ptr++); crc = ~crc; for (i = 2; i < count; i++) { unsigned long test = (unsigned long)(*ptr++); crc = ((crc << 8) | (test >> 8)) ^ CalcPoly(crc); crc = ((crc << 8) | (test & 0xff)) ^ CalcPoly(crc); } } return (~crc);}unsigned long CalcPoly(unsigned long arg){ register int j; register unsigned long result = arg & 0xff000000; const unsigned long polynomial = 0x04c11db7; for (j = 0; j < 8; j++) { if (result & 0x80000000) { result <<= 1; result ^= polynomial; } else { result <<= 1; } } return (result);}/******************************************************************************NAME flash_eraseSYNOPSIS void flash_erase(int first_page, int last_page)FUNCTION Erases the range of pages selectedRETURNS Nothing******************************************************************************/void flash_erase(int first_page, int last_page){#if PROGRAM_FLASH int i; fd.flash.prg_cfg.period = 0x1f3; // Flash access time in ticks rg.flash.prg_ctrl = 0x2900; // Enable erase/write // Erase flash pages from first_page to last_page for (i = first_page; i <= last_page; i++) { rg.flash.prg_adr = i << 8; // Set page address rg.flash.prg_ctrl = 0x2954; // Erase page in main memory usec_delay(5); // Wait 5 us rg.flash.prg_ctrl = 0x2955; // Enable nvstr, start erase msec_delay(10); // Wait 10 ms rg.flash.prg_ctrl = 0x2951; // Disable erase usec_delay(5); // Wait 5 us rg.flash.prg_ctrl = 0x2900; // Remove control signals while (1 == fd.flash.prg_adr.bsy) // Wait for erase to end ; } rg.flash.prg_ctrl = 0x0000; // Disable programming#endif}/******************************************************************************NAME flash_programSYNOPSIS void flash_program(unsigned int program_address, unsigned int *ptr, unsigned int count)FUNCTION Programmes the data block in to IROM at the given addressRETURNS Nothing******************************************************************************/void flash_program(unsigned int program_address, unsigned int *ptr, unsigned int count){#if PROGRAM_FLASH int page_complete; fd.flash.prg_cfg.period = 0x1f3; // Word program time rg.flash.prg_ctrl = 0x2900; // Enable program mode while (count > 0) { rg.flash.prg_adr = program_address; // Set address register rg.flash.prg_ctrl = 0x2992; // Enable program op usec_delay(5); // Wait 5 us rg.flash.prg_ctrl = 0x2993; // enable nvstr usec_delay(10); // Wait 10 us fd.flash.prg_cfg.last_wr = 0; // Clear this bit page_complete = FALSE; while ((count > 0) && !page_complete) { if ((1 == count) || (0x1f == (program_address & 0x1f))) { fd.flash.prg_cfg.last_wr = 1; // Set the last write bit page_complete = TRUE; } rg.flash.prg_adr = program_address++; // Set and increment rg.flash.prg_data = *ptr++; // Data to write - also starts write while (fd.flash.prg_adr.bsy) // Wait for write confirmation ; count--; } rg.flash.prg_ctrl = 0x2991; rg.flash.prg_ctrl = 0x2900; } rg.flash.prg_ctrl = 0x0000; // Programming complete, exit program mode#endif}/****************************************************************************** Note that the following are functions that form part of the library. It is important to place these in this file or they will be assembled to another part of flash, which will require flash accesses during programming******************************************************************************//******************************************************************************NAME msec_delaySYNOPSIS void msec_delay(int)FUNCTION Perform a delay in millisecondsRETURNS after requested number of milliseconds******************************************************************************/void msec_delay(unsigned int delay){ int msec_count = 1100; int msec_ripple = 0; int count; fd.ssm.tap_sel3.tmr = msec_ripple; for (count = 0; count < delay; count++) { rg.tim.tmr_ld = msec_count; rg.tim.cmd = TIM_CMD_TMR_LD_MASK; rg.tim.ctrl_en = TIM_CTRL_EN_TMR_CNT_MASK; while (rg.tim.tmr_cnt) ; rg.tim.ctrl_dis = TIM_CTRL_DIS_TMR_CNT_MASK; }}/******************************************************************************NAME usec_delaySYNOPSIS void usec_delay(int)FUNCTION Perform a delay in microsecondsRETURNS after requested number of microseconds******************************************************************************/void usec_delay(unsigned int delay){ int usec_count = 2; int usec_ripple = 0; int count; fd.ssm.tap_sel3.tmr = usec_ripple; for (count = 0; count < delay; count++) { rg.tim.tmr_ld = usec_count; rg.tim.cmd = TIM_CMD_TMR_LD_MASK; rg.tim.ctrl_en = TIM_CTRL_EN_TMR_CNT_MASK; while (rg.tim.tmr_cnt) ; rg.tim.ctrl_dis = TIM_CTRL_DIS_TMR_CNT_MASK; }}/******************************************************************************NAME readcharSYNOPSIS int readchar(voidFUNCTION Wait for a character to be received on DUART A, with optional timoutRETURNS Character received, or -1 if timout occured******************************************************************************/int readchar(void){ int c = -1; #if ENABLE_TIMEOUT fd.tim.cmd.cnt1_ld = 1; // Reload the timer while (!rg.tim.cnt1_cnt) ; while (rg.tim.cnt1_cnt) { if (fd.duart.a_sts.rx_1b_rdy) { c = (rg.duart.a_rx & 0xff); break; } }#else while (!fd.duart.a_sts.rx_1b_rdy) ; c = (rg.duart.a_rx & 0xff);#endif return (c);}/******************************************************************************NAME txcharSYNOPSIS int txchar(int c)FUNCTION Writes a character to UART A of the DUART.RETURNS The character.******************************************************************************/int txchar(int c){ while (!fd.duart.a_sts.tx_rdy) // Wait for the UART to be ready to transmit ; rg.duart.a_tx8 = c; // Send character return (c);}/******************************************************************************NAME Update_crcSYNOPOSIS unsigned int Update_crc(unsigned int CrntCRC, unsigned char Data)FUNCTION Updates and returns the CRC seed with the data byte. Use CCITT Polynomial X^15 + X^12 + X^5 + 1RETURNS Updated CRC******************************************************************************/unsigned int Update_crc(unsigned int CrntCRC, unsigned char Data){ CrntCRC = (unsigned char)(CrntCRC >> 8) | (CrntCRC << 8); CrntCRC ^= Data; CrntCRC ^= (CrntCRC & 0x00FF) >> 4; CrntCRC ^= (CrntCRC << 12); CrntCRC ^= (CrntCRC & 0x00FF) << 5; return (CrntCRC);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -