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,32 @@ 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 );
119138 flash_size = (((flash_ram_sz >> PUYA_FLASH_SZ_SHIFT ) & PUYA_FLASH_SZ_MASK ) + 1 ) << PUYA_FLASH_UNIT_SHIFT ;
120139 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 {
140+ target -> driver = "PY32F002A" ;
141+ break ;
142+ }
143+ case PUYA_DEV_ID_PY32F002B :
144+ /*
145+ * 0x1fff0ffc contains 0; did not find any other location that looks like it might contain the flash
146+ * and RAM sizes. We'll hard-code the datasheet values for now. Both flash size and RAM size actually
147+ * match the datasheet value, unlike PY32F002A which (sometimes?) has more RAM and flash than
148+ * documented.
149+ */
150+ flash_size = 24 * 1024 ;
151+ ram_size = 3 * 1024 ;
152+ target -> driver = "PY32F002B" ;
153+ break ;
154+ default :
125155 DEBUG_TARGET ("Unknown PY32 device %08" PRIx32 "\n" , dbg_idcode );
126156 return false;
127157 }
128158
159+ target -> part_id = dev_id ;
129160 target_add_ram32 (target , PUYA_RAM_START , ram_size );
130161 target_flash_s * flash = calloc (1 , sizeof (* flash ));
131162 if (!flash ) { /* calloc failed: heap exhaustion */
@@ -151,33 +182,63 @@ static bool puya_flash_prepare(target_flash_s *flash)
151182 target_mem32_write32 (flash -> t , PUYA_FLASH_KEYR , PUYA_FLASH_KEYR_KEY1 );
152183 target_mem32_write32 (flash -> t , PUYA_FLASH_KEYR , PUYA_FLASH_KEYR_KEY2 );
153184
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 );
185+ target_s * target = flash -> t ;
186+ uint32_t cal_base ;
187+
188+ switch (target -> part_id ) {
189+ case PUYA_DEV_ID_PY32F002A : {
190+ uint8_t hsi_fs =
191+ (target_mem32_read32 (flash -> t , PUYA_RCC_ICSCR ) >> PUYA_RCC_ICSCR_HSI_FS_SHIFT ) & PUYA_RCC_ICSCR_HSI_FS_MASK ;
192+ if (hsi_fs > 4 )
193+ hsi_fs = 0 ;
194+ DEBUG_TARGET ("HSI frequency selection is %d\n" , hsi_fs );
195+ cal_base = PUYA_FLASH_TIMING_CAL_PY32F002A_BASE + hsi_fs * 20 ;
196+ break ;
197+ }
198+ case PUYA_DEV_ID_PY32F002B :
199+ cal_base = PUYA_FLASH_TIMING_CAL_PY32F002B_BASE ;
200+ break ;
201+ default :
202+ /* Should have never made it past probe */
203+ DEBUG_TARGET ("Unknown PY32 device %08" PRIx32 "\n" , target -> part_id );
204+ return false;
205+ }
206+
207+ const uint32_t eppara0 = target_mem32_read32 (flash -> t , cal_base + 0 );
208+ const uint32_t eppara1 = target_mem32_read32 (flash -> t , cal_base + 4 );
209+ const uint32_t eppara2 = target_mem32_read32 (flash -> t , cal_base + 8 );
210+ const uint32_t eppara3 = target_mem32_read32 (flash -> t , cal_base + 12 );
211+ const uint32_t eppara4 = target_mem32_read32 (flash -> t , cal_base + 16 );
165212 DEBUG_TARGET ("PY32 flash timing cal 0: %08" PRIx32 "\n" , eppara0 );
166213 DEBUG_TARGET ("PY32 flash timing cal 1: %08" PRIx32 "\n" , eppara1 );
167214 DEBUG_TARGET ("PY32 flash timing cal 2: %08" PRIx32 "\n" , eppara2 );
168215 DEBUG_TARGET ("PY32 flash timing cal 3: %08" PRIx32 "\n" , eppara3 );
169216 DEBUG_TARGET ("PY32 flash timing cal 4: %08" PRIx32 "\n" , eppara4 );
170217
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-
218+ switch (target -> part_id ) {
219+ case PUYA_DEV_ID_PY32F002A :
220+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS0 , eppara0 & 0xffU );
221+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS1 , (eppara0 >> 16U ) & 0x1ffU );
222+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS3 , (eppara0 >> 8U ) & 0xffU );
223+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS2P , eppara1 & 0xffU );
224+ target_mem32_write32 (flash -> t , PUYA_FLASH_TPS3 , (eppara1 >> 16U ) & 0x7ffU );
225+ target_mem32_write32 (flash -> t , PUYA_FLASH_PERTPE , eppara2 & 0x1ffffU );
226+ target_mem32_write32 (flash -> t , PUYA_FLASH_SMERTPE , eppara3 & 0x1ffffU );
227+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRGTPE , eppara4 & 0xffffU );
228+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRETPE , (eppara4 >> 16U ) & 0x3fffU );
229+ break ;
230+ case PUYA_DEV_ID_PY32F002B :
231+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS0 , eppara0 & 0x1ffU );
232+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS1 , (eppara0 >> 18U ) & 0x3ffU );
233+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS3 , (eppara0 >> 9U ) & 0x1ffU );
234+ target_mem32_write32 (flash -> t , PUYA_FLASH_TS2P , eppara1 & 0x1ffU );
235+ target_mem32_write32 (flash -> t , PUYA_FLASH_TPS3 , (eppara1 >> 16U ) & 0xfffU );
236+ target_mem32_write32 (flash -> t , PUYA_FLASH_PERTPE , eppara2 & 0x3ffffU );
237+ target_mem32_write32 (flash -> t , PUYA_FLASH_SMERTPE , eppara3 & 0x3ffffU );
238+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRGTPE , eppara4 & 0xffffU );
239+ target_mem32_write32 (flash -> t , PUYA_FLASH_PRETPE , (eppara4 >> 16U ) & 0x3fffU );
240+ break ;
241+ }
181242 return true;
182243}
183244
0 commit comments