commit de60c86b2ae817590c82b62847e3f23054794eb2
parent fc068d707ecc405ed27cc3d5044b270ec43147e3
Author: Brian Swetland <swetland@frotz.net>
Date: Fri, 3 Mar 2023 16:28:04 -0800
speed up block memory transfers
With the clock set at 4MHz (measures at ~3.3MHz on the scope)
on an LPC MCU-LINK with 512byte packets, we see about 74KB/s
for the simple bulk reads. Using auto increment in the CSW
and removing almost all MAP.TAR writes, we get up to 202KB/s.
It may be possible to get somewhat better efficiency by using
DAP_TransferBlock instead of DAP_Transfer, but I suspect that's
not going to have much impact on high speed USB devices like
this one. On full speed devices, could be significant.
Diffstat:
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/src/transport-arm-debug.c b/src/transport-arm-debug.c
@@ -55,6 +55,7 @@ int dc_mem_wr32(DC* dc, uint32_t addr, uint32_t val) {
+#if 0
int dc_mem_rd_words(dctx_t* dc, uint32_t addr, uint32_t num, uint32_t* ptr) {
while (num > 0) {
dc_q_mem_rd32(dc, addr, ptr);
@@ -74,6 +75,55 @@ int dc_mem_wr_words(dctx_t* dc, uint32_t addr, uint32_t num, const uint32_t* ptr
}
return dc_q_exec(dc);
}
+#else
+// some implementations support >10 bits, but 10 is the minimum required
+// by spec (and some targets like rp2040 are limited to this)
+#define WRAPSIZE 0x400
+#define WRAPMASK (WRAPSIZE - 1)
+int dc_mem_rd_words(dctx_t* dc, uint32_t addr, uint32_t num, uint32_t* ptr) {
+ while (num > 0) {
+ uint32_t xfer = (WRAPSIZE - (addr & WRAPMASK)) / 4;
+ if (xfer > num) {
+ xfer = num;
+ }
+ dc_q_init(dc);
+ dc_q_map_csw_wr(dc, MAP_CSW_SZ_32 | MAP_CSW_INC_SINGLE | MAP_CSW_DEVICE_EN);
+ dc_q_map_tar_wr(dc, addr);
+ num -= xfer;
+ addr += xfer * 4;
+ while (xfer > 0) {
+ dc_q_ap_rd(dc, MAP_DRW, ptr++);
+ xfer--;
+ }
+ int r = dc_q_exec(dc);
+ if (r != DC_OK) {
+ return r;
+ }
+ }
+ return DC_OK;
+}
-
+int dc_mem_wr_words(dctx_t* dc, uint32_t addr, uint32_t num, const uint32_t* ptr) {
+ while (num > 0) {
+ uint32_t xfer = (WRAPSIZE - (addr & WRAPMASK)) / 4;
+ if (xfer > num) {
+ xfer = num;
+ }
+ dc_q_init(dc);
+ dc_q_map_csw_wr(dc, MAP_CSW_SZ_32 | MAP_CSW_INC_SINGLE | MAP_CSW_DEVICE_EN);
+ dc_q_map_tar_wr(dc, addr);
+ num -= xfer;
+ addr += xfer * 4;
+ while (xfer > 0) {
+ dc_q_ap_wr(dc, MAP_DRW, *ptr++);
+ xfer--;
+ }
+ int r = dc_q_exec(dc);
+ if (r != DC_OK) {
+ return r;
+ }
+ }
+ return DC_OK;
+}
+#endif