4545/* Pile of timing parameters needed to make sure flash works,
4646 * see section "4.4. 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 PUYA_FLASH_TIMING_CAL_PY32F002B_BASE 0x1fff011cU
4950/* This config word is undocumented, but the Puya-ISP boot code
5051 * uses it to determine the valid flash/ram size.
5152 * (yes, this *does* include undocumented free extra flash/ram in the 002A)
99100/* DBG */
100101#define PUYA_DBG_BASE 0x40015800U
101102#define PUYA_DBG_IDCODE (PUYA_DBG_BASE + 0x00U)
103+ /*
104+ * The format and values of the IDCODE register are undocumented but the vendor SDK splits IDCODE into 11:0 DEV_ID and
105+ * 31:16 REV_ID.
106+ */
107+ #define PUYA_DBG_IDCODE_DEV_ID_SHIFT 0U
108+ #define PUYA_DBG_IDCODE_DEV_ID_MASK 0xfffU
109+ #define PUYA_DBG_IDCODE_REV_ID_SHIFT 16U
110+ #define PUYA_DBG_IDCODE_REV_ID_MASK 0xffffU
111+
112+ /* On PY32F002AW15U an IDCODE value of 0x60001000 was observed */
113+ #define PUYA_DEV_ID_PY32F002A 0x000
114+ /*
115+ * On PY32F002BF15P an IDCODE value of 0x20220064 was observed. Internet search shows the same value is used on
116+ * PY32F002BW15.
117+ */
118+ #define PUYA_DEV_ID_PY32F002B 0x064
102119
103120/*
104121 * Flash functions
@@ -114,18 +131,33 @@ bool puya_probe(target_s *target)
114131 size_t flash_size = 0U ;
115132
116133 const uint32_t dbg_idcode = target_mem32_read32 (target , PUYA_DBG_IDCODE );
117- if ((dbg_idcode & 0xfffU ) == 0 ) {
134+ const uint16_t dev_id = (dbg_idcode >> PUYA_DBG_IDCODE_DEV_ID_SHIFT ) & PUYA_DBG_IDCODE_DEV_ID_MASK ;
135+ switch (dev_id ) {
136+ case PUYA_DEV_ID_PY32F002A : {
118137 const uint32_t flash_ram_sz = target_mem32_read32 (target , PUYA_FLASH_RAM_SZ );
119- flash_size = (((flash_ram_sz >> PUYA_FLASH_SZ_SHIFT ) & PUYA_FLASH_SZ_MASK ) + 1 ) << PUYA_FLASH_UNIT_SHIFT ;
138+ flash_size = (((flash_ram_sz >> PUYA_FLASH_SZ_SHIFT ) & PUYA_FLASH_SZ_MASK ) + 1 )
139+ << PUYA_FLASH_UNIT_SHIFT ;
120140 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 {
141+ target -> driver = "PY32F002A" ;
142+ break ;
143+ }
144+ case PUYA_DEV_ID_PY32F002B :
145+ /*
146+ * 0x1fff0ffc contains 0; did not find any other location that looks like it might contain the flash
147+ * and RAM sizes. We'll hard-code the datasheet values for now. Both flash size and RAM size actually
148+ * match the datasheet value, unlike PY32F002A which (sometimes?) has more RAM and flash than
149+ * documented.
150+ */
151+ flash_size = 24 * 1024 ;
152+ ram_size = 3 * 1024 ;
153+ target -> driver = "PY32F002B" ;
154+ break ;
155+ default :
125156 DEBUG_TARGET ("Unknown PY32 device %08" PRIx32 "\n" , dbg_idcode );
126157 return false;
127158 }
128159
160+ target -> part_id = dev_id ;
129161 target_add_ram32 (target , PUYA_RAM_START , ram_size );
130162 target_flash_s * flash = calloc (1 , sizeof (* flash ));
131163 if (!flash ) { /* calloc failed: heap exhaustion */
@@ -151,33 +183,64 @@ static bool puya_flash_prepare(target_flash_s *flash)
151183 target_mem32_write32 (flash -> t , PUYA_FLASH_KEYR , PUYA_FLASH_KEYR_KEY1 );
152184 target_mem32_write32 (flash -> t , PUYA_FLASH_KEYR , PUYA_FLASH_KEYR_KEY2 );
153185
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 );
186+ target_s * target = flash -> t ;
187+ uint32_t cal_base ;
188+
189+ switch (target -> part_id ) {
190+ case PUYA_DEV_ID_PY32F002A : {
191+ uint8_t hsi_fs =
192+ (target_mem32_read32 (flash -> t , PUYA_RCC_ICSCR ) >> PUYA_RCC_ICSCR_HSI_FS_SHIFT )
193+ & PUYA_RCC_ICSCR_HSI_FS_MASK ;
194+ if (hsi_fs > 4 )
195+ hsi_fs = 0 ;
196+ DEBUG_TARGET ("HSI frequency selection is %d\n" , hsi_fs );
197+ cal_base = PUYA_FLASH_TIMING_CAL_PY32F002A_BASE + hsi_fs * 20 ;
198+ break ;
199+ }
200+ case PUYA_DEV_ID_PY32F002B :
201+ cal_base = PUYA_FLASH_TIMING_CAL_PY32F002B_BASE ;
202+ break ;
203+ default :
204+ /* Should have never made it past probe */
205+ DEBUG_TARGET ("Unknown PY32 device %08" PRIx32 "\n" , target -> part_id );
206+ return false;
207+ }
208+
209+ const uint32_t eppara0 = target_mem32_read32 (flash -> t , cal_base + 0 );
210+ const uint32_t eppara1 = target_mem32_read32 (flash -> t , cal_base + 4 );
211+ const uint32_t eppara2 = target_mem32_read32 (flash -> t , cal_base + 8 );
212+ const uint32_t eppara3 = target_mem32_read32 (flash -> t , cal_base + 12 );
213+ const uint32_t eppara4 = target_mem32_read32 (flash -> t , cal_base + 16 );
165214 DEBUG_TARGET ("PY32 flash timing cal 0: %08" PRIx32 "\n" , eppara0 );
166215 DEBUG_TARGET ("PY32 flash timing cal 1: %08" PRIx32 "\n" , eppara1 );
167216 DEBUG_TARGET ("PY32 flash timing cal 2: %08" PRIx32 "\n" , eppara2 );
168217 DEBUG_TARGET ("PY32 flash timing cal 3: %08" PRIx32 "\n" , eppara3 );
169218 DEBUG_TARGET ("PY32 flash timing cal 4: %08" PRIx32 "\n" , eppara4 );
170219
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-
220+ switch (target -> part_id ) {
221+ case PUYA_DEV_ID_PY32F002A :
222+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS0 , eppara0 & 0xffU );
223+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS1 , (eppara0 >> 16U ) & 0x1ffU );
224+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS3 , (eppara0 >> 8U ) & 0xffU );
225+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS2P , eppara1 & 0xffU );
226+ target_mem32_write32 (flash -> t , PUYA_FLASH_TPS3 , (eppara1 >> 16U ) & 0x7ffU );
227+ target_mem32_write32 (flash -> t , PUYA_FLASH_PERTPE , eppara2 & 0x1ffffU );
228+ target_mem32_write32 (flash -> t , PUYA_FLASH_SMERTPE , eppara3 & 0x1ffffU );
229+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRGTPE , eppara4 & 0xffffU );
230+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRETPE , (eppara4 >> 16U ) & 0x3fffU );
231+ break ;
232+ case PUYA_DEV_ID_PY32F002B :
233+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS0 , eppara0 & 0x1ffU );
234+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS1 , (eppara0 >> 18U ) & 0x3ffU );
235+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS3 , (eppara0 >> 9U ) & 0x1ffU );
236+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS2P , eppara1 & 0x1ffU );
237+ target_mem32_write32 (flash -> t , PUYA_FLASH_TPS3 , (eppara1 >> 16U ) & 0xfffU );
238+ target_mem32_write32 (flash -> t , PUYA_FLASH_PERTPE , eppara2 & 0x3ffffU );
239+ target_mem32_write32 (flash -> t , PUYA_FLASH_SMERTPE , eppara3 & 0x3ffffU );
240+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRGTPE , eppara4 & 0xffffU );
241+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRETPE , (eppara4 >> 16U ) & 0x3fffU );
242+ break ;
243+ }
181244 return true;
182245}
183246
0 commit comments