3939#include "buffer_utils.h"
4040
4141/* Flash */
42- #define PUYA_FLASH_START 0x08000000U
43- #define PUYA_FLASH_PAGE_SIZE 128
42+ #define PUYA_FLASH_START 0x08000000U
43+ #define PUYA_00A_FLASH_PAGE_SIZE 128
44+ #define PUYA_07X_FLASH_PAGE_SIZE 256
4445
4546/* Pile of timing parameters needed to make sure flash works,
4647 * see section "4.4. Flash configuration bytes" of the RM.
4748 */
48- #define PUYA_FLASH_TIMING_CAL_BASE 0x1fff0f1cU
49+ #define PUYA_00A_FLASH_TIMING_CAL_BASE 0x1fff0f1cU
50+
4951/* This config word is undocumented, but the Puya-ISP boot code
5052 * uses it to determine the valid flash/ram size.
5153 * (yes, this *does* include undocumented free extra flash/ram in the 002A)
5254 *
5355 * bits[2:0] => flash size in multiples of 0x2000 bytes, minus 1
5456 * bits[5:4] => RAM size in multiples of 0x800 bytes, minus 1
5557 */
56- #define PUYA_FLASH_RAM_SZ 0x1fff0ffcU
58+ #define PUYA_00A_FLASH_RAM_SZ 0x1fff0ffcU
59+ #define PUYA_07X_FLASH_RAM_SZ 0x1FFF31FCU
60+
5761#define PUYA_FLASH_SZ_SHIFT 0U
5862#define PUYA_FLASH_SZ_MASK 7U
5963#define PUYA_FLASH_UNIT_SHIFT 13U
105109 */
106110static bool puya_flash_erase (target_flash_s * flash , target_addr_t addr , size_t len );
107111static bool puya_flash_write (target_flash_s * flash , target_addr_t dest , const void * src , size_t len );
108- static bool puya_flash_prepare (target_flash_s * flash );
112+ static bool puya_00a_flash_prepare (target_flash_s * flash );
113+ static bool puya_07x_flash_prepare (target_flash_s * flash );
109114static bool puya_flash_done (target_flash_s * flash );
110115
111116bool puya_probe (target_s * target )
@@ -114,39 +119,52 @@ bool puya_probe(target_s *target)
114119 size_t flash_size = 0U ;
115120
116121 const uint32_t dbg_idcode = target_mem32_read32 (target , PUYA_DBG_IDCODE );
117- if ((dbg_idcode & 0xfffU ) == 0 ) {
118- const uint32_t flash_ram_sz = target_mem32_read32 (target , PUYA_FLASH_RAM_SZ );
122+ if (dbg_idcode == 0x06188061U ) {
123+ const uint32_t flash_ram_sz = target_mem32_read32 (target , PUYA_07X_FLASH_RAM_SZ );
124+ flash_size = (((flash_ram_sz >> PUYA_FLASH_SZ_SHIFT ) & PUYA_FLASH_SZ_MASK ) + 1 ) << PUYA_FLASH_UNIT_SHIFT ;
125+ ram_size = (((flash_ram_sz >> PUYA_RAM_SZ_SHIFT ) & PUYA_RAM_SZ_MASK ) + 1 ) << PUYA_RAM_UNIT_SHIFT ;
126+ target -> driver = "PY32F07x" ;
127+ target_add_ram32 (target , PUYA_RAM_START , 0x4000 );
128+ } else if ((dbg_idcode & 0xfffU ) == 0 ) {
129+ const uint32_t flash_ram_sz = target_mem32_read32 (target , PUYA_00A_FLASH_RAM_SZ );
119130 flash_size = (((flash_ram_sz >> PUYA_FLASH_SZ_SHIFT ) & PUYA_FLASH_SZ_MASK ) + 1 ) << PUYA_FLASH_UNIT_SHIFT ;
120131 ram_size = (((flash_ram_sz >> PUYA_RAM_SZ_SHIFT ) & PUYA_RAM_SZ_MASK ) + 1 ) << PUYA_RAM_UNIT_SHIFT ;
121132 // TODO: which part families does this actually correspond to?
122133 // Tested with a PY32F002AW15U which returns 0x60001000 in IDCODE
123134 target -> driver = "PY32Fxxx" ;
135+ target_add_ram32 (target , PUYA_RAM_START , ram_size );
124136 } else {
125137 DEBUG_TARGET ("Unknown PY32 device %08" PRIx32 "\n" , dbg_idcode );
126138 return false;
127139 }
128140
129- target_add_ram32 (target , PUYA_RAM_START , ram_size );
130141 target_flash_s * flash = calloc (1 , sizeof (* flash ));
131142 if (!flash ) { /* calloc failed: heap exhaustion */
132143 DEBUG_ERROR ("calloc: failed in %s\n" , __func__ );
133144 return false;
134145 }
146+
135147 flash -> start = PUYA_FLASH_START ;
136148 flash -> length = flash_size ;
137- flash -> blocksize = PUYA_FLASH_PAGE_SIZE ;
138- flash -> writesize = PUYA_FLASH_PAGE_SIZE ;
139149 flash -> erase = puya_flash_erase ;
140150 flash -> write = puya_flash_write ;
141- flash -> prepare = puya_flash_prepare ;
151+ if (dbg_idcode == 0x06188061U ) {
152+ flash -> blocksize = PUYA_07X_FLASH_PAGE_SIZE ;
153+ flash -> writesize = PUYA_07X_FLASH_PAGE_SIZE ;
154+ flash -> prepare = puya_07x_flash_prepare ;
155+ } else {
156+ flash -> blocksize = PUYA_00A_FLASH_PAGE_SIZE ;
157+ flash -> writesize = PUYA_00A_FLASH_PAGE_SIZE ;
158+ flash -> prepare = puya_00a_flash_prepare ;
159+ }
142160 flash -> done = puya_flash_done ;
143161 flash -> erased = 0xffU ;
144162 target_add_flash (target , flash );
145163
146164 return true;
147165}
148166
149- static bool puya_flash_prepare (target_flash_s * flash )
167+ static bool puya_00a_flash_prepare (target_flash_s * flash )
150168{
151169 target_mem32_write32 (flash -> t , PUYA_FLASH_KEYR , PUYA_FLASH_KEYR_KEY1 );
152170 target_mem32_write32 (flash -> t , PUYA_FLASH_KEYR , PUYA_FLASH_KEYR_KEY2 );
@@ -157,20 +175,62 @@ static bool puya_flash_prepare(target_flash_s *flash)
157175 hsi_fs = 0 ;
158176 DEBUG_TARGET ("HSI frequency selection is %d\n" , hsi_fs );
159177
160- uint32_t eppara [5 ] = {0 };
161- for (uint16_t i = 0 ; i < 5 ; i ++ ) {
162- eppara [i ] = target_mem32_read32 (flash -> t , PUYA_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + i * 4U );
163- DEBUG_TARGET ("PY32 flash timing cal %u: %08" PRIx32 "\n" , i , eppara [i ]);
164- }
165- target_mem32_write32 (flash -> t , PUYA_FLASH_TS0 , eppara [0 ] & 0xffU );
166- target_mem32_write32 (flash -> t , PUYA_FLASH_TS1 , (eppara [0 ] >> 16U ) & 0x1ffU );
167- target_mem32_write32 (flash -> t , PUYA_FLASH_TS3 , (eppara [0 ] >> 8U ) & 0xffU );
168- target_mem32_write32 (flash -> t , PUYA_FLASH_TS2P , eppara [1 ] & 0xffU );
169- target_mem32_write32 (flash -> t , PUYA_FLASH_TPS3 , (eppara [1 ] >> 16U ) & 0x7ffU );
170- target_mem32_write32 (flash -> t , PUYA_FLASH_PERTPE , eppara [2 ] & 0x1ffffU );
171- target_mem32_write32 (flash -> t , PUYA_FLASH_SMERTPE , eppara [3 ] & 0x1ffffU );
172- target_mem32_write32 (flash -> t , PUYA_FLASH_PRGTPE , eppara [4 ] & 0xffffU );
173- target_mem32_write32 (flash -> t , PUYA_FLASH_PRETPE , (eppara [4 ] >> 16U ) & 0x3fffU );
178+ const uint32_t eppara0 = target_mem32_read32 (flash -> t , PUYA_00A_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + 0 );
179+ const uint32_t eppara1 = target_mem32_read32 (flash -> t , PUYA_00A_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + 4 );
180+ const uint32_t eppara2 = target_mem32_read32 (flash -> t , PUYA_00A_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + 8 );
181+ const uint32_t eppara3 = target_mem32_read32 (flash -> t , PUYA_00A_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + 12 );
182+ const uint32_t eppara4 = target_mem32_read32 (flash -> t , PUYA_00A_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + 16 );
183+ DEBUG_TARGET ("PY32 flash timing cal 0: %08" PRIx32 "\n" , eppara0 );
184+ DEBUG_TARGET ("PY32 flash timing cal 1: %08" PRIx32 "\n" , eppara1 );
185+ DEBUG_TARGET ("PY32 flash timing cal 2: %08" PRIx32 "\n" , eppara2 );
186+ DEBUG_TARGET ("PY32 flash timing cal 3: %08" PRIx32 "\n" , eppara3 );
187+ DEBUG_TARGET ("PY32 flash timing cal 4: %08" PRIx32 "\n" , eppara4 );
188+
189+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS0 , eppara0 & 0xffU );
190+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS1 , (eppara0 >> 16U ) & 0x1ffU );
191+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS3 , (eppara0 >> 8U ) & 0xffU );
192+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS2P , eppara1 & 0xffU );
193+ target_mem32_write32 (flash -> t , PUYA_FLASH_TPS3 , (eppara1 >> 16U ) & 0x7ffU );
194+ target_mem32_write32 (flash -> t , PUYA_FLASH_PERTPE , eppara2 & 0x1ffffU );
195+ target_mem32_write32 (flash -> t , PUYA_FLASH_SMERTPE , eppara3 & 0x1ffffU );
196+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRGTPE , eppara4 & 0xffffU );
197+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRETPE , (eppara4 >> 16U ) & 0x3fffU );
198+
199+ return true;
200+ }
201+
202+ static bool puya_07x_flash_prepare (target_flash_s * flash )
203+ {
204+ target_mem32_write32 (flash -> t , PUYA_FLASH_KEYR , PUYA_FLASH_KEYR_KEY1 );
205+ target_mem32_write32 (flash -> t , PUYA_FLASH_KEYR , PUYA_FLASH_KEYR_KEY2 );
206+
207+ uint8_t hsi_fs =
208+ (target_mem32_read32 (flash -> t , PUYA_RCC_ICSCR ) >> PUYA_RCC_ICSCR_HSI_FS_SHIFT ) & PUYA_RCC_ICSCR_HSI_FS_MASK ;
209+ if (hsi_fs > 4 )
210+ hsi_fs = 0 ;
211+ DEBUG_TARGET ("HSI frequency selection is %d\n" , hsi_fs );
212+
213+ const uint32_t eppara0 = target_mem32_read32 (flash -> t , 0x1FFF3238 + 4 * 0x28 );
214+ const uint32_t eppara1 = target_mem32_read32 (flash -> t , 0x1FFF3240 + 4 * 0x28 );
215+ const uint32_t eppara2 = target_mem32_read32 (flash -> t , 0x1FFF3248 + 4 * 0x28 );
216+ const uint32_t eppara3 = target_mem32_read32 (flash -> t , 0x1FFF3250 + 4 * 0x28 );
217+ const uint32_t eppara4 = target_mem32_read32 (flash -> t , 0x1FFF3258 + 4 * 0x28 );
218+
219+ DEBUG_TARGET ("PY32 flash timing cal 0: %08" PRIx32 "\n" , eppara0 );
220+ DEBUG_TARGET ("PY32 flash timing cal 1: %08" PRIx32 "\n" , eppara1 );
221+ DEBUG_TARGET ("PY32 flash timing cal 2: %08" PRIx32 "\n" , eppara2 );
222+ DEBUG_TARGET ("PY32 flash timing cal 3: %08" PRIx32 "\n" , eppara3 );
223+ DEBUG_TARGET ("PY32 flash timing cal 4: %08" PRIx32 "\n" , eppara4 );
224+
225+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS0 , eppara0 & 0xffU );
226+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS1 , (eppara0 >> 16U ) & 0x1ffU );
227+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS3 , (eppara0 >> 8U ) & 0xffU );
228+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS2P , eppara1 & 0xffU );
229+ target_mem32_write32 (flash -> t , PUYA_FLASH_TPS3 , (eppara1 >> 16U ) & 0x7ffU );
230+ target_mem32_write32 (flash -> t , PUYA_FLASH_PERTPE , eppara2 & 0x1ffffU );
231+ target_mem32_write32 (flash -> t , PUYA_FLASH_SMERTPE , eppara3 & 0x1ffffU );
232+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRGTPE , eppara4 & 0xffffU );
233+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRETPE , (eppara4 >> 16U ) & 0xFFFFU ); // diff
174234
175235 return true;
176236}
0 commit comments