Skip to content

Commit

Permalink
mcp23017: functions to metatable
Browse files Browse the repository at this point in the history
Avoids closures for each module.
  • Loading branch information
nwf committed Oct 25, 2020
1 parent ef35380 commit 5dedff4
Showing 1 changed file with 71 additions and 79 deletions.
150 changes: 71 additions & 79 deletions lua_modules/mcp23017/mcp23017.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
@version 1.0.0
]]

local i2c, string, issetBit, setBit, clearBit, error =
i2c, string, bit.isset, bit.set, bit.clear, error
local isINPUT, isGPB, isHIGH = true, true, true
local i2c, string, issetBit, setBit, clearBit =
i2c, string, bit.isset, bit.set, bit.clear

-- registers (not used registers are commented out)
local MCP23017_IODIRA = 0x00
Expand Down Expand Up @@ -51,12 +50,13 @@ local MCP23017_OLATB = 0x15

-- metatable
local mcp23017 = {
INPUT = isINPUT,
OUTPUT = not isINPUT,
GPA = not isGPB,
GPB = isGPB,
HIGH = isHIGH,
LOW = not isHIGH
-- convenience parameter enumeration names
INPUT = true,
OUTPUT = false,
GPA = false,
GPB = true,
HIGH = true,
LOW = false
}
mcp23017.__index = mcp23017

Expand Down Expand Up @@ -98,13 +98,68 @@ local function checkPinIsInRange(pin)
return pin
end

local function reset(address, i2cId)
writeByte(address, i2cId, MCP23017_IODIRA, 0xFF)
writeByte(address, i2cId, MCP23017_IODIRB, 0xFF)
function mcp23017:writeIODIR(bReg, newByte)
writeByte(self.address, self.i2cId,
bReg and MCP23017_IODIRB or MCP23017_IODIRA, newByte)
end

-- setup device
local function setup(address, i2cId)
function mcp23017:writeGPIO(bReg, newByte)
writeByte(self.address, self.i2cId,
bReg and MCP23017_GPIOB or MCP23017_GPIOA, newByte)
end

function mcp23017:readGPIO(bReg)
return readByte(self.address, self.i2cId,
bReg and MCP23017_GPIOB or MCP23017_GPIOA)
end

-- read pin input
function mcp23017:getPinState(bReg, pin)
return issetBit(readByte(self.address, self.i2cId,
bReg and MCP23017_GPIOB or MCP23017_GPIOA),
checkPinIsInRange(pin))
end

-- set pin to low or high
function mcp23017:setPin(bReg, pin, state)
local a, i = self.address, self.i2cId
local inReq = bReg and MCP23017_GPIOB or MCP23017_GPIOA
local inPin = checkPinIsInRange(pin)
local response = readByte(a, i, inReq)
writeByte(a, i, inReq,
state and setBit(response, inPin) or clearBit(response, inPin))
return true
end

-- set mode for a pin
function mcp23017:setMode(bReg, pin, mode)
local a, i = self.address, self.i2cId
local inReq = bReg and MCP23017_IODIRB or MCP23017_IODIRA
local inPin = checkPinIsInRange(pin)
local response = readByte(a, i, inReq)
writeByte(a, i, inReq,
mode and setBit(response, inPin) or clearBit(response, inPin))
return true
end

-- reset gpio mode
function mcp23017:reset()
local a, i = self.address, self.i2cId
writeByte(a, i, MCP23017_IODIRA, 0xFF)
writeByte(a, i, MCP23017_IODIRB, 0xFF)
end

-- setup internal pullup
function mcp23017:setInternalPullUp(bReg, iByte)
writeByte(self.address, self.i2cId,
bReg and MCP23017_DEFVALB or MCP23017_DEFVALA, iByte)
end

return function(address, i2cId)
local self = setmetatable({}, mcp23017)

self.address = address
self.i2cId = i2cId

-- check device address (0x20 to 0x27)
if (address < 32 or address > 39) then
Expand All @@ -113,73 +168,10 @@ local function setup(address, i2cId)

if (checkDevice(address, i2cId) ~= true) then
error("MCP23017 device on " .. string.format('0x%02X', address) .. " not found")
else
reset(address, i2cId)
return 1
end
end

return function(address, i2cId)
local self = setmetatable({}, mcp23017)

if setup(address, i2cId) then
self.writeIODIR = function(sf, bReg, newByte) -- luacheck: no unused
writeByte(address, i2cId,
bReg == isGPB and MCP23017_IODIRB or MCP23017_IODIRA,
newByte)
end

self.writeGPIO = function(sf, bReg, newByte) -- luacheck: no unused
writeByte(address, i2cId,
bReg == isGPB and MCP23017_GPIOB or MCP23017_GPIOA, newByte)
end

self.readGPIO = function(sf, bReg) -- luacheck: no unused
return readByte(address, i2cId, -- upvals
bReg == isGPB and MCP23017_GPIOB or MCP23017_GPIOA)
end

-- read pin input
self.getPinState = function(sf, bReg, pin) -- luacheck: no unused
return issetBit(readByte(address, i2cId,
bReg == isGPB and MCP23017_GPIOB or MCP23017_GPIOA),
checkPinIsInRange(pin))
end

-- set pin to low or high
self.setPin = function(sf, bReg, pin, state) -- luacheck: no unused
local inReq = bReg == isGPB and MCP23017_GPIOB or MCP23017_GPIOA
local inPin = checkPinIsInRange(pin)
local response = readByte(address, i2cId, inReq)
writeByte(address, i2cId, inReq,
state == isHIGH and setBit(response, inPin) or clearBit(response, inPin))
return true
end

-- set mode for a pin
self.setMode = function(sf, bReg, pin, mode) -- luacheck: no unused
local inReq = bReg == isGPB and MCP23017_IODIRB or MCP23017_IODIRA
local inPin = checkPinIsInRange(pin)
local response = readByte(address, i2cId, inReq)
writeByte(address, i2cId, inReq,
mode == isINPUT and setBit(response, inPin) or clearBit(response, inPin))
return true
end

-- reset gpio mode
self.reset = function(sf) -- luacheck: no unused
reset(address, i2cId)
end

-- setup internal pullup
self.setInternalPullUp = function(sf, bReg, iByte) -- luacheck: no unused
writeByte(address, i2cId,
bReg == isGPB and MCP23017_DEFVALB or MCP23017_DEFVALA, iByte)
end

return self
end
return nil
self:reset(address, i2cId)
return self
end


0 comments on commit 5dedff4

Please sign in to comment.