/**
* @file IAP_YMODEM_STM32F1_ATY.h
*
* @param Project DEVICE_GENERAL_ATY_LIB
*
* @author ATY
*
* @copyright
* - Copyright 2017 - 2023 MZ-ATY
* - This code follows:
* - MZ-ATY Various Contents Joint Statement -
*
* https://mengze.top/MZ-ATY_VCJS
* - CC 4.0 BY-NC-SA -
*
* https://creativecommons.org/licenses/by-nc-sa/4.0/
* - Your use will be deemed to have accepted the terms of this statement.
*
* @brief functions of IAP with YMODEM for STM32F1xx
*
* @version
* - 1_01_240911 > ATY
* -# Preliminary version, first Release
* - 1_03_250701 > ATY
* -# real fix to lib type
* - 1_03_250704 > ATY
* -# finish uart and ucdc IAP whole test
* - 1_04_251016 > ATY
* -# fix large bin 255 limit at 128 and 1K trans in USB CDC
********************************************************************************
*/
#ifndef __IAP_YMODEM_STM32F1_ATY_H
#define __IAP_YMODEM_STM32F1_ATY_H
#include "INCLUDE_ATY.h"
#include "HW_RESET_ATY.h"
/******************************* For user *************************************/
// do not forget change USER_VECT_TAB_ADDRESS VECT_TAB_OFFSET at system_stm32f1xx.c
#ifndef IAP_YMODEM_STM32F1_ATY_DBG
// #define IAP_YMODEM_STM32F1_ATY_DBG
#endif
#define IAP_VerA 102
#define IAP_VerB 251
#define IAP_VerC 202
#define Interface_UART huart3
extern UART_HandleTypeDef Interface_UART;
#ifndef IAP_YMODEM_STM32F1_ATY_USB
#if 0
#define IAP_YMODEM_STM32F1_ATY_USB
#endif
#endif
#ifndef IAP_S_TIME
#ifdef IAP_YMODEM_STM32F1_ATY_USB
#define IAP_S_TIME RX_TIMEOUT
#else
// #define IAP_S_TIME RX_TIMEOUT
#define IAP_S_TIME 1000
#endif
#endif
#ifndef IAP_3_TIME
#define IAP_3_TIME 5000
#endif
#ifdef IAP_YMODEM_STM32F1_ATY_USB
#include "usbd_def.h"
#include "usb_device.h"
#include "usbd_cdc_if.h"
extern USBD_HandleTypeDef hUsbDeviceFS;
void PUT_IN_CDC_Receive_FS(uint8_t* Buf, uint32_t* Len);
#endif
void Main_Menu(void);
void Main_Cycle(void);
/******************************************************************************/
/* interface realize **********************************************************/
/**
* @brief Comm status structures definition
*/
typedef enum{
COM_OK = 0x00,
COM_ERROR = 0x01,
COM_ABORT = 0x02,
COM_TIMEOUT = 0x03,
COM_DATA = 0x04,
COM_LIMIT = 0x05
} COM_StatusTypeDef;
HAL_StatusTypeDef Interface_PutString(uint8_t* p_string);
HAL_StatusTypeDef Interface_PutByte(uint8_t bytes);
COM_StatusTypeDef Interface_Download(void);
void Interface_Upload(void);
/* common *********************************************************************/
/* Constants used by Serial Command Line Mode */
#define TX_TIMEOUT ((uint32_t)100)
#define RX_TIMEOUT HAL_MAX_DELAY
#define IS_CAP_LETTER(c) (((c) >= 'A') && ((c) <= 'F'))
#define IS_LC_LETTER(c) (((c) >= 'a') && ((c) <= 'f'))
#define IS_09(c) (((c) >= '0') && ((c) <= '9'))
#define ISVALIDHEX(c) (IS_CAP_LETTER(c) || IS_LC_LETTER(c) || IS_09(c))
#define ISVALIDDEC(c) IS_09(c)
#define CONVERTDEC(c) (c - '0')
#define CONVERTHEX_ALPHA(c) (IS_CAP_LETTER(c) ? ((c) - 'A'+10) : ((c) - 'a'+10))
#define CONVERTHEX(c) (IS_09(c) ? ((c) - '0') : CONVERTHEX_ALPHA(c))
void Int2Str(uint8_t* p_str, uint32_t intnum);
uint32_t Str2Int(uint8_t* inputstr, uint32_t* intnum);
/* flash_if *******************************************************************/
/* Error code */
enum{
FLASHIF_OK = 0,
FLASHIF_ERASEKO,
FLASHIF_WRITINGCTRL_ERROR,
FLASHIF_WRITING_ERROR,
FLASHIF_PROTECTION_ERRROR
};
/* Protection type */
enum{
FLASHIF_PROTECTION_NONE = 0,
FLASHIF_PROTECTION_PCROPENABLED = 0x1,
FLASHIF_PROTECTION_WRPENABLED = 0x2,
FLASHIF_PROTECTION_RDPENABLED = 0x4,
};
/* Protection update */
enum{
FLASHIF_WRP_ENABLE,
FLASHIF_WRP_DISABLE
};
/* Define the address from where user application will be loaded.
Note: this area is reserved for the IAP code */
#define FLASH_PAGE_STEP FLASH_PAGE_SIZE /* Size of page : 2 Kbytes */
#ifndef APPLICATION_ADDRESS
#define APPLICATION_ADDRESS (uint32_t)0x08006000 /* Start user code address: ADDR_FLASH_PAGE_8 */
#endif
/* Notable Flash addresses */
#define USER_FLASH_END_ADDRESS 0x08020000
/* Define the user application size */
#define USER_FLASH_SIZE ((uint32_t)0x00012000) /* Small default template application */
/* Define bitmap representing user flash area that could be write protected (pages 8 to 39) */
#if defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6)
// 32KB Flash: 1KB/page, total 32 pages (0-31)
// Max page is 31, so protect from 8 to 31
#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES8TO11 | OB_WRP_PAGES12TO15 | \
OB_WRP_PAGES16TO19 | OB_WRP_PAGES20TO23 | \
OB_WRP_PAGES24TO27 | OB_WRP_PAGES28TO31)
#elif defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB)
// 128KB Flash: 1KB/page, total 128 pages (0-127)
// Protect from 8 to 39
#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES8TO11 | OB_WRP_PAGES12TO15 | \
OB_WRP_PAGES16TO19 | OB_WRP_PAGES20TO23 | \
OB_WRP_PAGES24TO27 | OB_WRP_PAGES28TO31 | \
OB_WRP_PAGES32TO35 | OB_WRP_PAGES36TO39)
#elif defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE)
// 512KB Flash: mixed sizes
// Pages 8-39 are valid in first 64KB (1KB/page)
#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES8TO9 | OB_WRP_PAGES10TO11 | \
OB_WRP_PAGES12TO13 | OB_WRP_PAGES14TO15 | \
OB_WRP_PAGES16TO17 | OB_WRP_PAGES18TO19 | \
OB_WRP_PAGES20TO21 | OB_WRP_PAGES22TO23 | \
OB_WRP_PAGES24TO25 | OB_WRP_PAGES26TO27 | \
OB_WRP_PAGES28TO29 | OB_WRP_PAGES30TO31 | \
OB_WRP_PAGES32TO33 | OB_WRP_PAGES34TO35 | \
OB_WRP_PAGES36TO37 | OB_WRP_PAGES38TO39)
#elif defined(STM32F105xC) || defined(STM32F107xC)
// Connectivity line: 256KB Flash, 2KB/page
// So pages 8-39 = 16KB - 78KB
#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES8TO9 | OB_WRP_PAGES10TO11 | \
OB_WRP_PAGES12TO13 | OB_WRP_PAGES14TO15 | \
OB_WRP_PAGES16TO17 | OB_WRP_PAGES18TO19 | \
OB_WRP_PAGES20TO21 | OB_WRP_PAGES22TO23 | \
OB_WRP_PAGES24TO25 | OB_WRP_PAGES26TO27 | \
OB_WRP_PAGES28TO29 | OB_WRP_PAGES30TO31 | \
OB_WRP_PAGES32TO33 | OB_WRP_PAGES34TO35 | \
OB_WRP_PAGES36TO37 | OB_WRP_PAGES38TO39)
#elif defined(STM32F101xG) || defined(STM32F103xG)
// XL-density: up to 1MB Flash, mixed page sizes
// Pages 8-39 are valid and all 1KB/page
#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES8TO9 | OB_WRP_PAGES10TO11 | \
OB_WRP_PAGES12TO13 | OB_WRP_PAGES14TO15 | \
OB_WRP_PAGES16TO17 | OB_WRP_PAGES18TO19 | \
OB_WRP_PAGES20TO21 | OB_WRP_PAGES22TO23 | \
OB_WRP_PAGES24TO25 | OB_WRP_PAGES26TO27 | \
OB_WRP_PAGES28TO29 | OB_WRP_PAGES30TO31 | \
OB_WRP_PAGES32TO33 | OB_WRP_PAGES34TO35 | \
OB_WRP_PAGES36TO37 | OB_WRP_PAGES38TO39)
#else
#error "Unsupported STM32F1 device or missing Flash protection definition."
#endif
/* ABSoulute value */
#define ABS_RETURN(x,y) ((x) < (y)) ? ((y)-(x)) : ((x)-(y))
/* Get the number of sectors from where the user program will be loaded */
#define FLASH_SECTOR_NUMBER ((uint32_t)(ABS_RETURN(APPLICATION_ADDRESS,FLASH_START_BANK1))>>12)
/* Compute the mask to test if the Flash memory, where the user program will be
loaded, is write protected */
#define FLASH_PROTECTED_SECTORS (~(uint32_t)((1 << FLASH_SECTOR_NUMBER) - 1))
void FLASH_If_Init(void);
uint32_t FLASH_If_Erase(uint32_t StartSector);
uint32_t FLASH_If_GetWriteProtectionStatus(void);
uint32_t FLASH_If_Write(uint32_t destination, uint32_t* p_source, uint32_t length);
uint32_t FLASH_If_WriteProtectionConfig(uint32_t modifier);
/* ymodem *********************************************************************/
/* Packet structure defines */
#define PACKET_HEADER_SIZE ((uint32_t)3)
//#define PACKET_DATA_INDEX ((uint32_t)4)
//#define PACKET_START_INDEX ((uint32_t)1)
//#define PACKET_NUMBER_INDEX ((uint32_t)2)
//#define PACKET_CNUMBER_INDEX ((uint32_t)3)
#define PACKET_DATA_INDEX ((uint32_t)3)
#define PACKET_START_INDEX ((uint32_t)0)
#define PACKET_NUMBER_INDEX ((uint32_t)1)
#define PACKET_CNUMBER_INDEX ((uint32_t)2)
#define PACKET_TRAILER_SIZE ((uint32_t)2)
#define PACKET_OVERHEAD_SIZE (PACKET_HEADER_SIZE + PACKET_TRAILER_SIZE - 1)
#define PACKET_SIZE ((uint32_t)128)
#define PACKET_1K_SIZE ((uint32_t)1024)
/* /-------- Packet in IAP memory ------------------------------------------\
* | 0 | 1 | 2 | 3 | 4 | ... | n+4 | n+5 | n+6 |
* |------------------------------------------------------------------------|
* | unused | start | number | !num | data[0] | ... | data[n] | crc0 | crc1 |
* \------------------------------------------------------------------------/
* the first byte is left unused for memory alignment reasons */
#define FILE_NAME_LENGTH ((uint32_t)64)
#define FILE_SIZE_LENGTH ((uint32_t)16)
#define SOH ((uint8_t)0x01) /* start of 128-byte data packet */
#define STX ((uint8_t)0x02) /* start of 1024-byte data packet */
#define EOT ((uint8_t)0x04) /* end of transmission */
#define ACK ((uint8_t)0x06) /* acknowledge */
#define NAK ((uint8_t)0x15) /* negative acknowledge */
#define CA ((uint32_t)0x18) /* two of these in succession aborts transfer */
#define CRC16 ((uint8_t)0x43) /* 'C' == 0x43, request 16-bit CRC */
#define NEGATIVE_BYTE ((uint8_t)0xFF)
#define ABORT1 ((uint8_t)0x41) /* 'A' == 0x41, abort by user */
#define ABORT2 ((uint8_t)0x61) /* 'a' == 0x61, abort by user */
#define NAK_TIMEOUT ((uint32_t)0x100000)
#define DOWNLOAD_TIMEOUT ((uint32_t)1000) /* One second retry delay */
#define MAX_ERRORS ((uint32_t)5)
static void PrepareIntialPacket(uint8_t* p_data, const uint8_t* p_file_name, uint32_t length);
static void PreparePacket(uint8_t* p_source, uint8_t* p_packet, uint8_t pkt_nr, uint32_t size_blk);
static HAL_StatusTypeDef ReceivePacket(uint8_t* p_data, uint32_t* p_length, uint32_t timeout);
uint16_t UpdateCRC16(uint16_t crc_in, uint8_t byte);
uint16_t Cal_CRC16(const uint8_t* p_data, uint32_t size);
uint8_t CalcChecksum(const uint8_t* p_data, uint32_t size);
COM_StatusTypeDef Ymodem_Receive(uint32_t* p_size);
COM_StatusTypeDef Ymodem_Transmit(uint8_t* p_buf, const uint8_t* p_file_name, uint32_t file_size);
extern uint8_t aFileName[FILE_NAME_LENGTH];
#endif /* __IAP_YMODEM_STM32F1_ATY_H */
/******************************** End Of File *********************************/