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

[复制链接]
6875|11
 楼主| smartpower 发表于 2020-12-31 19:23 | 显示全部楼层 |阅读模式
本帖最后由 smartpower 于 2021-1-6 08:58 编辑
  1. 过IO模拟SWD协议,读写cortex M0+  的寄存器源码。
  2. 自己从0开始撸出来的,实测可用。
  3. 移植时,实现IO操作的几个宏就能工作了。
  4. //==============================================================================
  5. //SWDIO = PA1
  6. #define SWDIO_SetHigh()     ( M0P_GPIOA->BSRR = 1<<1 )
  7. #define SWDIO_SetLow()      ( M0P_GPIOA->BRR = 1<<1 )
  8. #define SWDIO_SetInput()    ( M0P_GPIOA->DIR_f.PIN1 = 1 )
  9. #define SWDIO_SetOutput()   ( M0P_GPIOA->DIR_f.PIN1 = 0 )
  10. #define SWDIO_GetValue()    ( M0P_GPIOA->IN & (1<<1) )
  11. //SWCLK = PA2
  12. #define SWCLK_SetHigh()     ( M0P_GPIOA->BSRR = 1<<2 )
  13. #define SWCLK_SetLow()      ( M0P_GPIOA->BRR = 1<<2 )
  14. #define SWCLK_SetOutput()   ( M0P_GPIOA->DIR_f.PIN2 = 0 )
  15. //==============================================================================
  16. #define SwdDly()    __nop();__nop();
  17. //==============================================================================
  18. int main(void)
  19. {
  20.     __IO uint8_t  tmp8;
  21.     __IO uint32_t tmp32;
  22.     M0P_SYSCTRL->PERICLKEN0 = 0xffffffff;
  23.     M0P_SYSCTRL->PERICLKEN1 = 0xffffffff;
  24.     M0P_GPIOA->ADS = 0x00;
  25.     Swd_Bus_Reset();
  26.     while( 1 )
  27.     {
  28. //        Swd_Bus_Reset();
  29. //
  30. //        Swd_Bus_SendByte( 0x9E );
  31. //        Swd_Bus_SendByte( 0xE7 );
  32. //        Swd_Bus_SendByte( 0x00 );
  33. //        Swd_Bus_SendByte( 0x00 );
  34. //
  35.         Swd_Bus_Reset();
  36.         Swd_Bus_SendByte( 0x00 );
  37.         //--------------------------------------------------
  38.         //Read DP.IDR
  39.         Swd_Bus_SendByte( 0xa5 );
  40.         Swd_Bus_Turn();
  41.         tmp8 = Swd_Bus_RecvAck();
  42.         tmp32 = Swd_Bus_RecvWordAndParity();
  43.         Swd_Bus_Turn();
  44.         Swd_Bus_SendByte( 0x00 );
  45.         //--------------------------------------------------
  46.         //write ctrl/state
  47.         Swd_Bus_SendByte( 0xa9 );
  48.         Swd_Bus_Turn();
  49.         tmp8 = Swd_Bus_RecvAck();
  50.         Swd_Bus_Turn();
  51.         Swd_Bus_SendWordAndParity( 0x50000000 );
  52.         Swd_Bus_SendByte( 0x00 );
  53.         //--------------------------------------------------
  54.         //Read AP.IDR
  55.         Swd_Bus_SendByte( 0xb1 );  //write select AP BANK - 0F
  56.         Swd_Bus_Turn();
  57.         tmp8 = Swd_Bus_RecvAck();
  58.         Swd_Bus_Turn();
  59.         Swd_Bus_SendWordAndParity( 0x000000f0 );
  60.         Swd_Bus_SendByte( 0x00 );
  61.         Swd_Bus_SendByte( 0x9f );  //read DRW dummy
  62.         Swd_Bus_Turn();
  63.         tmp8  = Swd_Bus_RecvAck();
  64.         tmp32 = Swd_Bus_RecvWordAndParity();
  65.         Swd_Bus_Turn();
  66.         Swd_Bus_SendByte( 0x00 );
  67.         Swd_Bus_SendByte( 0xbd );  //read rdbuf
  68.         Swd_Bus_Turn();
  69.         tmp8  = Swd_Bus_RecvAck();
  70.         tmp32 = Swd_Bus_RecvWordAndParity();
  71.         Swd_Bus_Turn();
  72.         Swd_Bus_SendByte( 0x00 );
  73.         //--------------------------------------------------
  74.         //SET AP 位宽为32位
  75.         Swd_Bus_SendByte( 0xb1 );   //write select AP BANK - 00
  76.         Swd_Bus_Turn();
  77.         tmp8 = Swd_Bus_RecvAck();
  78.         Swd_Bus_Turn();
  79.         Swd_Bus_SendWordAndParity( 0x00000000 );
  80.         Swd_Bus_SendByte( 0x00 );
  81.         Swd_Bus_SendByte( 0xA3 );  //write CSW -
  82.         Swd_Bus_Turn();
  83.         tmp8 = Swd_Bus_RecvAck();
  84.         Swd_Bus_Turn();
  85.         Swd_Bus_SendWordAndParity( 0x23000002 );  //32bit 位宽,地址不自动增加
  86.         Swd_Bus_SendByte( 0x00 );
  87.         //--------------------------------------------------
  88.         //stop the cpu
  89.         Swd_Bus_SendByte( 0x8B );  //write TAR
  90.         Swd_Bus_Turn();
  91.         tmp8 = Swd_Bus_RecvAck();
  92.         Swd_Bus_Turn();
  93.         Swd_Bus_SendWordAndParity( 0xE000EDF0 );  //
  94.         Swd_Bus_SendByte( 0x00 );
  95.         Swd_Bus_SendByte( 0xBB );  //WRITE DRW
  96.         Swd_Bus_Turn();
  97.         tmp8 = Swd_Bus_RecvAck();
  98.         Swd_Bus_Turn();
  99.         Swd_Bus_SendWordAndParity( 0xA05F0303 );
  100.         Swd_Bus_SendByte( 0x00 );
  101.         //--------------------------------------------------
  102.         //Read User Memery
  103.         Swd_Bus_SendByte( 0x8B );  //write TAR
  104.         Swd_Bus_Turn();
  105.         tmp8 = Swd_Bus_RecvAck();
  106.         Swd_Bus_Turn();
  107.         Swd_Bus_SendWordAndParity( 0x00100d90 );
  108.         Swd_Bus_SendByte( 0x00 );
  109.         Swd_Bus_SendByte( 0x9f );  //read DRW
  110.         Swd_Bus_Turn();
  111.         tmp8  = Swd_Bus_RecvAck();
  112.         tmp32 = Swd_Bus_RecvWordAndParity();   //dummy
  113.         Swd_Bus_Turn();
  114.         Swd_Bus_SendByte( 0x00 );
  115.         Swd_Bus_SendByte( 0xbd );  //read rdbuf
  116.         Swd_Bus_Turn();
  117.         tmp8  = Swd_Bus_RecvAck();
  118.         tmp32 = Swd_Bus_RecvWordAndParity();   //read
  119.         Swd_Bus_Turn();
  120.         Swd_Bus_SendByte( 0x00 );
  121.         //--------------------------------
  122.        //write and read reg
  123.         Swd_Bus_SendByte( 0x8B );   //write TAR
  124.         Swd_Bus_Turn();
  125.         tmp8 = Swd_Bus_RecvAck();
  126.         Swd_Bus_Turn();
  127.         Swd_Bus_SendWordAndParity( 0x40020F04 );
  128.         Swd_Bus_SendByte( 0x00 );
  129.         Swd_Bus_SendByte( 0xBB );  //WRITE DRW
  130.         Swd_Bus_Turn();
  131.         tmp8 = Swd_Bus_RecvAck();
  132.         Swd_Bus_Turn();
  133.         Swd_Bus_SendWordAndParity( 0xffffffff );
  134.         Swd_Bus_SendByte( 0x00 );
  135.         Swd_Bus_SendByte( 0x9f );  //read DRW dummy
  136.         Swd_Bus_Turn();
  137.         tmp8  = Swd_Bus_RecvAck();
  138.         tmp32 = Swd_Bus_RecvWordAndParity();
  139.         Swd_Bus_Turn();
  140.         Swd_Bus_SendByte( 0x00 );
  141.         Swd_Bus_SendByte( 0xbd );    //read rdbuf
  142.         Swd_Bus_Turn();
  143.         tmp8  = Swd_Bus_RecvAck();
  144.         tmp32 = Swd_Bus_RecvWordAndParity();
  145.         Swd_Bus_Turn();
  146.         Swd_Bus_SendByte( 0x00 );
  147.         while( 1 );
  148.     }
  149. }
  150. //==============================================================================
  151. void Swd_Bus_Reset( void )
  152. {
  153.     uint8_t i;
  154.     SWCLK_SetOutput();
  155.     SWDIO_SetOutput();
  156.     SWDIO_SetHigh();
  157.     SWCLK_SetLow();
  158.     for( i=0; i<56; i++ )
  159.     {
  160.         SWCLK_SetHigh();
  161.         SwdDly();
  162.         SWCLK_SetLow();
  163.         SwdDly();
  164.     }
  165. }
  166. void Swd_Bus_Turn( void )
  167. {
  168.     SWDIO_SetInput();
  169.     SwdDly();
  170.     SWCLK_SetHigh();
  171.     SwdDly();
  172.     SWCLK_SetLow();
  173.     SwdDly();
  174. }
  175. //LSB FIRST
  176. void Swd_Bus_SendByte( uint8_t Va )
  177. {
  178.     uint8_t i;
  179.     SWDIO_SetLow();
  180.     SWDIO_SetOutput();
  181.     for( i=0; i<8; i++ )
  182.     {
  183.         if( Va & 0x01 )
  184.         {
  185.             SWDIO_SetHigh();
  186.         }
  187.         else
  188.         {
  189.             SWDIO_SetLow();
  190.         }
  191.         Va >>= 1;
  192.         SwdDly();
  193.         SWCLK_SetHigh();
  194.         SwdDly();
  195.         SWCLK_SetLow();
  196.     }
  197.     SwdDly();
  198. }
  199. //LSB FIRST
  200. void Swd_Bus_SendWordAndParity( uint32_t Va )
  201. {
  202.     uint8_t i;
  203.     uint8_t Pa = 0x00;
  204.     SWDIO_SetLow();
  205.     SWDIO_SetOutput();
  206.     for( i=0; i<32; i++ )
  207.     {
  208.         if( Va & 0x01 )
  209.         {
  210.             SWDIO_SetHigh();
  211.             Pa++;
  212.         }
  213.         else
  214.         {
  215.             SWDIO_SetLow();
  216.         }
  217.         Va >>= 1;
  218.         SwdDly();
  219.         SWCLK_SetHigh();
  220.         SwdDly();
  221.         SWCLK_SetLow();
  222.     }
  223.     //send Parity
  224.     if( Pa & 0x01 )
  225.     {
  226.         SWDIO_SetHigh();
  227.     }
  228.     else
  229.     {
  230.         SWDIO_SetLow();
  231.     }
  232.     SwdDly();
  233.     SWCLK_SetHigh();
  234.     SwdDly();
  235.     SWCLK_SetLow();
  236.     SwdDly();
  237. }
  238. //LSB FIRST
  239. uint32_t Swd_Bus_RecvWordAndParity( void )
  240. {
  241.     uint8_t  i;
  242.     uint32_t tmp32;
  243.     tmp32 = 0x00;
  244.     SWDIO_SetInput();
  245.     SwdDly();
  246.     for( i=0; i<32; i++ )
  247.     {
  248.         if( SWDIO_GetValue() )
  249.         {
  250.             tmp32 >>= 1;
  251.             tmp32 |= bv31;
  252.         }
  253.         else
  254.         {
  255.             tmp32 >>= 1;
  256.         }
  257.         SWCLK_SetHigh();
  258.         SwdDly();
  259.         SWCLK_SetLow();
  260.         SwdDly();
  261.     }
  262.     //------------------------------
  263.     //Parity
  264.     SWCLK_SetHigh();
  265.     SwdDly();
  266.     SWCLK_SetLow();
  267.     SwdDly();
  268.     return( tmp32 );
  269. }
  270. //LSB FIRST
  271. uint8_t Swd_Bus_RecvAck( void )
  272. {
  273.     uint8_t i;
  274.     uint8_t tmp8;
  275.     tmp8 = 0x00;
  276.     SWDIO_SetInput();
  277.     SwdDly();
  278.     for( i=0; i<3; i++ )
  279.     {
  280.         if( SWDIO_GetValue() )
  281.         {
  282.             tmp8 >>= 1;
  283.             tmp8 |= bv2;
  284.         }
  285.         else
  286.         {
  287.             tmp8 >>= 1;
  288.         }
  289.         SWCLK_SetHigh();
  290.         SwdDly();
  291.         SWCLK_SetLow();
  292.         SwdDly();
  293.     }
  294.     return( tmp8 );
  295. }

评论

太牛X了赞一个。  发表于 2021-1-2 21:58
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,只能读吗?能进行写吗?能的话这个可以做个离线下载器了。

评论

第122行到146行,是对寄存器的读写示例。  发表于 2021-1-6 08:59
fcccc 发表于 2021-1-5 15:44 | 显示全部楼层
很棒的操作,但是请问有什么用途?

评论

5楼已说明了其典型用途。  发表于 2021-1-6 09:00
@lonely 发表于 2021-9-27 17:21 | 显示全部楼层
楼主 请问如何取消读保护/写读保护呢?
lwb807 发表于 2021-10-28 16:45 | 显示全部楼层
利害,可以试试玩脱机烧录
lovelessing 发表于 2021-11-4 17:30 | 显示全部楼层
bv31和bv2这两个变量是什么
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

442

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部