这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界» 论坛首页» 嵌入式开发» MCU» 使用I/O模拟时序完成SWD接口ARM芯片的读写

共7条 1/1 1 跳转至

使用I/O模拟时序完成SWD接口ARM芯片的读写

工程师
2021-02-19 23:07:09 打赏

以下是使用IO模拟SWD协议,读写cortex M0+ 的寄存器源码,实测可用!

移植时,实现IO操作的几个宏就能工作了!


//==============================================================================

//SWDIO = PA1

#define SWDIO_SetHigh() ( M0P_GPIOA->BSRR = 1<<1 )

#define SWDIO_SetLow() ( M0P_GPIOA->BRR = 1<<1 )

#define SWDIO_SetInput() ( M0P_GPIOA->DIR_f.PIN1 = 1 )

#define SWDIO_SetOutput() ( M0P_GPIOA->DIR_f.PIN1 = 0 )

#define SWDIO_GetValue() ( M0P_GPIOA->IN & (1<<1) )

//SWCLK = PA2

#define SWCLK_SetHigh() ( M0P_GPIOA->BSRR = 1<<2 )

#define SWCLK_SetLow() ( M0P_GPIOA->BRR = 1<<2 )

#define SWCLK_SetOutput() ( M0P_GPIOA->DIR_f.PIN2 = 0 )

//==============================================================================

#define SwdDly() __nop();__nop();

//==============================================================================

int main(void)

{

__IO uint8_t tmp8;

__IO uint32_t tmp32;

M0P_SYSCTRL->PERICLKEN0 = 0xffffffff;

M0P_SYSCTRL->PERICLKEN1 = 0xffffffff;

M0P_GPIOA->ADS = 0x00;

Swd_Bus_Reset();

while( 1 )

{

// Swd_Bus_Reset();

//

// Swd_Bus_SendByte( 0x9E );

// Swd_Bus_SendByte( 0xE7 );

// Swd_Bus_SendByte( 0x00 );

// Swd_Bus_SendByte( 0x00 );

//

Swd_Bus_Reset();

Swd_Bus_SendByte( 0x00 );

//--------------------------------------------------

//Read DP.IDR

Swd_Bus_SendByte( 0xa5 );

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

tmp32 = Swd_Bus_RecvWordAndParity();

Swd_Bus_Turn();

Swd_Bus_SendByte( 0x00 );

//--------------------------------------------------

//write ctrl/state

Swd_Bus_SendByte( 0xa9 );

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

Swd_Bus_Turn();

Swd_Bus_SendWordAndParity( 0x50000000 );

Swd_Bus_SendByte( 0x00 );

//--------------------------------------------------

//Read AP.IDR

Swd_Bus_SendByte( 0xb1 ); //write select AP BANK - 0F

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

Swd_Bus_Turn();

Swd_Bus_SendWordAndParity( 0x000000f0 );

Swd_Bus_SendByte( 0x00 );

Swd_Bus_SendByte( 0x9f ); //read DRW dummy

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

tmp32 = Swd_Bus_RecvWordAndParity();

Swd_Bus_Turn();

Swd_Bus_SendByte( 0x00 );

Swd_Bus_SendByte( 0xbd ); //read rdbuf

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

tmp32 = Swd_Bus_RecvWordAndParity();

Swd_Bus_Turn();

Swd_Bus_SendByte( 0x00 );

//--------------------------------------------------

//SET AP 位宽为32位

Swd_Bus_SendByte( 0xb1 ); //write select AP BANK - 00

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

Swd_Bus_Turn();

Swd_Bus_SendWordAndParity( 0x00000000 );

Swd_Bus_SendByte( 0x00 );

Swd_Bus_SendByte( 0xA3 ); //write CSW -

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

Swd_Bus_Turn();

Swd_Bus_SendWordAndParity( 0x23000002 ); //32bit 位宽,地址不自动增加

Swd_Bus_SendByte( 0x00 );

//--------------------------------------------------

//stop the cpu

Swd_Bus_SendByte( 0x8B ); //write TAR

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

Swd_Bus_Turn();

Swd_Bus_SendWordAndParity( 0xE000EDF0 ); //

Swd_Bus_SendByte( 0x00 );

Swd_Bus_SendByte( 0xBB ); //WRITE DRW

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

Swd_Bus_Turn();

Swd_Bus_SendWordAndParity( 0xA05F0303 );

Swd_Bus_SendByte( 0x00 );

//--------------------------------------------------

//Read User Memery

Swd_Bus_SendByte( 0x8B ); //write TAR

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

Swd_Bus_Turn();

Swd_Bus_SendWordAndParity( 0x00100d90 );

Swd_Bus_SendByte( 0x00 );

Swd_Bus_SendByte( 0x9f ); //read DRW

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

tmp32 = Swd_Bus_RecvWordAndParity(); //dummy

Swd_Bus_Turn();

Swd_Bus_SendByte( 0x00 );

Swd_Bus_SendByte( 0xbd ); //read rdbuf

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

tmp32 = Swd_Bus_RecvWordAndParity(); //read

Swd_Bus_Turn();

Swd_Bus_SendByte( 0x00 );

//--------------------------------

//write and read reg

Swd_Bus_SendByte( 0x8B ); //write TAR

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

Swd_Bus_Turn();

Swd_Bus_SendWordAndParity( 0x40020F04 );

Swd_Bus_SendByte( 0x00 );

Swd_Bus_SendByte( 0xBB ); //WRITE DRW

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

Swd_Bus_Turn();

Swd_Bus_SendWordAndParity( 0xffffffff );

Swd_Bus_SendByte( 0x00 );

Swd_Bus_SendByte( 0x9f ); //read DRW dummy

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

tmp32 = Swd_Bus_RecvWordAndParity();

Swd_Bus_Turn();

Swd_Bus_SendByte( 0x00 );

Swd_Bus_SendByte( 0xbd ); //read rdbuf

Swd_Bus_Turn();

tmp8 = Swd_Bus_RecvAck();

tmp32 = Swd_Bus_RecvWordAndParity();

Swd_Bus_Turn();

Swd_Bus_SendByte( 0x00 );

while( 1 );

}

}

//==============================================================================

void Swd_Bus_Reset( void )

{

uint8_t i;

SWCLK_SetOutput();

SWDIO_SetOutput();

SWDIO_SetHigh();

SWCLK_SetLow();

for( i=0; i<56; i++ )

{

SWCLK_SetHigh();

SwdDly();

SWCLK_SetLow();

SwdDly();

}

}

void Swd_Bus_Turn( void )

{

SWDIO_SetInput();

SwdDly();

SWCLK_SetHigh();

SwdDly();

SWCLK_SetLow();

SwdDly();

}

//LSB FIRST

void Swd_Bus_SendByte( uint8_t Va )

{

uint8_t i;

SWDIO_SetLow();

SWDIO_SetOutput();

for( i=0; i<8; i++ )

{

if( Va & 0x01 )

{

SWDIO_SetHigh();

}

else

{

SWDIO_SetLow();

}

Va >>= 1;

SwdDly();

SWCLK_SetHigh();

SwdDly();

SWCLK_SetLow();

}

SwdDly();

}

//LSB FIRST

void Swd_Bus_SendWordAndParity( uint32_t Va )

{

uint8_t i;

uint8_t Pa = 0x00;

SWDIO_SetLow();

SWDIO_SetOutput();

for( i=0; i<32; i++ )

{

if( Va & 0x01 )

{

SWDIO_SetHigh();

Pa++;

}

else

{

SWDIO_SetLow();

}

Va >>= 1;

SwdDly();

SWCLK_SetHigh();

SwdDly();

SWCLK_SetLow();

}

//send Parity

if( Pa & 0x01 )

{

SWDIO_SetHigh();

}

else

{

SWDIO_SetLow();

}

SwdDly();

SWCLK_SetHigh();

SwdDly();

SWCLK_SetLow();

SwdDly();

}

//LSB FIRST

uint32_t Swd_Bus_RecvWordAndParity( void )

{

uint8_t i;

uint32_t tmp32;

tmp32 = 0x00;

SWDIO_SetInput();

SwdDly();

for( i=0; i<32; i++ )

{

if( SWDIO_GetValue() )

{

tmp32 >>= 1;

tmp32 |= bv31;

}

else

{

tmp32 >>= 1;

}

SWCLK_SetHigh();

SwdDly();

SWCLK_SetLow();

SwdDly();

}

//------------------------------

//Parity

SWCLK_SetHigh();

SwdDly();

SWCLK_SetLow();

SwdDly();

return( tmp32 );

}

//LSB FIRST

uint8_t Swd_Bus_RecvAck( void )

{

uint8_t i;

uint8_t tmp8;

tmp8 = 0x00;

SWDIO_SetInput();

SwdDly();

for( i=0; i<3; i++ )

{

if( SWDIO_GetValue() )

{

tmp8 >>= 1;

tmp8 |= bv2;

}

else

{

tmp8 >>= 1;

}

SWCLK_SetHigh();

SwdDly();

SWCLK_SetLow();

SwdDly();

}

return( tmp8 );

}





关键词: SWD 模拟时序

工程师
2021-02-19 23:26:33 打赏
2楼

这都可以。厉害!


工程师
2021-02-19 23:29:56 打赏
3楼

Good job!
请问楼主用的是啥芯片来运行这些代码? 另外,可以读其它内核的(如 m3)吗?


工程师
2021-02-19 23:34:11 打赏
4楼

很棒的参考源,thanks!


工程师
2021-02-19 23:41:11 打赏
5楼

讲解的非常不错的


工程师
2021-02-19 23:49:38 打赏
6楼

代码写的非常不错


高工
2021-02-22 09:07:35 打赏
7楼


共7条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]