smartpower 发表于 2020-12-31 19:23

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

本帖最后由 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_ttmp8;
    __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_ti;
    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

支持一下,这都可以。

Kelan 发表于 2021-1-3 11:06

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

smartpower 发表于 2021-1-3 11:36

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

linguanghua 发表于 2021-1-5 15:43

niu B,只能读吗?能进行写吗?能的话这个可以做个离线下载器了。

fcccc 发表于 2021-1-5 15:44

很棒的操作,但是请问有什么用途?

@lonely 发表于 2021-9-27 17:21

楼主 请问如何取消读保护/写读保护呢?

lwb807 发表于 2021-10-28 16:45

利害,可以试试玩脱机烧录

lovelessing 发表于 2021-11-4 17:30

bv31和bv2这两个变量是什么
页: [1]
查看完整版本: 最简单IO模拟SWD协议读写cortex m0+ 单片机寄存器源代码