在线时间603 小时
UID23776
注册时间2015-5-27
NXP金币0
TA的每日心情 | 衰 2021-4-20 18:38 |
---|
签到天数: 341 天 连续签到: 1 天 [LV.8]以坛为家I
金牌会员
 
- 积分
- 2370
- 最后登录
- 2022-4-29
|
本帖最后由 boboo-23776 于 2017-3-8 16:07 编辑
学习SWD协议中,刚入门,用的FRDM-KE02板子,读写寄存器等已正常,写出来与大家交流
SWD其实就2根线的协议,SWDCLK控制时钟,SWDIO控制数据,通过对寄存器的读写来完成于MCU的通信
首先,需要进入SWD模式。发至少50个1 和一个0xE79E 强制切换到SWD模式即可。
J-link切换时通常还会发一个0x6DB7,据说是兼容老版本ARM的强制切换
uint8_t SWJ_JTAG2SWD(void)
{
uint32_t i;
SWDIO_SET();
for(i = 0; i < 56; i++)
{
SW_CLOCK_CYCLE();
}
SWJ_SendData(0xE79E);//SWJ_SendData(0xB76D);以后遇到再加
for(i = 0; i < 56; i++)
{
SW_CLOCK_CYCLE();
}
SWDIO_CLR();
for(i = 0; i < 16; i++)
{
SW_CLOCK_CYCLE();
}
return 0;
}
然后就是读写DP/AP寄存器
-Start 起始位,始终为1
-APnDP 选择访问DP寄存器还是AP寄存器。
- Rnw 选择读还是写。
-A[2:3] DP或者AP寄存器的地址,低位在前。
-Praity 校验位,APnDP、RnW和A[2:3]共4个bit的校验位。
-Stop 停止位。始终为0
-Park 始终为1
DP寄存器
Address Read Write
0x00 IDCODE ABORT
0x04 CTRL/STAT CTRL/STAT
0x08 RESEND SELECT
0x0C RDBUFF N/A
Address Read Write
0x00 CSW CSW
0x04 TAR TAR
0x08 N/A N/A
0x0C DRW DRW
0xFC IDR N/A
读IDCODE正常图
uint8_t SWJ_ReadDP(uint8_t adr, uint32_t *val)
{
uint32_t tmp_in;
uint8_t ack;
uint8_t err;
tmp_in = SWD_REG_DP | SWD_REG_R | SWD_REG_ADR(adr);
ack = SWD_Transfer(tmp_in, val);
(ack == DAP_TRANSFER_OK) ? (err = 0) : (err = 1);
return err;
}
uint8_t SWJ_ReadAP(uint32_t adr, uint32_t *val)
{
uint8_t tmp_in, ack, err;
uint32_t apsel = adr & APSEL;
uint32_t bank_sel = adr & APBANKSEL;
if(SWJ_WriteDP(DP_SELECT, apsel | bank_sel))
{
return 1;
}
tmp_in = SWD_REG_AP | SWD_REG_R | SWD_REG_ADR(adr);
/* first dummy read */
ack = SWD_Transfer(tmp_in, val);
ack = SWD_Transfer(tmp_in, val);
(ack == DAP_TRANSFER_OK) ? (err = 0) : (err = 1);
return err;
}
然后就可以对目标读写了
uint8_t SWJ_WriteMem32(uint32_t addr, uint32_t val)
{
uint8_t err;
SWJ_WriteAP(AP_CSW, CSW_VALUE | CSW_SIZE32);
err = SWJ_WriteData(addr, val);
return err;
}
static uint8_t SWJ_ReadMem32(uint32_t addr, uint32_t *val)
{
uint8_t err;
SWJ_WriteAP(AP_CSW, CSW_VALUE | CSW_SIZE32);
err = SWJ_ReadData(addr, val);
return err;
}
SWD.rar
(9.24 KB, 下载次数: 1275)
|
|