OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5356|回复: 5

stm32mp157无系统裸机之硬件I2C(I2C6,AP3216C)

[复制链接]

14

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-9-14
在线时间
157 小时
发表于 2020-12-25 16:49:25 | 显示全部楼层 |阅读模式
本帖最后由 sppz 于 2020-12-26 10:46 编辑

1.stm32mp157裸机启动过程探寻
2.stm32mp157无系统裸机之中断(GIC)初窥门径
3.stm32mp157无系统裸机之定时器(TIM6)简单使用
4.stm32mp157无系统裸机之EXTI(WK_UP, KEY0, KEY1)按键

本篇为原子stm32mp157无系统裸机,个人框架(c++)下的第四篇[记录,总结,资料汇总].
本篇为I2C实验.实现了I2C6(AP3216C)简单使用.

--------分割线,以下为资料地址--------
stm32mp157参考手册
原子157硬件参考手册
AP3216C手册

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

14

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-9-14
在线时间
157 小时
 楼主| 发表于 2020-12-25 16:50:07 | 显示全部楼层
本帖最后由 sppz 于 2020-12-26 10:55 编辑

便民措施: px.zip (2.67 KB, 下载次数: 2)
回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-9-14
在线时间
157 小时
 楼主| 发表于 2020-12-25 16:50:46 | 显示全部楼层
本帖最后由 sppz 于 2020-12-26 11:00 编辑

I2C协议和AP3216C不细说,请大家自己查手册和教程.
GPIOA设置
  1.     { // A.0 WK_UP, A.11 I2C6_SCL, A.12 I2C6_SDA
  2.         auto moder(GPIOA::MODER(0)); moder.MODE() = 0;
  3.         moder.index(11); moder.MODE() = 2;
  4.         moder.index(12); moder.MODE() = 2;
  5.         moder.push();
  6.         auto otyper(GPIOA::OTYPER(0)); otyper.OT() = 0;
  7.         otyper.index(11); otyper.OT() = 1; // 一定要是开漏!!!
  8.         otyper.index(12); otyper.OT() = 1; // 一定要是开漏!!!
  9.         otyper.push();
  10.         auto ospeedr(GPIOA::OSPEEDR(0)); ospeedr.OS() = 0;
  11.         ospeedr.index(11); ospeedr.OS() = 3;
  12.         ospeedr.index(12); ospeedr.OS() = 3;
  13.         ospeedr.push();
  14.         auto pupdr(GPIOA::PUPDR(0)); pupdr.PUPD() = 2;
  15.         pupdr.index(11); pupdr.PUPD() = 0;
  16.         pupdr.index(12); pupdr.PUPD() = 0;
  17.         pupdr.push();
  18.         auto afr(GPIOA::AFR(0)); afr.AF() = 0;
  19.         afr.index(11); afr.AF() = 2;
  20.         afr.index(12); afr.AF() = 2;
  21.         afr.push();
  22.     }
复制代码
I2C6初始化
  1. static void initialize_i2c6() noexcept // clock default use apb5
  2. {
  3.     auto mp_apb5ensetr(RCC::MP_APB5ENSETR());
  4.     mp_apb5ensetr.I2C6EN() = 1;
  5.     mp_apb5ensetr.push();
  6.     auto cr1(I2C6::CR1());
  7.     cr1.ANFOFF() = 1;
  8.     cr1.DNF() = 0;
  9.     cr1.NOSTRETCH() = 0;
  10.     cr1.push();
  11.     auto cr2(I2C6::CR2());
  12.     cr2.PECBYTE() = 0;
  13.     cr2.push();
  14.     //
  15.     auto timingr(I2C6::TIMINGR());
  16.     timingr.PRESC() = 5;
  17.     timingr.SCLL() = 24;
  18.     timingr.SCLH() = 24;
  19.     timingr.SDADEL() = 25;
  20.     timingr.SCLDEL() = 24;
  21.     timingr.push();
  22.     cr1.pull();
  23.     cr1.PE() = 1;
  24.     cr1.push();
  25. }
复制代码

下图是此设置下协议波形(从PZ.6, PZ.7输出的I2C6的波形),大约400K?
1.png

回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-9-14
在线时间
157 小时
 楼主| 发表于 2020-12-25 16:51:14 | 显示全部楼层
本帖最后由 sppz 于 2020-12-26 11:03 编辑

I2C操作函数
  1. static void i2c6_write1(unsigned_integer8 address, unsigned_integer8 data) noexcept
  2. {
  3.     auto isr(I2C6::ISR());
  4.     while (isr.BUSY() == 1) { isr.pull(); };
  5.     auto cr2(I2C6::CR2());
  6.     cr2.SADD() = address;
  7.     cr2.RD_WRN() = 0;
  8.     cr2.ADD10() = 0;
  9.     cr2.NBYTES() = 1;
  10.     cr2.RELOAD() = 0;
  11.     cr2.AUTOEND() = 1;
  12.     cr2.START()  = 1;
  13.     cr2.push();
  14.     do { isr.pull(); } while (isr.TXE() == 0);
  15.     auto txdr(I2C6::TXDR(data));
  16.     txdr.push();
  17. }

  18. static void i2c6_write2(unsigned_integer8 address, unsigned_integer8 data0, unsigned_integer8 data1) noexcept
  19. {
  20.     auto isr(I2C6::ISR());
  21.     while (isr.BUSY() == 1) { isr.pull(); };
  22.     auto cr2(I2C6::CR2());
  23.     cr2.SADD() = address;
  24.     cr2.RD_WRN() = 0;
  25.     cr2.ADD10() = 0;
  26.     cr2.NBYTES() = 2;
  27.     cr2.RELOAD() = 0;
  28.     cr2.AUTOEND() = 1;
  29.     cr2.START()  = 1;
  30.     cr2.push();
  31.     I2C6::TXDR_cache txdr;
  32.     do { isr.pull(); } while (isr.TXE() == 0);
  33.     txdr.TXDATA() = data0;
  34.     txdr.push();
  35.     do { isr.pull(); } while (isr.TXE() == 0);
  36.     txdr.TXDATA() = data1;
  37.     txdr.push();
  38. }

  39. static unsigned_integer8 i2c6_read(unsigned_integer8 address) noexcept
  40. {
  41.     auto isr(I2C6::ISR());
  42.     while (isr.BUSY() == 1) { isr.pull(); };
  43.     auto cr2(I2C6::CR2());
  44.     cr2.SADD() = address;
  45.     cr2.RD_WRN() = 1;
  46.     cr2.ADD10() = 0;
  47.     cr2.NBYTES() = 1;
  48.     cr2.RELOAD() = 0;
  49.     cr2.AUTOEND() = 1;
  50.     cr2.START() = 1;
  51.     cr2.push();
  52.     do { isr.pull(); } while (isr.RXNE() == 0);
  53.     auto rxdr(I2C6::RXDR());
  54.     return rxdr.RXDATA();
  55. }
复制代码

AP3216C的操作函数
  1. static void ap3216c_write(unsigned_integer8 address, unsigned_integer8 data) noexcept
  2. {
  3.     i2c6_write2(0x1e << 1, address, data); // 注意7位地址时,使用的是bit[1..7]
  4. }

  5. static unsigned_integer8 ap3216c_read(unsigned_integer8 address) noexcept
  6. {
  7.     i2c6_write1(0x1e << 1, address); // 注意7位地址时,使用的是bit[1..7]
  8.     return i2c6_read(0x1e << 1);
  9. }
复制代码
更新后的按键和TIM6
  1.     size systick_count(0);
  2.     void px_GIC_TIM6() noexcept //
  3.     {
  4.         auto sr(TIM6::SR());
  5.         sr.UIF() = 0;
  6.         sr.push();
  7.         ++systick_count;
  8.         if (systick_count % 1000 == 0)
  9.         {
  10.             put_string("second=");
  11.             put_size(systick_count / 1000);
  12.             {
  13.                 auto odr(GPIOF::ODR(3)); odr.OD() ^= 1;
  14.                 odr.push();
  15.             }
  16.             put_string(" ap3216c");
  17.             put_string(" mode[0x0]="); put_size(ap3216c_read(0x0));
  18.             put_string(" PS_low[0xe]="); put_size(ap3216c_read(0xe));
  19.             put_string(" PS_high[0xf]="); put_size(ap3216c_read(0xf));
  20.             put_string("\r\n");
  21.         }
  22.     }
  23.     void px_GIC_EXTI3() noexcept // KEY0
  24.     {
  25.         auto rpr(EXTI::RPR(3));
  26.         if (rpr.RPIF() == 1)
  27.         {
  28.             rpr.value() = 0;
  29.             rpr.RPIF() = 1;
  30.             rpr.push();
  31.         }
  32.         auto fpr(EXTI::FPR(3));
  33.         if (fpr.FPIF() == 1)
  34.         {
  35.             fpr.value() = 0;
  36.             fpr.FPIF() = 1;
  37.             fpr.push();
  38.         }
  39.         put_string("KEY0 open ap3216c.\r\n");
  40.         ap3216c_write(0x0, 3);
  41.     }

  42.     void px_GIC_EXTI7() noexcept // KEY1
  43.     {
  44.         auto rpr(EXTI::RPR(7));
  45.         if (rpr.RPIF() == 1)
  46.         {
  47.             rpr.value() = 0;
  48.             rpr.RPIF() = 1;
  49.             rpr.push();
  50.         }
  51.         auto fpr(EXTI::FPR(7));
  52.         if (fpr.FPIF() == 1)
  53.         {
  54.             fpr.value() = 0;
  55.             fpr.FPIF() = 1;
  56.             fpr.push();
  57.         }
  58.         put_string("KEY1 close ap3216c.\r\n");
  59.         ap3216c_write(0x0, 0);
  60.     }
复制代码

回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-9-14
在线时间
157 小时
 楼主| 发表于 2020-12-25 16:52:03 | 显示全部楼层
本帖最后由 sppz 于 2020-12-26 11:06 编辑

记录下一些细节
1.I2C引脚需要设置为开漏.
2.AP3216C可以在远高于400K的情况下运行(虽然手册上说是400K).


记录下整个main文件
  1. import px.base_object;
  2. import px.cpu.stm32mp157.RCC;
  3. import px.cpu.stm32mp157.GPIO;
  4. import px.cpu.stm32mp157.USART;
  5. import px.cpu.stm32mp157.GIC;
  6. import px.cpu.stm32mp157.TIM;
  7. import px.cpu.stm32mp157.EXTI;
  8. import px.cpu.stm32mp157.I2C;

  9. using namespace px_namespace;
  10. using namespace px_namespace::cpu::stm32mp157;

  11. static void reset_clock() noexcept
  12. {
  13.     // clock use HSI
  14.     {
  15.         auto ocensetr(RCC::OCENSETR());
  16.         ocensetr.HSION() = 1;
  17.         ocensetr.push();
  18.         for (auto ocrdyr(RCC::OCRDYR()); ocrdyr.HSIRDY() == 0; ocrdyr.pull()) {}
  19.         auto hsicfgr(RCC::HSICFGR());
  20.         hsicfgr.HSIDIV() = 0;
  21.         hsicfgr.push();
  22.         for (auto ocrdyr(RCC::OCRDYR()); ocrdyr.HSIDIVRDY() == 0; ocrdyr.pull()) {}
  23.         auto mpckselr(RCC::MPCKSELR());
  24.         mpckselr.MPUSRC() = 0;
  25.         mpckselr.push();
  26.         do { mpckselr.pull(); } while (mpckselr.MPUSRCRDY() == 0);
  27.         auto axidivr(RCC::AXIDIVR());
  28.         axidivr.AXIDIV() = 0;
  29.         axidivr.push();
  30.         do { axidivr.pull(); } while (axidivr.AXIDIVRDY() == 0);
  31.         auto assckselr(RCC::ASSCKSELR());
  32.         assckselr.AXISSRC() = 0;
  33.         assckselr.push();
  34.         do { assckselr.pull(); } while (assckselr.AXISSRCRDY() == 0);
  35.         auto mcudivr(RCC::MCUDIVR());
  36.         mcudivr.MCUDIV() = 0;
  37.         mcudivr.push();
  38.         do { mcudivr.pull(); } while (mcudivr.MCUDIVRDY() == 0);
  39.         auto mssckselr(RCC::MSSCKSELR());
  40.         mssckselr.MCUSSRC() = 0;
  41.         mssckselr.push();
  42.         do { mssckselr.pull(); } while (mssckselr.MCUSSRCRDY() == 0);
  43.     }
  44.     // close PLLs
  45.     {
  46.         auto pll1cr(RCC::PLL1CR());
  47.         pll1cr.DIVPEN() = 0;
  48.         pll1cr.DIVQEN() = 0;
  49.         pll1cr.DIVREN() = 0;
  50.         pll1cr.push();
  51.         pll1cr.PLLON() = 0;
  52.         pll1cr.push();
  53.         do { pll1cr.pull(); } while (pll1cr.PLL1RDY() == 1);
  54.         auto pll2cr(RCC::PLL2CR());
  55.         pll2cr.DIVPEN() = 0;
  56.         pll2cr.DIVQEN() = 0;
  57.         pll2cr.DIVREN() = 0;
  58.         pll2cr.push();
  59.         pll2cr.PLLON() = 0;
  60.         pll2cr.push();
  61.         do { pll2cr.pull(); } while (pll2cr.PLL2RDY() == 1);
  62.         auto pll3cr(RCC::PLL3CR());
  63.         pll3cr.DIVPEN() = 0;
  64.         pll3cr.DIVQEN() = 0;
  65.         pll3cr.DIVREN() = 0;
  66.         pll3cr.push();
  67.         pll3cr.PLLON() = 0;
  68.         pll3cr.push();
  69.         do { pll3cr.pull(); } while (pll3cr.PLL3RDY() == 1);
  70.         auto pll4cr(RCC::PLL4CR());
  71.         pll4cr.DIVPEN() = 0;
  72.         pll4cr.DIVQEN() = 0;
  73.         pll4cr.DIVREN() = 0;
  74.         pll4cr.push();
  75.         pll4cr.PLLON() = 0;
  76.         pll4cr.push();
  77.         do { pll4cr.pull(); } while (pll4cr.PLL4RDY() == 1);
  78.     }
  79. }

  80. // MPU[PLL1_P] 600Mhz, AXI[PLL2_P] 266.5Mhz(reference Using the SSCG block), DDR[PLL2_R] 533Mhz, , MCU 200Mhz, APB[1-5] 100Mhz
  81. static void set_clock() noexcept
  82. {
  83.     // open HSE
  84.     {
  85.         auto ocensetr(RCC::OCENSETR());
  86.         ocensetr.HSEON();
  87.         ocensetr.push();
  88.         for (auto ocrdyr(RCC::OCRDYR()); ocrdyr.HSERDY() == 0; ocrdyr.pull()) {}
  89.     }
  90.     // PLLs source select
  91.     {
  92.         auto rck12selr(RCC::RCK12SELR());
  93.         rck12selr.PLL12SRC() = 1;
  94.         rck12selr.push();
  95.         do { rck12selr.pull(); } while (rck12selr.PLL12SRCRDY() == 0);
  96.         auto rck3selr(RCC::RCK3SELR());
  97.         rck3selr.PLL3SRC() = 1;
  98.         rck3selr.push();
  99.         do { rck3selr.pull(); } while (rck3selr.PLL3SRCRDY() == 0);
  100.     }
  101.     // PLL1 set
  102.     {
  103.         auto pll1cfgr1(RCC::PLL1CFGR1());
  104.         pll1cfgr1.DIVN() = 49;
  105.         pll1cfgr1.DIVM1() = 1;
  106.         pll1cfgr1.push();
  107.         auto pll1cfgr2(RCC::PLL1CFGR2());
  108.         pll1cfgr2.DIVP() = 0;
  109.         pll1cfgr2.push();
  110.         auto pll1fracr(RCC::PLL1FRACR());
  111.         pll1fracr.FRACV() = 0;
  112.         pll1fracr.FRACLE() = 0;
  113.         pll1fracr.push();
  114.         pll1fracr.FRACLE() = 1;
  115.         pll1fracr.push();
  116.         auto pll1cr(RCC::PLL1CR());
  117.         pll1cr.SSCG_CTRL() = 0;
  118.         pll1cr.PLLON() = 1;
  119.         pll1cr.push();
  120.         do { pll1cr.pull(); } while (pll1cr.PLL1RDY() == 0);
  121.         pll1cr.DIVPEN() = 1;
  122.         pll1cr.push();
  123.     }
  124.     // PLL2 set
  125.     {
  126.         auto pll2cfgr1(RCC::PLL2CFGR1());
  127.         pll2cfgr1.DIVN() = 43;
  128.         pll2cfgr1.DIVM2() = 1;
  129.         pll2cfgr1.push();
  130.         auto pll2cfgr2(RCC::PLL2CFGR2());
  131.         pll2cfgr2.DIVP() = 1;
  132.         pll2cfgr2.DIVR() = 0;
  133.         pll2cfgr2.push();
  134.         auto pll2fracr(RCC::PLL2FRACR());
  135.         pll2fracr.FRACV() = 0;
  136.         pll2fracr.FRACLE() = 0;
  137.         pll2fracr.push();
  138.         pll2fracr.FRACLE() = 1;
  139.         pll2fracr.push();
  140.         auto pll2csgr(RCC::PLL2CSGR());
  141.         pll2csgr.MOD_PER() = 120;
  142.         pll2csgr.SSCG_MODE() = 1;
  143.         pll2csgr.INC_STEP() = 12;
  144.         pll2csgr.push();
  145.         auto pll2cr(RCC::PLL2CR());
  146.         pll2cr.SSCG_CTRL() = 1;
  147.         pll2cr.PLLON() = 1;
  148.         pll2cr.push();
  149.         do { pll2cr.pull(); } while (pll2cr.PLL2RDY() == 0);
  150.         pll2cr.DIVPEN() = 1;
  151.         pll2cr.DIVREN() = 1;
  152.         pll2cr.push();
  153.     }
  154.     // PLL3 set
  155.     {
  156.         auto pll3cfgr1(RCC::PLL3CFGR1());
  157.         pll3cfgr1.DIVN() = 49;
  158.         pll3cfgr1.DIVM3() = 2;
  159.         pll3cfgr1.IFRGE() = 1;
  160.         pll3cfgr1.push();
  161.         auto pll3cfgr2(RCC::PLL3CFGR2());
  162.         pll3cfgr2.DIVP() = 1;
  163.         pll3cfgr2.push();
  164.         auto pll3fracr(RCC::PLL3FRACR());
  165.         pll3fracr.FRACV() = 0;
  166.         pll3fracr.FRACLE() = 0;
  167.         pll3fracr.push();
  168.         pll3fracr.FRACLE() = 1;
  169.         pll3fracr.push();
  170.         auto pll3cr(RCC::PLL3CR());
  171.         pll3cr.PLLON() = 1;
  172.         pll3cr.push();
  173.         do { pll3cr.pull(); } while (pll3cr.PLL3RDY() == 0);
  174.         pll3cr.DIVPEN() = 1;
  175.         pll3cr.push();
  176.     }
  177.     // MCU set
  178.     {
  179.         auto mcudivr(RCC::MCUDIVR());
  180.         mcudivr.MCUDIV() = 0;
  181.         mcudivr.push();
  182.         do { mcudivr.pull(); } while (mcudivr.MCUDIVRDY() == 0);
  183.     }
  184.     // AXI set
  185.     {
  186.         auto axidivr(RCC::AXIDIVR());
  187.         axidivr.AXIDIV() = 0;
  188.         axidivr.push();
  189.         do { axidivr.pull(); } while (axidivr.AXIDIVRDY() == 0);
  190.     }
  191.     // APB4 set
  192.     {
  193.         auto apb4divr(RCC::APB4DIVR());
  194.         apb4divr.APB4DIV() = 1;
  195.         apb4divr.push();
  196.         do { apb4divr.pull(); } while (apb4divr.APB4DIVRDY() == 0);
  197.     }
  198.     // APB5
  199.     {
  200.         auto apb5divr(RCC::APB5DIVR());
  201.         apb5divr.APB5DIV() = 1;
  202.         apb5divr.push();
  203.         do { apb5divr.pull(); } while (apb5divr.APB5DIVRDY() == 0);
  204.     }
  205.     // APB1
  206.     {
  207.         auto apb1divr(RCC::APB1DIVR());
  208.         apb1divr.APB1DIV() = 1;
  209.         apb1divr.push();
  210.         do { apb1divr.pull(); } while (apb1divr.APB1DIVRDY() == 0);
  211.     }
  212.     // APB2
  213.     {
  214.         auto apb2divr(RCC::APB2DIVR());
  215.         apb2divr.APB2DIV() = 1;
  216.         apb2divr.push();
  217.         do { apb2divr.pull(); } while (apb2divr.APB2DIVRDY() == 0);
  218.     }
  219.     // APB3
  220.     {
  221.         auto apb3divr(RCC::APB3DIVR());
  222.         apb3divr.APB3DIV() = 1;
  223.         apb3divr.push();
  224.         do { apb3divr.pull(); } while (apb3divr.APB3DIVRDY() == 0);
  225.     }
  226.     // switch
  227.     {
  228.         auto mpckselr(RCC::MPCKSELR());
  229.         mpckselr.MPUSRC() = 2; // pll1_p_ck
  230.         mpckselr.push();
  231.         do { mpckselr.pull(); } while (mpckselr.MPUSRCRDY() == 0);
  232.         auto assckselr(RCC::ASSCKSELR());
  233.         assckselr.AXISSRC() = 2; // pll2_p_ck
  234.         assckselr.push();
  235.         do { assckselr.pull(); } while (assckselr.AXISSRCRDY() == 0);
  236.         auto mssckselr(RCC::MSSCKSELR());
  237.         mssckselr.MCUSSRC() = 3; // pll3_p_ck
  238.         mssckselr.push();
  239.         do { mssckselr.pull(); } while (mssckselr.MCUSSRCRDY() == 0);
  240.     }
  241. }

  242. static void initialize_clock() noexcept
  243. {
  244.     reset_clock();
  245.     set_clock();
  246. }

  247. static void initialize_gic() noexcept
  248. {
  249.     //38 EXTI0, 41 EXTI3, 84 uart4, 86 tim6, 97 EXTI7
  250.     auto igroupr(GICD::IGROUPR(38)); igroupr.GROUP_STATUS() = 1;
  251.     igroupr.index(41); igroupr.GROUP_STATUS() = 1;
  252.     igroupr.index(84); igroupr.GROUP_STATUS() = 1;
  253.     igroupr.index(86); igroupr.GROUP_STATUS() = 1;
  254.     igroupr.index(97); igroupr.GROUP_STATUS() = 1;
  255.     igroupr.push();
  256.     auto isenabler(GICD::ISENABLER(38)); isenabler.SET_ENABLE() = 1;
  257.     isenabler.index(41); isenabler.SET_ENABLE() = 1;
  258.     isenabler.index(84); isenabler.SET_ENABLE() = 1;
  259.     isenabler.index(86); isenabler.SET_ENABLE() = 1;
  260.     isenabler.index(97); isenabler.SET_ENABLE() = 1;
  261.     isenabler.push();
  262.     auto ipriorityr(GICD::IPRIORITYR(38)); ipriorityr.PRIORITY() = 0;
  263.     ipriorityr.index(41); ipriorityr.PRIORITY() = 0;
  264.     ipriorityr.index(84); ipriorityr.PRIORITY() = 0;
  265.     ipriorityr.index(86); ipriorityr.PRIORITY() = 0;
  266.     ipriorityr.index(97); ipriorityr.PRIORITY() = 0;
  267.     ipriorityr.push();
  268.     auto itargetsr(GICD::ITARGETSR(38)); itargetsr.CPU_TARGETS() = 1;
  269.     itargetsr.index(41); itargetsr.CPU_TARGETS() = 1;
  270.     itargetsr.index(84); itargetsr.CPU_TARGETS() = 1;
  271.     itargetsr.index(86); itargetsr.CPU_TARGETS() = 1;
  272.     itargetsr.index(97); itargetsr.CPU_TARGETS() = 1;
  273.     itargetsr.push();
  274.     auto icfgr(GICD::ICFGR(38)); icfgr.INT_CONFIG() = 3;
  275.     icfgr.index(41); icfgr.INT_CONFIG() = 3;
  276.     icfgr.index(84); icfgr.INT_CONFIG() = 1;
  277.     icfgr.index(86); icfgr.INT_CONFIG() = 1;
  278.     icfgr.index(97); icfgr.INT_CONFIG() = 3;
  279.     icfgr.push();
  280. }

  281. void initialize_exti() noexcept
  282. {
  283.     // PA.0 WK_UP, PG.3 KEY0, PH.7 KEY1
  284.     auto rtsr(EXTI::RTSR(0)); rtsr.RT() = 1;
  285.     rtsr.index(3); rtsr.RT() = 1;
  286.     rtsr.index(7); rtsr.RT() = 1;
  287.     rtsr.push();
  288.     auto ftsr(EXTI::FTSR(0)); ftsr.FT() = 1;
  289.     ftsr.index(3); ftsr.FT() = 1;
  290.     ftsr.index(7); ftsr.FT() = 1;
  291.     ftsr.push();
  292.     auto exticr(EXTI::EXTICR(0)); exticr.EXTI() = 0;
  293.     exticr.index(3); exticr.EXTI() = 6;
  294.     exticr.index(7); exticr.EXTI() = 7;
  295.     exticr.push();
  296.     auto imr(EXTI::IMR(0)); imr.IM() = 1;
  297.     imr.index(3); imr.IM() = 1;
  298.     imr.index(7); imr.IM() = 1;
  299.     imr.push();
  300.     auto emr(EXTI::EMR(0)); emr.EM() = 1;
  301.     emr.index(3); emr.EM() = 1;
  302.     emr.index(7); emr.EM() = 1;
  303.     emr.push();
  304. }

  305. static void initialize_gpio() noexcept
  306. {
  307.     // open GPIO[A, B, F, G, H, I]
  308.     {
  309.         auto mp_ahb4ensetr(RCC::MP_AHB4ENSETR());
  310.         mp_ahb4ensetr.GPIOAEN() = 1;
  311.         mp_ahb4ensetr.GPIOBEN() = 1;
  312.         mp_ahb4ensetr.GPIOFEN() = 1;
  313.         mp_ahb4ensetr.GPIOGEN() = 1;
  314.         mp_ahb4ensetr.GPIOHEN() = 1;
  315.         mp_ahb4ensetr.GPIOIEN() = 1;
  316.         mp_ahb4ensetr.push();
  317.     }
  318.     { // A.0 WK_UP, A.11 I2C6_SCL, A.12 I2C6_SDA
  319.         auto moder(GPIOA::MODER(0)); moder.MODE() = 0;
  320.         moder.index(11); moder.MODE() = 2;
  321.         moder.index(12); moder.MODE() = 2;
  322.         moder.push();
  323.         auto otyper(GPIOA::OTYPER(0)); otyper.OT() = 0;
  324.         otyper.index(11); otyper.OT() = 1; // 一定要是开漏!!!
  325.         otyper.index(12); otyper.OT() = 1; // 一定要是开漏!!!
  326.         otyper.push();
  327.         auto ospeedr(GPIOA::OSPEEDR(0)); ospeedr.OS() = 0;
  328.         ospeedr.index(11); ospeedr.OS() = 3;
  329.         ospeedr.index(12); ospeedr.OS() = 3;
  330.         ospeedr.push();
  331.         auto pupdr(GPIOA::PUPDR(0)); pupdr.PUPD() = 2;
  332.         pupdr.index(11); pupdr.PUPD() = 0;
  333.         pupdr.index(12); pupdr.PUPD() = 0;
  334.         pupdr.push();
  335.         auto afr(GPIOA::AFR(0)); afr.AF() = 0;
  336.         afr.index(11); afr.AF() = 2;
  337.         afr.index(12); afr.AF() = 2;
  338.         afr.push();
  339.     }
  340.     { // B.2 UART4_RX
  341.         auto moder(GPIOB::MODER(2)); moder.MODE() = 2;
  342.         moder.push();
  343.         auto otyper(GPIOB::OTYPER(2)); otyper.OT() = 0;
  344.         otyper.push();
  345.         auto ospeedr(GPIOB::OSPEEDR(2)); ospeedr.OS() = 3;
  346.         ospeedr.push();
  347.         auto pupdr(GPIOB::PUPDR(2)); pupdr.PUPD() = 1;
  348.         pupdr.push();
  349.         auto afr(GPIOB::AFR(2)); afr.AF() = 8;
  350.         afr.push();
  351.     }
  352.     { // F.3 led
  353.         auto moder(GPIOF::MODER(3)); moder.MODE() = 1;
  354.         moder.push();
  355.         auto otyper(GPIOF::OTYPER(3)); otyper.OT() = 0;
  356.         otyper.push();
  357.         auto ospeedr(GPIOF::OSPEEDR(3)); ospeedr.OS() = 0;
  358.         ospeedr.push();
  359.         auto pupdr(GPIOF::PUPDR(3)); pupdr.PUPD() = 1;
  360.         pupdr.push();
  361.         auto odr(GPIOF::ODR(3)); odr.OD() = 1;
  362.         odr.push();
  363.     }
  364.     { // G.3 KEY0, G.11 UART4_TX
  365.         auto moder(GPIOG::MODER(3)); moder.MODE() = 0;
  366.         moder.index(11); moder.MODE() = 2;
  367.         moder.push();
  368.         auto otyper(GPIOG::OTYPER(3)); otyper.OT() = 0;
  369.         otyper.index(11); otyper.OT() = 0;
  370.         otyper.push();
  371.         auto ospeedr(GPIOG::OSPEEDR(3)); ospeedr.OS() = 0;
  372.         ospeedr.index(11); ospeedr.OS() = 3;
  373.         ospeedr.push();
  374.         auto pupdr(GPIOG::PUPDR(3)); pupdr.PUPD() = 1;
  375.         pupdr.index(11); pupdr.PUPD() = 1;
  376.         pupdr.push();
  377.         auto afr(GPIOG::AFR(3)); afr.AF() = 0;
  378.         afr.index(11); afr.AF() = 6;
  379.         afr.push();
  380.     }
  381.     { // H.7 KEY1
  382.         auto moder(GPIOH::MODER(7)); moder.MODE() = 0;
  383.         moder.push();
  384.         auto otyper(GPIOH::OTYPER(7)); otyper.OT() = 0;
  385.         otyper.push();
  386.         auto ospeedr(GPIOH::OSPEEDR(7)); ospeedr.OS() = 0;
  387.         ospeedr.push();
  388.         auto pupdr(GPIOH::PUPDR(7)); pupdr.PUPD() = 1;
  389.         pupdr.push();
  390.         auto afr(GPIOH::AFR(7)); afr.AF() = 0;
  391.         afr.push();
  392.     }
  393.     { // I.0 led
  394.         auto moder(GPIOI::MODER(0)); moder.MODE() = 1;
  395.         moder.push();
  396.         auto otyper(GPIOI::OTYPER(0)); otyper.OT() = 0;
  397.         otyper.push();
  398.         auto ospeedr(GPIOI::OSPEEDR(0)); ospeedr.OS() = 0;
  399.         ospeedr.push();
  400.         auto pupdr(GPIOI::PUPDR(0)); pupdr.PUPD() = 1;
  401.         pupdr.push();
  402.         auto odr(GPIOI::ODR(0)); odr.OD() = 0;
  403.         odr.push();
  404.     }
  405.     // // test I2C6
  406.     // {
  407.     //     auto mp_ahb5ensetr(RCC::MP_AHB5ENSETR());
  408.     //     mp_ahb5ensetr.GPIOZEN() = 1;
  409.     //     mp_ahb5ensetr.push();
  410.     // }
  411.     // { // Z.6 I2C6_SCL, Z.7 I2C6_SDA
  412.     //     auto moder(GPIOZ::MODER(6)); moder.MODE() = 2;
  413.     //     moder.index(7); moder.MODE() = 2;
  414.     //     moder.push();
  415.     //     auto otyper(GPIOZ::OTYPER(6)); otyper.OT() = 0;
  416.     //     otyper.index(7); otyper.OT() = 0;
  417.     //     otyper.push();
  418.     //     auto ospeedr(GPIOZ::OSPEEDR(6)); ospeedr.OS() = 3;
  419.     //     ospeedr.index(7); ospeedr.OS() = 3;
  420.     //     ospeedr.push();
  421.     //     auto pupdr(GPIOZ::PUPDR(6)); pupdr.PUPD() = 1;
  422.     //     pupdr.index(7); pupdr.PUPD() = 1;
  423.     //     pupdr.push();
  424.     //     auto afr(GPIOZ::AFR(6)); afr.AF() = 2;
  425.     //     afr.index(7); afr.AF() = 2;
  426.     //     afr.push();
  427.     // }
  428. }

  429. static void initialize_uart4() noexcept
  430. {
  431.     auto apb1rstsetr(RCC::APB1RSTSETR());
  432.     apb1rstsetr.UART4RST() = 1;
  433.     apb1rstsetr.push();
  434.     auto apb1rstclrr(RCC::APB1RSTCLRR());
  435.     while (apb1rstclrr.UART4RST() == 0) { apb1rstclrr.pull(); }
  436.     apb1rstclrr.UART4RST() = 1;
  437.     apb1rstclrr.push();
  438.     do { apb1rstclrr.pull(); } while (apb1rstclrr.UART4RST() == 1);
  439.     auto uart24ckselr(RCC::UART24CKSELR());
  440.     uart24ckselr.UART24SRC() = 0;
  441.     uart24ckselr.push();
  442.     auto mp_apb1ensetr(RCC::MP_APB1ENSETR());
  443.     mp_apb1ensetr.UART4EN() = 1;
  444.     mp_apb1ensetr.push();
  445.     auto prescr(UART4::PRESCR());
  446.     prescr.PRESC() = 0;
  447.     prescr.push();
  448.     auto brr(UART4::BRR());
  449.     brr.BR() = 100000000 / 115200;
  450.     brr.push();
  451.     auto cr1(UART4::CR1());
  452.     cr1.UE() = 1;
  453.     cr1.RE() = 1;
  454.     cr1.TE() = 1;
  455.     cr1.RXNEIE() = 1;
  456.     cr1.M0() = 0;
  457.     cr1.OVER8() = 0;
  458.     cr1.M1() = 0;
  459.     cr1.push();
  460. }

  461. static void initialize_i2c6() noexcept // clock default use apb5
  462. {
  463.     auto mp_apb5ensetr(RCC::MP_APB5ENSETR());
  464.     mp_apb5ensetr.I2C6EN() = 1;
  465.     mp_apb5ensetr.push();
  466.     auto cr1(I2C6::CR1());
  467.     cr1.ANFOFF() = 1;
  468.     cr1.DNF() = 0;
  469.     cr1.NOSTRETCH() = 0;
  470.     cr1.push();
  471.     auto cr2(I2C6::CR2());
  472.     cr2.PECBYTE() = 0;
  473.     cr2.push();
  474.     //
  475.     auto timingr(I2C6::TIMINGR());
  476.     timingr.PRESC() = 5;
  477.     timingr.SCLL() = 24;
  478.     timingr.SCLH() = 24;
  479.     timingr.SDADEL() = 25;
  480.     timingr.SCLDEL() = 24;
  481.     timingr.push();
  482.     cr1.pull();
  483.     cr1.PE() = 1;
  484.     cr1.push();
  485. }

  486. static void initialize_tim6() noexcept
  487. {
  488.     // 根据157 reference-568页,当前配置下TIM的频率为200Mhz
  489.     auto mp_apb1ensetr(RCC::MP_APB1ENSETR());
  490.     mp_apb1ensetr.TIM6EN() = 1;
  491.     mp_apb1ensetr.push();
  492.     auto cr2(TIM6::CR2());
  493.     cr2.MMS() = 0;
  494.     cr2.push();
  495.     auto dier(TIM6::DIER());
  496.     dier.UIE() = 1;
  497.     dier.UDE() = 0;
  498.     dier.push();
  499.     auto pscr(TIM6::PSCR());
  500.     pscr.PSC() = 199;
  501.     pscr.push();
  502.     auto arr(TIM6::ARR());
  503.     arr.AR() = 1000;
  504.     arr.push();
  505.     auto cr1(TIM6::CR1());
  506.     cr1.CEN() = 1;
  507.     cr1.UDIS() = 0;
  508.     cr1.URS() = 0;
  509.     cr1.OPM() = 0;
  510.     cr1.ARPE() = 1;
  511.     cr1.UIFREMAP() = 0;
  512.     cr1.push();
  513. }

  514. void put_character(const character_type value) noexcept
  515. {
  516.     for (auto isr(UART4::ISR()); isr.TXE() == 0; isr.pull()) {}
  517.     auto tdr(UART4::TDR(0));
  518.     tdr.TD() = value;
  519.     tdr.push();
  520. }

  521. void put_string(const character_type* value) noexcept
  522. {
  523.     while (*value != '\0')
  524.     {
  525.         put_character(*value);
  526.         ++value;
  527.     }
  528. }

  529. void put_size(const size& value) noexcept
  530. {
  531.     if (value < 10)
  532.     {
  533.         put_character('0' + value.value());
  534.         return;
  535.     }
  536.     put_size(value / 10);
  537.     put_character('0' + (value % 10).value());
  538. }

  539. static void i2c6_write1(unsigned_integer8 address, unsigned_integer8 data) noexcept
  540. {
  541.     auto isr(I2C6::ISR());
  542.     while (isr.BUSY() == 1) { isr.pull(); };
  543.     auto cr2(I2C6::CR2());
  544.     cr2.SADD() = address;
  545.     cr2.RD_WRN() = 0;
  546.     cr2.ADD10() = 0;
  547.     cr2.NBYTES() = 1;
  548.     cr2.RELOAD() = 0;
  549.     cr2.AUTOEND() = 1;
  550.     cr2.START()  = 1;
  551.     cr2.push();
  552.     do { isr.pull(); } while (isr.TXE() == 0);
  553.     auto txdr(I2C6::TXDR(data));
  554.     txdr.push();
  555. }

  556. static void i2c6_write2(unsigned_integer8 address, unsigned_integer8 data0, unsigned_integer8 data1) noexcept
  557. {
  558.     auto isr(I2C6::ISR());
  559.     while (isr.BUSY() == 1) { isr.pull(); };
  560.     auto cr2(I2C6::CR2());
  561.     cr2.SADD() = address;
  562.     cr2.RD_WRN() = 0;
  563.     cr2.ADD10() = 0;
  564.     cr2.NBYTES() = 2;
  565.     cr2.RELOAD() = 0;
  566.     cr2.AUTOEND() = 1;
  567.     cr2.START()  = 1;
  568.     cr2.push();
  569.     I2C6::TXDR_cache txdr;
  570.     do { isr.pull(); } while (isr.TXE() == 0);
  571.     txdr.TXDATA() = data0;
  572.     txdr.push();
  573.     do { isr.pull(); } while (isr.TXE() == 0);
  574.     txdr.TXDATA() = data1;
  575.     txdr.push();
  576. }

  577. static unsigned_integer8 i2c6_read(unsigned_integer8 address) noexcept
  578. {
  579.     auto isr(I2C6::ISR());
  580.     while (isr.BUSY() == 1) { isr.pull(); };
  581.     auto cr2(I2C6::CR2());
  582.     cr2.SADD() = address;
  583.     cr2.RD_WRN() = 1;
  584.     cr2.ADD10() = 0;
  585.     cr2.NBYTES() = 1;
  586.     cr2.RELOAD() = 0;
  587.     cr2.AUTOEND() = 1;
  588.     cr2.START() = 1;
  589.     cr2.push();
  590.     do { isr.pull(); } while (isr.RXNE() == 0);
  591.     auto rxdr(I2C6::RXDR());
  592.     return rxdr.RXDATA();
  593. }

  594. static void ap3216c_write(unsigned_integer8 address, unsigned_integer8 data) noexcept
  595. {
  596.     i2c6_write2(0x1e << 1, address, data); // 注意7位地址时,使用的是bit[1..7]
  597. }

  598. static unsigned_integer8 ap3216c_read(unsigned_integer8 address) noexcept
  599. {
  600.     i2c6_write1(0x1e << 1, address); // 注意7位地址时,使用的是bit[1..7]
  601.     return i2c6_read(0x1e << 1);
  602. }

  603. void initialize() noexcept
  604. {
  605.     initialize_clock();
  606.     initialize_gpio();
  607.     initialize_uart4();
  608.     initialize_i2c6();
  609.     initialize_tim6();
  610.     initialize_gic();
  611.     initialize_exti();
  612.     put_string("boot.\r\n");
  613. }

  614. extern "C"
  615. {
  616.     void px_GIC_UART4() noexcept // 最简单的处理
  617.     {
  618.         auto isr(UART4::ISR());
  619.         if (isr.RXNE() == 1)
  620.         {
  621.             put_character((character_type)UART4::RDR().RD());
  622.         }
  623.     }

  624.     size systick_count(0);
  625.     void px_GIC_TIM6() noexcept //
  626.     {
  627.         auto sr(TIM6::SR());
  628.         sr.UIF() = 0;
  629.         sr.push();
  630.         ++systick_count;
  631.         if (systick_count % 1000 == 0)
  632.         {
  633.             put_string("second=");
  634.             put_size(systick_count / 1000);
  635.             {
  636.                 auto odr(GPIOF::ODR(3)); odr.OD() ^= 1;
  637.                 odr.push();
  638.             }
  639.             put_string(" ap3216c");
  640.             put_string(" mode[0x0]="); put_size(ap3216c_read(0x0));
  641.             put_string(" PS_low[0xe]="); put_size(ap3216c_read(0xe));
  642.             put_string(" PS_high[0xf]="); put_size(ap3216c_read(0xf));
  643.             put_string("\r\n");
  644.         }
  645.     }

  646.     void px_GIC_EXTI0() noexcept // WK_UP
  647.     {
  648.         auto rpr(EXTI::RPR(0));
  649.         if (rpr.RPIF() == 1)
  650.         {
  651.             rpr.value() = 0;
  652.             rpr.RPIF() = 1;
  653.             rpr.push();
  654.         }
  655.         auto fpr(EXTI::FPR(0));
  656.         if (fpr.FPIF() == 1)
  657.         {
  658.             fpr.value() = 0;
  659.             fpr.FPIF() = 1;
  660.             fpr.push();
  661.         }
  662.         put_string("WK_UP.\r\n");
  663.     }

  664.     void px_GIC_EXTI3() noexcept // KEY0
  665.     {
  666.         auto rpr(EXTI::RPR(3));
  667.         if (rpr.RPIF() == 1)
  668.         {
  669.             rpr.value() = 0;
  670.             rpr.RPIF() = 1;
  671.             rpr.push();
  672.         }
  673.         auto fpr(EXTI::FPR(3));
  674.         if (fpr.FPIF() == 1)
  675.         {
  676.             fpr.value() = 0;
  677.             fpr.FPIF() = 1;
  678.             fpr.push();
  679.         }
  680.         put_string("KEY0 open ap3216c.\r\n");
  681.         ap3216c_write(0x0, 3);
  682.     }

  683.     void px_GIC_EXTI7() noexcept // KEY1
  684.     {
  685.         auto rpr(EXTI::RPR(7));
  686.         if (rpr.RPIF() == 1)
  687.         {
  688.             rpr.value() = 0;
  689.             rpr.RPIF() = 1;
  690.             rpr.push();
  691.         }
  692.         auto fpr(EXTI::FPR(7));
  693.         if (fpr.FPIF() == 1)
  694.         {
  695.             fpr.value() = 0;
  696.             fpr.FPIF() = 1;
  697.             fpr.push();
  698.         }
  699.         put_string("KEY1 close ap3216c.\r\n");
  700.         ap3216c_write(0x0, 0);
  701.     }

  702.     void px_GIC_default() noexcept
  703.     {
  704.         put_string("GIC_default\r\n");
  705.     }
  706. }
复制代码

回复 支持 反对

使用道具 举报

14

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-9-14
在线时间
157 小时
 楼主| 发表于 2020-12-25 16:52:25 | 显示全部楼层
本帖最后由 sppz 于 2020-12-26 11:09 编辑

有兴趣跟进了解的请关注:px

下一个为SPI

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-1-31 17:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表