SWD协议 源码 入门示例

通过IO模拟SWD协议,实现读写cortex M0+  的寄存器源码。

自己从0开始撸出来的,实测可用。

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

如需学习SWD协议,请移步SWD 协议入门指引及实际寄存器读写波形示例_smartpower的博客-CSDN博客_pc寄存器的swd波形

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

//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  @ 0x00100d90

        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  @ 0x40020F04

        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 );

}

  • 11
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值