4242#define PUYA_FLASH_START 0x08000000U
4343#define PUYA_FLASH_PAGE_SIZE 128
4444
45- /* Pile of timing parameters needed to make sure flash works,
46- * see section "4.4 . Flash configuration bytes" of the RM.
45+ /*
46+ * Pile of timing parameters needed to make sure flash works, see section "4.5 . Flash configuration bytes" of the RM.
4747 */
48- #define PUYA_FLASH_TIMING_CAL_BASE 0x1fff0f1cU
48+ #define PUYA_FLASH_TIMING_CAL_PY32F002A_BASE 0x1fff0f1cU
49+ #define PY32F002A_EPPARA0_TS0_SHIFT 0U
50+ #define PY32F002A_EPPARA0_TS0_MASK 0xffU
51+ #define PY32F002A_EPPARA0_TS3_SHIFT 8U
52+ #define PY32F002A_EPPARA0_TS3_MASK 0xffU
53+ #define PY32F002A_EPPARA0_TS1_SHIFT 16U
54+ #define PY32F002A_EPPARA0_TS1_MASK 0x1ffU
55+ #define PY32F002A_EPPARA1_TS2P_SHIFT 0U
56+ #define PY32F002A_EPPARA1_TS2P_MASK 0xffU
57+ #define PY32F002A_EPPARA1_TPS3_SHIFT 16U
58+ #define PY32F002A_EPPARA1_TPS3_MASK 0x7ffU
59+ #define PY32F002A_EPPARA2_PERTPE_SHIFT 0U
60+ #define PY32F002A_EPPARA2_PERTPE_MASK 0x1ffffU
61+ #define PY32F002A_EPPARA3_SMERTPE_SHIFT 0U
62+ #define PY32F002A_EPPARA3_SMERTPE_MASK 0x1ffffU
63+ #define PY32F002A_EPPARA4_PRGTPE_SHIFT 0U
64+ #define PY32F002A_EPPARA4_PRGTPE_MASK 0xffffU
65+ #define PY32F002A_EPPARA4_PRETPE_SHIFT 16U
66+ /* This one is a bit of a mess. The PY32F002A Reference Manual says EPPARA4 26:16 (11 bit) are PRETPE[11:0] (12
67+ * bit). FLASH_PRETPE is 14 bit wide (0:13) and must be initialised from the value in EPPARA4. The PY32F002A flash
68+ * driver (PY32F0xx_20.FLM) contained in the Keil Device Family Pack v1.2.1 provided by Puya stores the full upper 16
69+ * bits of EPPARA4 into FLASH_PRETPE. Presumably the reserved bits are 0. We use the width of FLASH_PRETPE (14 bits)
70+ * for now. */
71+ #define PY32F002A_EPPARA4_PRETPE_MASK 0x3fffU
72+ #define PUYA_FLASH_TIMING_CAL_PY32F002B_BASE 0x1fff011cU
73+ #define PY32F002B_EPPARA0_TS0_SHIFT 0U
74+ #define PY32F002B_EPPARA0_TS0_MASK 0x1ffU
75+ #define PY32F002B_EPPARA0_TS3_SHIFT 9U
76+ #define PY32F002B_EPPARA0_TS3_MASK 0x1ffU
77+ #define PY32F002B_EPPARA0_TS1_SHIFT 18U
78+ #define PY32F002B_EPPARA0_TS1_MASK 0x3ffU
79+ #define PY32F002B_EPPARA1_TS2P_SHIFT 0U
80+ #define PY32F002B_EPPARA1_TS2P_MASK 0x1ffU
81+ #define PY32F002B_EPPARA1_TPS3_SHIFT 16U
82+ #define PY32F002B_EPPARA1_TPS3_MASK 0xfffU
83+ #define PY32F002B_EPPARA2_PERTPE_SHIFT 0U
84+ #define PY32F002B_EPPARA2_PERTPE_MASK 0x3ffffU
85+ #define PY32F002B_EPPARA3_SMERTPE_SHIFT 0U
86+ #define PY32F002B_EPPARA3_SMERTPE_MASK 0x3ffffU
87+ #define PY32F002B_EPPARA4_PRGTPE_SHIFT 0U
88+ #define PY32F002B_EPPARA4_PRGTPE_MASK 0xffffU
89+ #define PY32F002B_EPPARA4_PRETPE_SHIFT 16U
90+ #define PY32F002B_EPPARA4_PRETPE_MASK 0x3fffU
91+
4992/* This config word is undocumented, but the Puya-ISP boot code
5093 * uses it to determine the valid flash/ram size.
5194 * (yes, this *does* include undocumented free extra flash/ram in the 002A)
99142/* DBG */
100143#define PUYA_DBG_BASE 0x40015800U
101144#define PUYA_DBG_IDCODE (PUYA_DBG_BASE + 0x00U)
145+ /*
146+ * The format and values of the IDCODE register are undocumented but the vendor SDK splits IDCODE into 11:0 DEV_ID and
147+ * 31:16 REV_ID.
148+ */
149+ #define PUYA_DBG_IDCODE_DEV_ID_SHIFT 0U
150+ #define PUYA_DBG_IDCODE_DEV_ID_MASK 0xfffU
151+ #define PUYA_DBG_IDCODE_REV_ID_SHIFT 16U
152+ #define PUYA_DBG_IDCODE_REV_ID_MASK 0xffffU
153+
154+ /* On PY32F002AW15U an IDCODE value of 0x60001000 was observed */
155+ #define PUYA_DEV_ID_PY32F002A 0x000U
156+ /*
157+ * On PY32F002BF15P an IDCODE value of 0x20220064 was observed. Internet search shows the same value is used on
158+ * PY32F002BW15.
159+ */
160+ #define PUYA_DEV_ID_PY32F002B 0x064U
102161
103162/*
104163 * Flash functions
@@ -114,18 +173,32 @@ bool puya_probe(target_s *target)
114173 size_t flash_size = 0U ;
115174
116175 const uint32_t dbg_idcode = target_mem32_read32 (target , PUYA_DBG_IDCODE );
117- if ((dbg_idcode & 0xfffU ) == 0 ) {
176+ const uint16_t dev_id = (dbg_idcode >> PUYA_DBG_IDCODE_DEV_ID_SHIFT ) & PUYA_DBG_IDCODE_DEV_ID_MASK ;
177+ switch (dev_id ) {
178+ case PUYA_DEV_ID_PY32F002A : {
118179 const uint32_t flash_ram_sz = target_mem32_read32 (target , PUYA_FLASH_RAM_SZ );
119180 flash_size = (((flash_ram_sz >> PUYA_FLASH_SZ_SHIFT ) & PUYA_FLASH_SZ_MASK ) + 1 ) << PUYA_FLASH_UNIT_SHIFT ;
120181 ram_size = (((flash_ram_sz >> PUYA_RAM_SZ_SHIFT ) & PUYA_RAM_SZ_MASK ) + 1 ) << PUYA_RAM_UNIT_SHIFT ;
121- // TODO: which part families does this actually correspond to?
122- // Tested with a PY32F002AW15U which returns 0x60001000 in IDCODE
123- target -> driver = "PY32Fxxx" ;
124- } else {
182+ target -> driver = "PY32F002A" ;
183+ break ;
184+ }
185+ case PUYA_DEV_ID_PY32F002B :
186+ /*
187+ * 0x1fff0ffc contains 0; did not find any other location that looks like it might contain the flash
188+ * and RAM sizes. We'll hard-code the datasheet values for now. Both flash size and RAM size actually
189+ * match the datasheet value, unlike PY32F002A which (sometimes?) has more RAM and flash than
190+ * documented.
191+ */
192+ flash_size = 24U * 1024U ;
193+ ram_size = 3U * 1024U ;
194+ target -> driver = "PY32F002B" ;
195+ break ;
196+ default :
125197 DEBUG_TARGET ("Unknown PY32 device %08" PRIx32 "\n" , dbg_idcode );
126198 return false;
127199 }
128200
201+ target -> part_id = dev_id ;
129202 target_add_ram32 (target , PUYA_RAM_START , ram_size );
130203 target_flash_s * flash = calloc (1 , sizeof (* flash ));
131204 if (!flash ) { /* calloc failed: heap exhaustion */
@@ -151,33 +224,81 @@ static bool puya_flash_prepare(target_flash_s *flash)
151224 target_mem32_write32 (flash -> t , PUYA_FLASH_KEYR , PUYA_FLASH_KEYR_KEY1 );
152225 target_mem32_write32 (flash -> t , PUYA_FLASH_KEYR , PUYA_FLASH_KEYR_KEY2 );
153226
154- uint8_t hsi_fs =
155- (target_mem32_read32 (flash -> t , PUYA_RCC_ICSCR ) >> PUYA_RCC_ICSCR_HSI_FS_SHIFT ) & PUYA_RCC_ICSCR_HSI_FS_MASK ;
156- if (hsi_fs > 4 )
157- hsi_fs = 0 ;
158- DEBUG_TARGET ("HSI frequency selection is %d\n" , hsi_fs );
159-
160- const uint32_t eppara0 = target_mem32_read32 (flash -> t , PUYA_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + 0 );
161- const uint32_t eppara1 = target_mem32_read32 (flash -> t , PUYA_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + 4 );
162- const uint32_t eppara2 = target_mem32_read32 (flash -> t , PUYA_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + 8 );
163- const uint32_t eppara3 = target_mem32_read32 (flash -> t , PUYA_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + 12 );
164- const uint32_t eppara4 = target_mem32_read32 (flash -> t , PUYA_FLASH_TIMING_CAL_BASE + hsi_fs * 20 + 16 );
227+ target_s * target = flash -> t ;
228+ uint32_t cal_base ;
229+
230+ switch (target -> part_id ) {
231+ case PUYA_DEV_ID_PY32F002A : {
232+ uint8_t hsi_fs =
233+ (target_mem32_read32 (flash -> t , PUYA_RCC_ICSCR ) >> PUYA_RCC_ICSCR_HSI_FS_SHIFT ) & PUYA_RCC_ICSCR_HSI_FS_MASK ;
234+ if (hsi_fs > 4 )
235+ hsi_fs = 0 ;
236+ DEBUG_TARGET ("HSI frequency selection is %d\n" , hsi_fs );
237+ cal_base = PUYA_FLASH_TIMING_CAL_PY32F002A_BASE + hsi_fs * 20 ;
238+ break ;
239+ }
240+ case PUYA_DEV_ID_PY32F002B :
241+ cal_base = PUYA_FLASH_TIMING_CAL_PY32F002B_BASE ;
242+ break ;
243+ default :
244+ /* Should have never made it past probe */
245+ DEBUG_TARGET ("Unknown PY32 device %08" PRIx32 "\n" , target -> part_id );
246+ return false;
247+ }
248+
249+ const uint32_t eppara0 = target_mem32_read32 (flash -> t , cal_base + 0 );
250+ const uint32_t eppara1 = target_mem32_read32 (flash -> t , cal_base + 4 );
251+ const uint32_t eppara2 = target_mem32_read32 (flash -> t , cal_base + 8 );
252+ const uint32_t eppara3 = target_mem32_read32 (flash -> t , cal_base + 12 );
253+ const uint32_t eppara4 = target_mem32_read32 (flash -> t , cal_base + 16 );
165254 DEBUG_TARGET ("PY32 flash timing cal 0: %08" PRIx32 "\n" , eppara0 );
166255 DEBUG_TARGET ("PY32 flash timing cal 1: %08" PRIx32 "\n" , eppara1 );
167256 DEBUG_TARGET ("PY32 flash timing cal 2: %08" PRIx32 "\n" , eppara2 );
168257 DEBUG_TARGET ("PY32 flash timing cal 3: %08" PRIx32 "\n" , eppara3 );
169258 DEBUG_TARGET ("PY32 flash timing cal 4: %08" PRIx32 "\n" , eppara4 );
170259
171- target_mem32_write32 (flash -> t , PUYA_FLASH_TS0 , eppara0 & 0xffU );
172- target_mem32_write32 (flash -> t , PUYA_FLASH_TS1 , (eppara0 >> 16U ) & 0x1ffU );
173- target_mem32_write32 (flash -> t , PUYA_FLASH_TS3 , (eppara0 >> 8U ) & 0xffU );
174- target_mem32_write32 (flash -> t , PUYA_FLASH_TS2P , eppara1 & 0xffU );
175- target_mem32_write32 (flash -> t , PUYA_FLASH_TPS3 , (eppara1 >> 16U ) & 0x7ffU );
176- target_mem32_write32 (flash -> t , PUYA_FLASH_PERTPE , eppara2 & 0x1ffffU );
177- target_mem32_write32 (flash -> t , PUYA_FLASH_SMERTPE , eppara3 & 0x1ffffU );
178- target_mem32_write32 (flash -> t , PUYA_FLASH_PRGTPE , eppara4 & 0xffffU );
179- target_mem32_write32 (flash -> t , PUYA_FLASH_PRETPE , (eppara4 >> 16U ) & 0x3fffU );
180-
260+ switch (target -> part_id ) {
261+ case PUYA_DEV_ID_PY32F002A :
262+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS0 ,
263+ (eppara0 >> PY32F002A_EPPARA0_TS0_SHIFT ) & PY32F002A_EPPARA0_TS0_MASK );
264+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS1 ,
265+ (eppara0 >> PY32F002A_EPPARA0_TS1_SHIFT ) & PY32F002A_EPPARA0_TS1_MASK );
266+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS3 ,
267+ (eppara0 >> PY32F002A_EPPARA0_TS3_SHIFT ) & PY32F002A_EPPARA0_TS3_MASK );
268+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS2P ,
269+ (eppara1 >> PY32F002A_EPPARA1_TS2P_SHIFT ) & PY32F002A_EPPARA1_TS2P_MASK );
270+ target_mem32_write32 (flash -> t , PUYA_FLASH_TPS3 ,
271+ (eppara1 >> PY32F002A_EPPARA1_TPS3_SHIFT ) & PY32F002A_EPPARA1_TPS3_MASK );
272+ target_mem32_write32 (flash -> t , PUYA_FLASH_PERTPE ,
273+ (eppara2 >> PY32F002A_EPPARA2_PERTPE_SHIFT ) & PY32F002A_EPPARA2_PERTPE_MASK );
274+ target_mem32_write32 (flash -> t , PUYA_FLASH_SMERTPE ,
275+ (eppara3 >> PY32F002A_EPPARA3_SMERTPE_SHIFT ) & PY32F002A_EPPARA3_SMERTPE_MASK );
276+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRGTPE ,
277+ (eppara4 >> PY32F002A_EPPARA4_PRGTPE_SHIFT ) & PY32F002A_EPPARA4_PRGTPE_MASK );
278+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRETPE ,
279+ (eppara4 >> PY32F002A_EPPARA4_PRETPE_SHIFT ) & PY32F002A_EPPARA4_PRETPE_MASK );
280+ break ;
281+ case PUYA_DEV_ID_PY32F002B :
282+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS0 ,
283+ (eppara0 >> PY32F002B_EPPARA0_TS0_SHIFT ) & PY32F002B_EPPARA0_TS0_MASK );
284+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS1 ,
285+ (eppara0 >> PY32F002B_EPPARA0_TS1_SHIFT ) & PY32F002B_EPPARA0_TS1_MASK );
286+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS3 ,
287+ (eppara0 >> PY32F002B_EPPARA0_TS3_SHIFT ) & PY32F002B_EPPARA0_TS3_MASK );
288+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS2P ,
289+ (eppara1 >> PY32F002B_EPPARA1_TS2P_SHIFT ) & PY32F002B_EPPARA1_TS2P_MASK );
290+ target_mem32_write32 (flash -> t , PUYA_FLASH_TPS3 ,
291+ (eppara1 >> PY32F002B_EPPARA1_TPS3_SHIFT ) & PY32F002B_EPPARA1_TPS3_MASK );
292+ target_mem32_write32 (flash -> t , PUYA_FLASH_PERTPE ,
293+ (eppara2 >> PY32F002B_EPPARA2_PERTPE_SHIFT ) & PY32F002B_EPPARA2_PERTPE_MASK );
294+ target_mem32_write32 (flash -> t , PUYA_FLASH_SMERTPE ,
295+ (eppara3 >> PY32F002B_EPPARA3_SMERTPE_SHIFT ) & PY32F002B_EPPARA3_SMERTPE_MASK );
296+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRGTPE ,
297+ (eppara4 >> PY32F002B_EPPARA4_PRGTPE_SHIFT ) & PY32F002B_EPPARA4_PRGTPE_MASK );
298+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRETPE ,
299+ (eppara4 >> PY32F002B_EPPARA4_PRETPE_SHIFT ) & PY32F002B_EPPARA4_PRETPE_MASK );
300+ break ;
301+ }
181302 return true;
182303}
183304
0 commit comments