这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 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 跳转至

回复

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