对于 stm32 这种 jtag 发送特殊序列激活 swd 的, 建议在 jtag
下控制 tms 发送特殊序列, ch347的序列模式只支持一次 8 个 1 或者 8 个 0, 通常 56 个 1 个 8 个 0 进入 swd 的 idle 模式
对于 stm32 这种 jtag 发送特殊序列激活 swd 的, 建议在 jtag
下控制 tms 发送特殊序列, ch347的序列模式只支持一次 8 个 1 或者 8 个 0, 通常 56 个 1 个 8 个 0 进入 swd 的 idle 模式
命令头为 0xE5
和 0xE8
Command::Ch347SwdInit => 0xE5,
Command::Ch347Swd => 0xE8,
Command::Ch347SwdRegW => 0xA0,
Command::Ch347SwdSeqW => 0xA1,
Command::Ch347SwdRegR => 0xA2,
初始化 Swd
, 速率的索引和 Jtag
一致, 最大是 60MHz
uint8_t cmdBuf[128] = "";
unsigned long i = 0;
cmdBuf[i++] = CH347_CMD_SWD_INIT;
cmdBuf[i++] = 8; /* Data length is 6 */
cmdBuf[i++] = 0;
cmdBuf[i++] = 0x40;
cmdBuf[i++] = 0x42;
cmdBuf[i++] = 0x0f; /* Reserved Bytes */
cmdBuf[i++] = 0x00; /* Reserved Bytes */
cmdBuf[i++] = iClockRate; /* JTAG clock speed */
i += 3; /* Reserved Bytes */
控制序列如下 0xE8, low, high, regw....., seqw...., regr....
, 开始为对应的操作,后面接子命令,需要管理各个子命令的接收数据。
接收 0xA0, ACK
发送控制序列, 写寄存器序列
ch347_swd_context.send_buf[ch347_swd_context.send_len++] =
CH347_CMD_SWD_REG_W;
/* 8bit + 32bit +1bit */
ch347_swd_context.send_buf[ch347_swd_context.send_len++] = 0x29; // 可能是 Host(8bit) + Data(32bit) + Parity(1bit))
ch347_swd_context.send_buf[ch347_swd_context.send_len++] = 0x00;
ch347_swd_context.send_buf[ch347_swd_context.send_len++] = cmd; // 就是头 0b10xx_x0x1, x代表需要设置的位
ch347_swd_context.send_buf[ch347_swd_context.send_len++] = out[0];
ch347_swd_context.send_buf[ch347_swd_context.send_len++] = out[1];
ch347_swd_context.send_buf[ch347_swd_context.send_len++] = out[2];
ch347_swd_context.send_buf[ch347_swd_context.send_len++] = out[3];
ch347_swd_context.send_buf[ch347_swd_context.send_len++] = parity; // 奇偶校验
// 还需要记录读取的字节数目,后面flush中读取的时候会处理
/* 0xA0 + 1 byte(3bit ACK) */
ch347_swd_context.need_recv_len += (1 + 1);
写序列
基本上用于 reset
或者 jtag 2 swd
接收仅仅返回 0xA1
Byte 0: 0xA1 (CH347_CMD_SWD_SEQ_W)
Byte 1-2: Length (序列长度 out_len, 小端序)
Byte 3-N: Sequence Data (序列数据, 按字节存储, 长度为 DIV_ROUND_UP(out_len, 8))