打印
[程序源码]

最简单IO模拟SWD协议读写cortex m0+ 单片机寄存器源代码

[复制链接]
6280|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
smartpower|  楼主 | 2020-12-31 19:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 smartpower 于 2021-1-6 08:58 编辑
过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
        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 );
}

使用特权

评论回复
评论
xyz549040622 2021-1-2 21:58 回复TA
太牛X了赞一个。 

相关帖子

沙发
xyz549040622| | 2021-1-2 21:58 | 只看该作者
支持一下,这都可以。

使用特权

评论回复
板凳
Kelan| | 2021-1-3 11:06 | 只看该作者
Good job!
请问楼主用的是啥芯片来运行这些代码? 另外,可以读其它内核的(如 m3)吗?

使用特权

评论回复
地板
smartpower|  楼主 | 2021-1-3 11:36 | 只看该作者
M3的,在总线复位后多发送几个字节,就是MAIN里被注释的部分。

使用特权

评论回复
5
linguanghua| | 2021-1-5 15:43 | 只看该作者
niu B,只能读吗?能进行写吗?能的话这个可以做个离线下载器了。

使用特权

评论回复
评论
smartpower 2021-1-6 08:59 回复TA
第122行到146行,是对寄存器的读写示例。 
6
fcccc| | 2021-1-5 15:44 | 只看该作者
很棒的操作,但是请问有什么用途?

使用特权

评论回复
评论
smartpower 2021-1-6 09:00 回复TA
5楼已说明了其典型用途。 
7
@lonely| | 2021-9-27 17:21 | 只看该作者
楼主 请问如何取消读保护/写读保护呢?

使用特权

评论回复
8
lwb807| | 2021-10-28 16:45 | 只看该作者
利害,可以试试玩脱机烧录

使用特权

评论回复
9
lovelessing| | 2021-11-4 17:30 | 只看该作者
bv31和bv2这两个变量是什么

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

442

帖子

11

粉丝