int main(void) { _delay_ms(1000); //power_on_delay RFM73_Initialize(); RED_LED_OUT(); RED_LED_OFF(); set_sleep_mode(SLEEP_MODE_PWR_DOWN); sei(); // enable interrupts globally sleep_mode(); // go to sleep while(1) { Receive_Packet(); sleep_mode(); } }
int main(void) { power_on_delay(); timer0_init(); RED_LED_OUT(); RED_LED_OFF(); if(rfm70_init(RFM70_MODE_PRX, addr) != 0) { RED_LED_ON(); } sei(); // enable interrupts globally rfm70_set_ack_payload(RFM70_PIPE0, ack_pld, sizeof(ack_pld)); while(1) { Receive_Packet(); } }
int main(void) { uint8_t i; power_on_delay(); rfm70_init(RFM70_MODE_PRX, addr); RED_LED_OUT(); RED_LED_OFF(); usbInit(); usbDeviceDisconnect(); /* Disconnect for some time to enforce reenumeration */ i = 0; while(--i) { _delay_ms(1); } usbDeviceConnect(); sei(); // enable interrupts globally while(1) { usbPoll(); Receive_Packet(); } }
//--------------------------------------------------------------------------------- static int32_t Ymodem_Receive ( char* FileName, uint32_t maxsize, uint8_t getname ) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr; int32_t i, packet_length, file_len, write_len, session_done, file_done, packets_received, errors, session_begin, size = 0; for (session_done = 0, errors = 0, session_begin = 0; ;) { for (packets_received = 0, file_done = 0; ;) { switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT)) { case 0: switch (packet_length) { /* Abort by sender */ case -1: Send_Byte(ACK); return 0; /* End of transmission */ case 0: Send_Byte(ACK); file_done = 1; break; /* Normal packet */ default: if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) { errors ++; if (errors > MAX_ERRORS) { send_CA(); return 0; } Send_Byte(NAK); } else { errors = 0; if (packets_received == 0) { /* Filename packet */ if (packet_data[PACKET_HEADER] != 0) { // Filename packet has valid data if (getname == 0) { for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < SPIFFS_OBJ_NAME_LEN);) { FileName[i++] = *file_ptr++; } FileName[i++] = '\0'; } for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < packet_length);) { file_ptr++; } for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &size); // Test the size of the file if (size < 1 || size > maxsize) { file_fd = FILE_NOT_OPENED; /* End session */ send_CA(); return -4; } /* *** Open the file *** */ if (FILE_NOT_OPENED != file_fd) { SPIFFS_close(&fs,file_fd); file_fd = FILE_NOT_OPENED; } file_fd = SPIFFS_open(&fs, (char*)FileName, mode2flag("w"), 0); if (file_fd <= FILE_NOT_OPENED) { file_fd = FILE_NOT_OPENED; /* End session */ send_CA(); return -2; } file_len = 0; Send_Byte(ACK); Send_Byte(CRC16); } /* Filename packet is empty, end session */ else { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } /* Data packet */ else { /* Write received data to file */ if (file_len < size) { file_len = file_len + packet_length; if (file_len > size) { write_len = packet_length - (file_len - size); } else { write_len = packet_length; } if (file_fd <= FILE_NOT_OPENED) { file_fd = FILE_NOT_OPENED; // File not opened, End session send_CA(); return -2; } if (SPIFFS_write(&fs,file_fd, (char*)(packet_data + PACKET_HEADER), write_len) < 0) { //failed SPIFFS_close(&fs,file_fd); file_fd = FILE_NOT_OPENED; /* End session */ send_CA(); return -1; } } //success Send_Byte(ACK); } packets_received ++; session_begin = 1; } } break; case 1: send_CA(); return -3; default: if (session_begin >= 0) { errors ++; } if (errors > MAX_ERRORS) { send_CA(); return 0; } Send_Byte(CRC16); break; } if (file_done != 0) { break; } } if (session_done != 0) { break; } } return (int32_t)size; }
//======================================================================================= //inline void sendMachine_3(){ enum { DATAMAXLEN = 64, DATAMARKERPOSITION = 0, DATAMARKER = '?', DATACODELENPOSITION = 1, DATACODEPOSION = 2 }; #define ASKDATALEN 3 char ASKDATA[ASKDATALEN] = "***"; #define ANSWERDATALEN 3 char ANSWERDATA[ANSWERDATALEN] = "+++"; static char data[DATAMAXLEN]; #define REPCOUNTER 3 static char repeat_counter = REPCOUNTER; enum {WAITNEWCODE, WAITCODEDONE, WAITBOX, SENDTOBOX, WAITDELAY}; static char state = WAITNEWCODE; switch (state){ //======================== case WAITNEWCODE: //======================== if (getFlag(FLAG_NEW_NOCK) == TRUE) state = WAITCODEDONE; break; //======================== case WAITCODEDONE: //======================== if (getFlag(FLAG_NEW_NOCK) == FALSE){ //state = WAITBOX; //DEBUG state = SENDTOBOX; } break; //======================== case WAITBOX:{ //======================== char len = Receive_Packet(data, DATAMAXLEN); if (len > 0){ #ifdef LOGG loggerWriteToMarker((LogMesT)" WAITBOX get data: *", '*'); loggerWrite((LogMesT)data, len); #endif for (char i = 0; i < ANSWERDATALEN; i++) if (data[i] != ANSWERDATA[i]) return; state = SENDTOBOX; break; } SwitchToTxMode(); Send_Packet(W_TX_PAYLOAD_NOACK_CMD, (unsigned char *)ASKDATA, ASKDATALEN); //Send_Packet(0, ASKDATA, ASKDATALEN); SwitchToRxMode(); state = WAITDELAY; }break; //======================== case WAITDELAY: //======================== if (processWait() == TRUE) #ifdef LOGG loggerWriteToMarker((LogMesT)" goto WAITBOX\r*", '*'); #endif state = WAITBOX; break; //======================== case SENDTOBOX:{ //======================== #ifdef LOGG loggerWriteToMarker((LogMesT)" SENDTOBOX\r*", '*'); #endif SwitchToTxMode(); Nock * nock = getNock(NOCK_PATTERN); data[DATAMARKERPOSITION] = DATAMARKER; data[DATACODELENPOSITION] = nock->count; unsigned char i; for (i = 0; i < nock->count; i++){ int time = nock->nock[i]; char * p = &time; data[DATACODEPOSION + i*2] = *p; p++; data[DATACODEPOSION + i*2 + 1] = *p; } data[DATACODEPOSION + i * 2] = DATAMARKER; Send_Packet(W_TX_PAYLOAD_NOACK_CMD, (unsigned char *)data, DATACODEPOSION + nock->count * 2 + 1); //Send_Packet(0, (unsigned char *)data, DATACODEPOSION + nock->count + 1); #ifdef LOGG loggerWriteToMarker((LogMesT)" nock count: *", '*'); char ch = nock->count + 48; loggerWrite(&ch, 1); #endif if (repeat_counter-- <= 0){ repeat_counter = REPCOUNTER; state = WAITNEWCODE; } }break; //======================== default: break; //======================== } }
/** * @brief Receive a file using the ymodem protocol. * @param buf: Address of the first byte. * @retval The size of the file. */ int32_t Ymodem_Receive (uint8_t *buf) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; int32_t i, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0; uint32_t flashdestination, ramsource; /* Initialize flashdestination variable */ flashdestination = APPLICATION_ADDRESS; for (session_done = 0, errors = 0, session_begin = 0; ;) { for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) { switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT)) { case 0: errors = 0; switch (packet_length) { /* Abort by sender */ case - 1: Send_Byte(ACK); return 0; /* End of transmission */ case 0: Send_Byte(ACK); file_done = 1; break; /* Normal packet */ default: if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) { Send_Byte(NAK); } else { if (packets_received == 0) { /* Filename packet */ if (packet_data[PACKET_HEADER] != 0) { /* Filename packet has valid data */ for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) { FileName[i++] = *file_ptr++; } FileName[i++] = '\0'; for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &size); /* Test the size of the image to be sent */ /* Image size is greater than Flash size */ if (size > (USER_FLASH_SIZE + 1)) { /* End session */ Send_Byte(CA); Send_Byte(CA); return -1; } /* erase user application area */ FLASH_If_Erase(APPLICATION_ADDRESS); Send_Byte(ACK); Send_Byte(CRC16); } /* Filename packet is empty, end session */ else { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } /* Data packet */ else { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); ramsource = (uint32_t)buf; /* Write received data in Flash */ if (FLASH_If_Write(&flashdestination, (uint32_t*) ramsource, (uint16_t) packet_length/4) == 0) { Send_Byte(ACK); } else /* An error occurred while writing to Flash memory */ { /* End session */ Send_Byte(CA); Send_Byte(CA); return -2; } } packets_received ++; session_begin = 1; } } break; case 1: Send_Byte(CA); Send_Byte(CA); return -3; default: if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) { Send_Byte(CA); Send_Byte(CA); return 0; } Send_Byte(CRC16); break; } if (file_done != 0) { break; } } if (session_done != 0) { break; } } return (int32_t)size; }
/** * @brief Receive a file using the ymodem protocol * @param buf: Address of the first byte * @retval The size of the file */ int32_t Ymodem_Receive (uint8_t *buf) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; int32_t i, j, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0; /* Initialize FlashDestination variable */ FlashDestination = ApplicationAddress; for (session_done = 0, errors = 0, session_begin = 0; ;) { for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) { switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT)) { case 0: errors = 0; switch (packet_length) { /* Abort by sender */ case - 1: Send_Byte(ACK); return 0; /* End of transmission */ case 0: Send_Byte(ACK); file_done = 1; break; /* Normal packet */ default: if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) { Send_Byte(NAK); } else { if (packets_received == 0) { /* Filename packet */ if (packet_data[PACKET_HEADER] != 0) { /* Filename packet has valid data */ for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) { file_name[i++] = *file_ptr++; } file_name[i++] = '\0'; for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &size); /* Test the size of the image to be sent */ /* Image size is greater than Flash size */ if (size > (FLASH_SIZE - 1)) { /* End session */ Send_Byte(CA); Send_Byte(CA); return -1; } /* Erase the needed pages where the user application will be loaded */ /* Define the number of page to be erased */ NbrOfPage = FLASH_PagesMask(size); /* Erase the FLASH pages */ for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(FlashDestination + (PageSize * EraseCounter)); } Send_Byte(ACK); Send_Byte(CRC16); } /* Filename packet is empty, end session */ else { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } /* Data packet */ else { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); RamSource = (uint32_t)buf; for (j = 0;(j < packet_length) && (FlashDestination < ApplicationAddress + size);j += 4) { /* Program the data received into STM32F10x Flash */ FLASH_ProgramWord(FlashDestination, *(uint32_t*)RamSource); if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource) { /* End session */ Send_Byte(CA); Send_Byte(CA); return -2; } FlashDestination += 4; RamSource += 4; } Send_Byte(ACK); } packets_received ++; session_begin = 1; } } break; case 1: Send_Byte(CA); Send_Byte(CA); return -3; default: if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) { Send_Byte(CA); Send_Byte(CA); return 0; } Send_Byte(CRC16); break; } if (file_done != 0) { break; } } if (session_done != 0) { break; } } return (int32_t)size; }
int32_t Ymodem_Receive(uint8_t *buf) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; int32_t i,j,packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0; /* Initialize FlashDestination variable */ FlashDestination = ApplicationAddress; for(session_done = 0, errors = 0, session_begin = 0; ;) { for(packets_received = 0, file_done = 0, buf_ptr = buf; ;) { switch(Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT)) { case 0: errors = 0; switch (packet_length) { /* Abort by sender */ case - 1: Send_Byte(ACK); return 0; /* End of transmission */ case 0: Send_Byte(ACK); file_done = 1; break; /* Normal packet */ default: if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff))//数据包编号 { Send_Byte(NAK); } else { if(packets_received == 0)/* 第一次传输文件属性 */ { if(packet_data[PACKET_HEADER] != 0)/* Filename packet has valid data */ { for(i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) file_name[i++] = *file_ptr++; file_name[i++] = '\0';/*接收文件名结束*/ for(i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) file_size[i++] = *file_ptr++; file_size[i++] = '\0';/*接收文件名大小结束*/ Str2Int(file_size, &size); if(size > (FLASH_SIZE - SYSTEM_BOOTLOADER_LENGTH -1))//代码长度超过空间大小 { Send_Byte(CA); Send_Byte(CA); return -1; } if ((size % PAGE_SIZE) != 0)//根据代码大小分配块 NbrOfPage = (size / PAGE_SIZE) + 1; else NbrOfPage = size / PAGE_SIZE; for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_OK); EraseCounter++) { FLASHStatus = FLASH_EraseSector(FlashDestination/PageSize + EraseCounter);//擦除代码所需要块 FLASHStatus = FLASH_OK; } Send_Byte(ACK); Send_Byte(CRC16); } else/* Filename packet is empty, end session */ { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } else/* Data packet */ { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); RamSource = (uint32_t)buf; for (j = 0;(j < packet_length) && (FlashDestination < ApplicationAddress + size);j += 4) { /* Program the data received into STM32F10x Flash */ FLASH_WriteWord(FlashDestination, *(uint32_t*)RamSource); if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource) { /* End session */ Send_Byte(CA); Send_Byte(CA); return -2; } FlashDestination += 4; RamSource += 4; } Send_Byte(ACK); } packets_received ++; session_begin = 1;//错误计数器 } } break; case 1: Send_Byte(CA); Send_Byte(CA); return -3; default: if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) { Send_Byte(CA); Send_Byte(CA); return 0; } Send_Byte(CRC16); break; } if (file_done != 0) { break; } } if (session_done != 0) { break; } } return (int32_t)size; }
/** * @brief Receive a file using the ymodem protocol. * @param buf: Address of the first byte. * @retval The size of the file. */ int32_t Ymodem_Receive (uint8_t *buf, mico_flash_t flash, uint32_t flashdestination, int32_t maxRecvSize) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; int32_t i, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0; uint32_t ramsource; MicoFlashInitialize(flash); for (session_done = 0, errors = 0, session_begin = 0; ;) { for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) { switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT)) { case 0: errors = 0; switch (packet_length) { /* Abort by sender */ case - 1: Send_Byte(ACK); MicoFlashFinalize(flash); return 0; /* End of transmission */ case 0: Send_Byte(ACK); file_done = 1; break; /* Normal packet */ default: if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) { Send_Byte(NAK); } else { if (packets_received == 0) { /* Filename packet */ if (packet_data[PACKET_HEADER] != 0) { /* Filename packet has valid data */ for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) { FileName[i++] = *file_ptr++; } FileName[i++] = '\0'; for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &size); /* Test the size of the image to be sent */ /* Image size is greater than Flash size */ if (size > (maxRecvSize + 1)) { /* End session */ Send_Byte(CA); Send_Byte(CA); MicoFlashFinalize(flash); return -1;//The image size is higher than memory! } /* erase user application area */ MicoFlashErase(flash, flashdestination, flashdestination + maxRecvSize - 1); Send_Byte(ACK); Send_Byte(CRC16); } /* Filename packet is empty, end session */ else { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } /* Data packet */ else { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); ramsource = (uint32_t)buf; /* Write received data in Flash */ if (MicoFlashWrite(flash, &flashdestination, (uint8_t*) ramsource, (uint32_t) packet_length) == 0) { Send_Byte(ACK); } else /* An error occurred while writing to Flash memory */ { /* End session */ Send_Byte(CA); Send_Byte(CA); MicoFlashFinalize(flash); return -2;//Verification failed! } } packets_received ++; session_begin = 1; } } break; case 1: Send_Byte(CA); Send_Byte(CA); MicoFlashFinalize(flash); return -3;//Aborted by user. default: if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) { Send_Byte(CA); Send_Byte(CA); MicoFlashFinalize(flash); return 0;//Failed to receive file! } Send_Byte(CRC16); break; } if (file_done != 0) { break; } } if (session_done != 0) { break; } } MicoFlashFinalize(flash); return (int32_t)size;//successful }
int main(void) { uchar i; int intro = 1; static char reciveErrorCount = 0; static char carrierErrorCount = 0; wdt_enable(WDTO_1S); /* Even if you don't use the watchdog, turn it off here. On newer devices, * the status of the watchdog (on/off, period) is PRESERVED OVER RESET! * RESET status: all port bits are inputs without pull-up. * That's the way we need D+ and D-. Therefore we don't need any * additional hardware initialization. */ usbInit(); usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ i = 0; while (--i) { // fake USB disconnect for > 250 ms wdt_reset(); _delay_ms(1); } usbDeviceConnect(); //sei(); //Ports initialization and other piperials LCD_Initalize(); LCD_Clear(); /* About project screen */ //LCD_GoTo(center("SMiW 2011/2012"), 0); //LCD_WriteText("SMiW 2011/2012"); //LCD_GoTo(center("Marcin Jabrzyk"), 2); //LCD_WriteText("Marcin Jabrzyk"); irmp_init(); //IR libary timer_init(); //IR timmer and ADC starter adc_init(); //ADC configuration cli(); intro = 0; if (RFM70_Initialize(0, (uint8_t*) "Smiw2")) { LCD_GoTo(center("Init RFM70"), 2); LCD_WriteText("Init RFM70"); _delay_ms(100); } else { LCD_GoTo(center("ERR init RFM70"), 1); LCD_WriteText("ERR init RFM70"); } if (RFM70_Present()) { LCD_GoTo(center("RFM70 present"), 3); LCD_WriteText("RFM70 present"); } else { LCD_GoTo(center("RFM70 not present"), 3); LCD_WriteText("RFM70 not present"); } sei(); for (;;) { /* main event loop */ wdt_reset(); usbPoll(); if (RFM70_Present()) { sprintf(screenDebug[0], screenDebugTemplate[0], "OK"); } else { sprintf(screenDebug[0], screenDebugTemplate[0], "ERROR"); } if (Carrier_Detected()) { sprintf(screenDebug[1], screenDebugTemplate[1], "OK"); carrierErrorCount = 0; } else { carrierErrorCount++; } if (carrierErrorCount > 50) { sprintf(screenDebug[1], screenDebugTemplate[1], "NONE"); } char* _tempGrzejnik; if (Packet_Received()) { sprintf(screenDebug[2], screenDebugTemplate[2], "OK"); Receive_Packet(message); //if from grzejnik starts with "a" else from piec _tempGrzejnik = strchr(message, 'a'); if (_tempGrzejnik != NULL ) { strncpy(tempFromGrzejnik, _tempGrzejnik, 4); sprintf(screenCenter[2], screenCenterTemplate[2], _tempGrzejnik); } else { strncpy(tempFromPiec, message, 4); sprintf(screenCenter[1], screenCenterTemplate[1], message); } reciveErrorCount = 0; } else { reciveErrorCount++; } if (reciveErrorCount > 90) { sprintf(screenDebug[2], screenDebugTemplate[2], "WAIT"); } if (irmp_get_data(&irmp_data)) { // When IR decodes a new key presed. lastKey = irmp_data.command; //Save the key itoa(irmp_data.command, lastKeyStr, 10); //Convert it to string sprintf(screenCenter[3], screenCenterTemplate[3], lastKeyStr); isChanged = 1; intro = 0; } if (intro == 0) { switch (lastKey) { //Change the view case 69: printScreenWithCenter(screenLeft); break; //CH- case 70: printScreen(screenCenter); break; //CH case 71: printScreenWithCenter(screenRight); break; //CH+ case 82: printScreen(screenDebug); break; default: printScreen(screenCenter); break; //Any other key } } usbPoll(); } return 0; }
/** * @brief Receive a file using the ymodem protocol * @param buf: Address of the first byte * @retval The size of the file */ int32_t Ymodem_Receive (uint8_t *buf) { uint8_t packet_data[PACKET_1KB_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; int32_t i, j, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0; /* Initialize FlashDestination variable */ FlashDestination = ApplicationAddress; Send_Byte(CRC16); for (session_done = 0, errors = 0, session_begin = 0; ;) { for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) { switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT)) { case 0://成功收到数据 // errors = 0; switch (packet_length) { /* Abort by sender */ case - 1://接收失败 Send_Byte(ACK); return 0; /* End of transmission */ case 0://本次文件传送结束 Send_Byte(ACK); file_done = 1; break; /* Normal packet */ default://接收成功 if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) { Send_Byte(NAK); } else { if (packets_received == 0)//文件信息(首包) { /* Filename packet */ if (packet_data[PACKET_HEADER] != 0)//文件名字 { /* Filename packet has valid data */ for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) { file_name[i++] = *file_ptr++;//保存文件名字 } file_name[i++] = '\0';//字符串形式 for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) { file_size[i++] = *file_ptr++;//文件大小 } file_size[i++] = '\0'; Str2Int(file_size, &size); /* Test the size of the image to be sent */ /* Image size is greater than Flash size */ if (size > (FLASH_SIZE - 1)) { /* End session */ Send_Byte(CA); Send_Byte(CA); return -1; } /* Erase the needed pages where the user application will be loaded */ /* Define the number of page to be erased */ if(EraseSomePages(size, 0)) { } else { /* End session */ Send_Byte(CA); Send_Byte(CA); return -1; //Erase failed } Send_Byte(ACK); Send_Byte(CRC16); } /* Filename packet is empty, end session */ else { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } /* Data packet */ else//文件信息保存完之后开始接收数据 { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); RamSource = (uint32_t)buf; for (j = 0;(j < packet_length) && (FlashDestination < ApplicationAddress + size);j += 4) { /* Program the data received into STM32F10x Flash */ FLASH_Unlock(); FLASH_ProgramWord(FlashDestination, *(uint32_t*)RamSource); FLASH_Lock(); if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource) { /* End session */ Send_Byte(CA); Send_Byte(CA); return -2; } FlashDestination += 4; RamSource += 4; } Send_Byte(ACK); } packets_received ++; session_begin = 1; } } break; case 1://用户按下了'a'或'A' Send_Byte(CA); Send_Byte(CA); return -3; default://检查错误 if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) { Send_Byte(CA); Send_Byte(CA); return 0; } Send_Byte(CRC16);//发送校验值 break; } if (file_done != 0) { break; } } if (session_done != 0)//文件发送完成 { break; } } return (int32_t)size; }
/******************************************************************************* * @函数名称 Ymodem_Receive * @函数说明 通过 ymodem协议接收一个文件 * @输入参数 buf: 首地址指针 * @输出参数 无 * @返回参数 文件长度 *******************************************************************************/ int32_t Ymodem_Receive (uint8_t *buf) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; int32_t i, j, packet_length, session_done, file_done, packets_received, errors, session_begin; uint32_t receive_file_size = 0; uint8_t receive_result; //初始化Flash地址变量 FlashDestination = ApplicationAddress; for (session_done = 0, errors = 0, session_begin = 0; ;) //死循环,初始化 { for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) //死循环,初始化 { //0: 正常返回 //-1: 超时或者数据包错误 //1: 用户取消 receive_result=Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT); //for debug // Send_Byte(receive_result); // Send_Byte(packet_length); switch (receive_result) //从发送端接收一个数据包 { case 0: //0:正常返回 errors = 0; switch (packet_length) { //发送端终止 case - 1: Send_Byte(ACK); return 0; //结束传输 case 0: Send_Byte(ACK); file_done = 1; break; //正常的数据包 default: if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) //数据包编号错误 { Send_Byte(NAK); } else //包编号正确 { //表示第0帧,即文件名数据包 if (packets_received == 0) { //文件名数据包 if (packet_data[PACKET_HEADER] != 0) { //文件名数据包有效数据区域 for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) { file_name[i++] = *file_ptr++; } file_name[i++] = '\0'; //上位机发送的文件名 for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &receive_file_size); //size表示上位机发送过来的文件的大小 //for debug // Send_Byte(size); //测试数据包是否过大 if (receive_file_size > (FLASH_SIZE - 1)) { //结束 Send_Byte(CA); Send_Byte(CA); return -1; } //计算需要擦除Flash的页 NbrOfPage = FLASH_PagesMask(receive_file_size); //for debug // Send_Byte(0xfd); //擦除Flash for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(FlashDestination + (PageSize * EraseCounter)); } //for debug // Send_Byte(0xfe); Send_Byte(ACK); //收到上位机发送的第0帧之后发送ACK命令 Send_Byte(CRC16); //接着再发送C,表示等待上位机发送数据帧 //for debug // Send_Byte(0xff); } //文件名数据包空,结束传输 else { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } //非第0帧的协议数据包 else { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); RamSource = (uint32_t)buf; //内层for循环初始化buf_ptr = buf for (j = 0; (j < packet_length) && (FlashDestination < ApplicationAddress + receive_file_size); j += 4) { //把接收到的数据编写到Flash中 FLASH_ProgramWord(FlashDestination, *(uint32_t*)RamSource); if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource) //检查写flash是否成功 { //结束 Send_Byte(CA); Send_Byte(CA); return -2; } FlashDestination += 4; RamSource += 4; }//非第0帧的协议数据包结束 Send_Byte(ACK); //接受到第非0帧数据帧之后,发送ACK命令 } packets_received ++; //不管是第0帧还是第非0帧,数据包编号自增 session_begin = 1; //接受数据包成功则会话开始 }//包编号正确结束 }//内层switch循环结束 break; case 1: //1: 用户取消 Send_Byte(CA); Send_Byte(CA); return -3; default: //-1: 超时或者数据包错误 if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) //如果错误次数大于MAX_ERRORS=5 { Send_Byte(CA); Send_Byte(CA); return 0; } Send_Byte(CRC16); //发送C break; }//外层switch结束 if (file_done != 0) { break; } }//内层for循环结束 if (session_done != 0) { break; } }//外层for循环结束 return (int32_t)receive_file_size; }
/******************************************************************************* * 函数命名: Ymodem * 输入参数: - address of the first byte * 输出参数: - None * —返回值: - The size of the file * 函数功能: Receive a file using the ymodem protocol *******************************************************************************/ int32_t Ymodem_Receive (uint8_t *buf) { uint8_t packet_data[128 + 5], file_size[50], *file_ptr, *buf_ptr; int32_t i, packet_length, session_done, file_done, errors, session_begin, size = 0, packets_received = 0; uint32_t flashdestination, ramsource; /* Initialize flashdestination variable */ flashdestination = 0; flashdestination = APPLICATION_ADDRESS; //flashdestination = 0x1100; for (session_done = 0, errors = 0, session_begin = 0; ;) { for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) { switch (Receive_Packet(packet_data, &packet_length, 0x10000))//纯数据缓存在 packet_data 中 0x1000 { case 0://正常传输 or 传输结束 errors = 0; switch (packet_length)//数据包长度 { case -1:/* Abort by sender */ Put_char(ACK); return 0; case 0:/* End of transmission */ Put_char(ACK); file_done = 1; // session_done = 1; //ybz 改变Ymodem协议 多个bin文件不可以连续传输。因为升级中掉电后,bin文件还存在在上位机的进程中,上电后再给一个bin文件升级时,其实是download了两个bin文件. 加上此句会造成上位机卡死。 break; default:/* Normal packet */ if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) { Put_char(NAK); } else { if (packets_received == 0) { /* Filename packet */ if ((packet_data[PACKET_HEADER] != 0) && (packet_data[4] != 0) && (packet_data[4] != 0x30)) { /* Filename packet has valid data */ for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) { FileName[i++] = *file_ptr++; } FileName[i++] = '\0'; for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH); ) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &size); temp = size; /* Test the size of the image to be sent */ /* Image size is greater than Flash size */ if (size > USER_FLASH_SIZE) //USER_FLASH_SIZE + 1 { /* End session */ Put_char(CA); Put_char(CA); return -1; //写入bin文件的size 大于 Flash可以写入的size } /* erase user application area */ __disable_irq(); // MFlash_SectorErase ((uint16_t*)0x00001000);//擦除第2扇区 MFlash_SectorErase ((uint16_t*)0x00010000); //擦除第3扇区 Put_char(ACK); Put_char(CRC16); __NOP(); } /* Filename packet is empty, end session */ else { Put_char(ACK); file_done = 1; session_done = 1; break; } } /* Filename packet */ else /* Data packet */ { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); ramsource = (uint32_t)buf; /* Write received data in Flash */ // 要写的地址 数据首地址 数据长度 if (0 == Write(flashdestination, (uint32_t*)ramsource, (uint16_t)packet_length/4)) { Put_char(ACK); flashdestination = flashdestination + packet_length; } else /* An error occurred while writing to Flash memory */ { /* End session */ Put_char(CA); Put_char(CA); return -2; } } //end if(packets_received == 0) packets_received++; session_begin = 1; }//end if() /* Normal packet */ } break; //break case 0://正常传输 or 传输结束 case 1://abort by user Put_char(CA); Put_char(CA); return -3; default: //如果会话开始后发生错误 if (session_begin > 0) { errors++; } if (errors > MAX_ERRORS) //错误累积到一定程度之后,终止会话。 (5次) { Put_char(CA); Put_char(CA); return 0; } flashdestination = 0; //这两句修复了,升级过程中掉电。再上电后重新发送APP_bin第一次发生错误后,再次发送APP_bin写入flash地址错误 (正确的地址应为0x0000_1100) flashdestination = APPLICATION_ADDRESS; //重新发送C字符后, 重新初始化APP_address //flashdestination = 0x1100; Delay_ms(1000); //ybz Put_char(CRC16); //如果没有接收到字符 就一直向终端发送字符C break; //break switch } if (file_done != 0) //发送文件过程有错,退出文件传输 { break; //break for (file_done = 0) } } if (session_done != 0) //会话发生错误, 退出会话 { break; //break for (session_done = 0) } } return (int32_t)size; }