1 /************************************************************************* 2 * 3 * File name : FlashPrg.c 4 * Description : Cypress FM4 internal flashloader 5 * 6 * History : 7 * 1. Date : 9, 2018 8 * Author : Kevin Zhou 9 * Description : Adapt for S6E2H series 10 * 11 * $Revision: 0 $ 12 **************************************************************************/ 13 #include "FlashOS.H" // FlashOS Structures 14 15 #include "s6e2hgxg.h" 16 17 18 typedef enum {IDLE, ERASE, WRITE} status; 19 20 #define flash_unit u16 21 #define flash_ptr volatile flash_unit * 22 23 //Flash commands 24 #define READ_RESET 0xF0 25 #define MASS_ERASE 0x10 26 #define SECTOR_ERASE 0x30 27 #define FLASH_WRITE 0xA0 28 #define SECTOR_ERASE_SUSPEND 0xB0 29 #define READ 0xF0 30 #define DATA1 0x55 //General command signature 31 #define DATA2 0x80 //General command signature 32 #define DATA3 0xAA //General command signature 33 34 //Magic flash addresses 35 #define ADDRESS1 0xAA8 36 #define ADDRESS2 0x554 37 38 //Commands use 16bit access 39 #define SET_COMMAND(data, address) *((flash_ptr)address) = (flash_unit)data 40 41 //Hardware sequence flags 42 #define DPOL 0x80 43 #define TOGG 0x40 44 #define TLOV 0x20 45 #define SETI 0x08 46 #define TOGG2 0x04 47 48 #define PROTECT_OFFSET 0x400000 49 #define CR_TRIM_OFFSET 0x402000 50 51 static void FlashCleanup(flash_ptr flash_halfword) { 52 *flash_halfword = READ_RESET; 53 } 54 55 56 int Init (u32 adr, u32 clk, u32 fnc) 57 { 58 //Set access size 59 FM4_FLASH_IF->FASZR_f.ASZ = 1; 60 FM4_WORKFLASH_IF->WFASZR_f.ASZ = 0; 61 62 return(0); 63 } 64 65 int UnInit (u32 fnc) 66 { 67 return 0; 68 } 69 70 int EraseChip (void) 71 { 72 return (0); 73 } 74 75 int EraseSector (u32 adr,u32 sz) 76 { 77 flash_unit tmp; 78 flash_ptr block_start = (flash_ptr)adr; 79 80 SET_COMMAND(DATA3, ADDRESS1); 81 SET_COMMAND(DATA1, ADDRESS2); 82 SET_COMMAND(DATA2, ADDRESS1); 83 SET_COMMAND(DATA3, ADDRESS1); 84 SET_COMMAND(DATA1, ADDRESS2); 85 SET_COMMAND(SECTOR_ERASE, block_start); 86 tmp = *(flash_ptr)block_start; 87 88 while(TOGG & (*(flash_ptr)block_start ^ (tmp = *(flash_ptr)block_start))) 89 { 90 if(TLOV & tmp) { 91 if(TOGG & (tmp ^ *(flash_ptr)block_start)) 92 { 93 FlashCleanup(block_start); 94 return 1; 95 } 96 } 97 } 98 99 return (0); 100 } 101 102 int ProgramPage (u32 adr, u32 sz, unsigned char *buf) 103 { 104 flash_unit tmp; 105 106 flash_ptr flash_halfword = (flash_ptr)adr; 107 flash_unit * buffer_halfword = (flash_unit *)buf; 108 109 for (; sz; sz-=sizeof(flash_unit), flash_halfword++, buffer_halfword++) 110 { 111 SET_COMMAND(DATA3, ADDRESS1); 112 SET_COMMAND(DATA1, ADDRESS2); 113 SET_COMMAND(FLASH_WRITE, ADDRESS1); 114 SET_COMMAND(*buffer_halfword, flash_halfword); 115 tmp = *flash_halfword; 116 117 while(TOGG & (*flash_halfword ^ (tmp = *flash_halfword))) 118 { 119 if(TLOV & tmp) { 120 if(TOGG & (tmp ^ *flash_halfword)) 121 { 122 FlashCleanup(flash_halfword); 123 return 1; 124 } 125 } 126 } 127 } 128 129 return (0); 130 }