pins.lua 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. --- 模块功能:GPIO 功能配置,包括输入输出IO和上升下降沿中断IO
  2. -- @module pins
  3. -- @author openLuat
  4. -- @license MIT
  5. -- @copyright openLuat
  6. -- @release 2017.09.23 11:34
  7. require "sys"
  8. module(..., package.seeall)
  9. local interruptCallbacks = {}
  10. local dirs = {}
  11. --- 配置GPIO模式
  12. -- @number pin GPIO,ID
  13. -- GPIO 0到GPIO 31表示为pio.P0_0到pio.P0_31
  14. -- GPIO 32到GPIO XX表示为pio.P1_0到pio.P1_(XX-32),例如GPIO33 表示为pio.P1_1
  15. -- GPIO 64到GPIO XX表示为pio.P2_0到pio.P2_(XX-64),例如GPIO65 表示为pio.P2_1
  16. -- @param val number、nil或者function类型
  17. -- 配置为输出模式时,为number类型,表示默认电平,0是低电平,1是高电平
  18. -- 配置为输入模式时,为nil
  19. -- 配置为中断模式时,为function类型,表示中断处理函数
  20. -- @param pull number,pio.PULLUP:上拉模式。pio.PULLDOWN:下拉模式。pio.NOPULL:高阻态
  21. -- 如果没有设置此参数,默认的上下拉参考模块的硬件设计说明书
  22. -- @return function
  23. -- 配置为输出模式时,返回的函数,可以设置IO的电平
  24. -- 配置为输入或者中断模式时,返回的函数,可以实时获取IO的电平
  25. -- @usage setOutputFnc = pins.setup(pio.P1_1,0),配置GPIO 33,输出模式,默认输出低电平;
  26. --执行setOutputFnc(0)可输出低电平,执行setOutputFnc(1)可输出高电平
  27. -- @usage getInputFnc = pins.setup(pio.P1_1,intFnc),配置GPIO33,中断模式
  28. -- 产生中断时自动调用intFnc(msg)函数:上升沿中断时:msg为cpu.INT_GPIO_POSEDGE;下降沿中断时:msg为cpu.INT_GPIO_NEGEDGE
  29. -- 执行getInputFnc()即可获得当前电平;如果是低电平,getInputFnc()返回0;如果是高电平,getInputFnc()返回1
  30. -- @usage getInputFnc = pins.setup(pio.P1_1),配置GPIO33,输入模式
  31. --执行getInputFnc()即可获得当前电平;如果是低电平,getInputFnc()返回0;如果是高电平,getInputFnc()返回1
  32. -- @usage
  33. --有些GPIO需要打开对应的ldo电压域之后,才能正常配置工作,电压域和对应的GPIO关系如下
  34. --pmd.ldoset(x,pmd.LDO_VSIM1) -- GPIO 29、30、31
  35. --pmd.ldoset(x,pmd.LDO_VLCD) -- GPIO 0、1、2、3、4
  36. --pmd.ldoset(x,pmd.LDO_VMMC) -- GPIO 24、25、26、27、28
  37. --x=0时:关闭LDO
  38. --x=1时:LDO输出1.716V
  39. --x=2时:LDO输出1.828V
  40. --x=3时:LDO输出1.939V
  41. --x=4时:LDO输出2.051V
  42. --x=5时:LDO输出2.162V
  43. --x=6时:LDO输出2.271V
  44. --x=7时:LDO输出2.375V
  45. --x=8时:LDO输出2.493V
  46. --x=9时:LDO输出2.607V
  47. --x=10时:LDO输出2.719V
  48. --x=11时:LDO输出2.831V
  49. --x=12时:LDO输出2.942V
  50. --x=13时:LDO输出3.054V
  51. --x=14时:LDO输出3.165V
  52. --x=15时:LDO输出3.177V
  53. --除了上面列举出的GPIO外,其余的GPIO不需要打开特定的电压域,可以直接配置工作
  54. function setup(pin, val, pull)
  55. -- 关闭该IO
  56. pio.pin.close(pin)
  57. -- 中断模式配置
  58. if type(val) == "function" then
  59. pio.pin.setdir(pio.INT, pin)
  60. if pull then pio.pin.setpull(pull or pio.PULLUP, pin) end
  61. --注册引脚中断的处理函数
  62. interruptCallbacks[pin] = val
  63. dirs[pin] = false
  64. return function()
  65. return pio.pin.getval(pin)
  66. end
  67. end
  68. -- 输出模式初始化默认配置
  69. if val ~= nil then
  70. dirs[pin] = true
  71. pio.pin.setdir(val == 1 and pio.OUTPUT1 or pio.OUTPUT, pin)
  72. else
  73. -- 输入模式初始化默认配置
  74. dirs[pin] = false
  75. pio.pin.setdir(pio.INPUT, pin)
  76. if pull then pio.pin.setpull(pull or pio.PULLUP, pin) end
  77. end
  78. -- 返回一个自动切换输入输出模式的函数
  79. return function(val)
  80. val = tonumber(val)
  81. if (not val and dirs[pin]) or (val and not dirs[pin]) then
  82. pio.pin.close(pin)
  83. pio.pin.setdir(val and (val == 1 and pio.OUTPUT1 or pio.OUTPUT) or pio.INPUT, pin)
  84. if not val and pull then pio.pin.setpull(pull or pio.PULLUP, pin) end
  85. dirs[pin] = val and true or false
  86. return val or pio.pin.getval(pin)
  87. end
  88. if val then
  89. pio.pin.setval(val, pin)
  90. return val
  91. else
  92. return pio.pin.getval(pin)
  93. end
  94. end
  95. end
  96. --- 关闭GPIO模式
  97. -- @number pin GPIO,ID
  98. --
  99. -- GPIO 0到GPIO 31表示为pio.P0_0到pio.P0_31
  100. --
  101. -- GPIO 32到GPIO XX表示为pio.P1_0到pio.P1_(XX-32),例如GPIO33 表示为pio.P1_1
  102. -- @usage pins.close(pio.P1_1),关闭GPIO33
  103. function close(pin)
  104. pio.pin.close(pin)
  105. end
  106. rtos.on(rtos.MSG_INT, function(msg)
  107. if interruptCallbacks[msg.int_resnum] == nil then
  108. log.warn('pins.rtos.on', 'warning:rtos.MSG_INT callback nil', msg.int_resnum)
  109. return
  110. end
  111. interruptCallbacks[msg.int_resnum](msg.int_id)
  112. end)