OpenVINOTM,给你看得见的未来!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 可通过IO模拟SWD协议读取cortexm0+的源码

共4条 1/1 1 跳转至

可通过IO模拟SWD协议读取cortexm0+的源码

工程师
2021-01-03 21:09:56    评分


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

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

移植时,实现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  [url=home.php?mod=space&uid=72445]@[/url] 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  [url=home.php?mod=space&uid=72445]@[/url] 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 );

}





关键词: 源码     SWD     下载协议     仿真接口    

工程师
2021-01-03 21:15:59    评分
2楼

Good job!


( M0P_GPIOA->DIR_f.PIN1 = 1 )

这个位定义比较少见,请问楼主用的是啥芯片来运行这些代码? 


助工
2021-01-03 21:19:19    评分
3楼

该源码可以读其它内核的(如 m3)吗?


工程师
2021-01-03 21:25:43    评分
4楼

如果要读M3的,在总线复位后多发送几个字节,就是MAIN里被注释的部分


共4条 1/1 1 跳转至

回复

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