Skip to content

Commit

Permalink
Control the state of unused pins with "defaultout" and "defaultoe".
Browse files Browse the repository at this point in the history
Unused pins were forced to input state until now. This is still
the default behaviour, but it can be changed with the "defaultout"
and "defaultoe" attributes now:

 <FTDI vendor="0x0403" product="0x6010">
  <Device single="true" pinMask="fffffffe" defaultout="00000001" defaultoe="00000001"/>
 </FTDI>

Both are 8 digit hex numbers like "pinMask" defining the output and
output enable values for the pins in the form

  AABBCCDD

With

  AA = the value for the AD pins
  BB = the value for the AC pins
  CC = the value for the BD pins
  DD = the value for the BC pins

Please note that only pins which are 0 in the pin mask can be
controlled with defaultout and defaultoe.

Example: Set out=1 and oe=1 for BC0
  pinMask="fffffffe"
  defaultout="00000001"
  defaultoe="00000001"
  • Loading branch information
docbacardi committed Apr 27, 2023
1 parent 8e7a75a commit 37d6721
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 27 deletions.
10 changes: 9 additions & 1 deletion iomatrix/templates/io_matrix/ftdi.lua
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,14 @@ function IoMatrix_FTDI:__find_ftdi_devices(atAllDevices, atDeviceAttr)
if aucPinMask~=nil then
self.tLog.debug('Pin mask: %s', table.concat(aucPinMask, ', '))
end
local aucDefaultOut = tDeviceAttr.defaultout
if aucDefaultOut~=nil then
self.tLog.debug('Default out: %s', table.concat(aucDefaultOut, ', '))
end
local aucDefaultOE = tDeviceAttr.defaultoe
if aucDefaultOE~=nil then
self.tLog.debug('Default OE: %s', table.concat(aucDefaultOE, ', '))
end
local fSingle = tDeviceAttr.single

-- Search the complete list of devices.
Expand Down Expand Up @@ -207,7 +215,7 @@ function IoMatrix_FTDI:__find_ftdi_devices(atAllDevices, atDeviceAttr)
break
else
local tFtdi = self.cFTDI2232H(self.tLog)
local tResult = tFtdi:open(tFoundDevice.tListEntry, aucPinMask)
local tResult = tFtdi:open(tFoundDevice.tListEntry, aucPinMask, aucDefaultOut, aucDefaultOE)
if tResult==nil then
self.tLog.error('Failed to open the device [%s].', tFoundDevice.strPrettyPortNumbers)
tAllOk = false
Expand Down
78 changes: 52 additions & 26 deletions iomatrix/templates/io_matrix/ftdi_2232h.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ function Ftdi2232H:_init(tLog)
self.tContextB = nil

self.aucPinMask = nil
self.aucDefaultOut = nil
self.aucDefaultOe = nil

self.atBuffer = {
r = 0,
Expand All @@ -26,12 +28,39 @@ end



function Ftdi2232H:open(tListEntry, aucPinMask)
function Ftdi2232H:open(tListEntry, aucPinMask, aucDefaultOut, aucDefaultOe)
local bit = self.bit

-- The mask defines which pins are in use.
-- Use all pins by default.
if aucPinMask==nil then
aucPinMask = { 0xff, 0xff, 0xff, 0xff }
end
self.aucPinMask = aucPinMask

-- Provide a default output value for unused pins.
-- The default is 0.
if aucDefaultOut==nil then
aucDefaultOut = { 0x00, 0x00, 0x00, 0x00 }
end
self.aucDefaultOut = {
bit.band(aucDefaultOut[1], bit.bxor(aucPinMask[1], 0xff)),
bit.band(aucDefaultOut[2], bit.bxor(aucPinMask[2], 0xff)),
bit.band(aucDefaultOut[3], bit.bxor(aucPinMask[3], 0xff)),
bit.band(aucDefaultOut[4], bit.bxor(aucPinMask[4], 0xff))
}
-- Provide a default output enable value for unused pins.
-- The default is 0.
if aucDefaultOe==nil then
aucDefaultOe = { 0x00, 0x00, 0x00, 0x00 }
end
self.aucDefaultOe = {
bit.band(aucDefaultOe[1], bit.bxor(aucPinMask[1], 0xff)),
bit.band(aucDefaultOe[2], bit.bxor(aucPinMask[2], 0xff)),
bit.band(aucDefaultOe[3], bit.bxor(aucPinMask[3], 0xff)),
bit.band(aucDefaultOe[4], bit.bxor(aucPinMask[4], 0xff))
}

-- Create a context for interface A and B.
local tContextA = self.luaftdi.Context()
local tContextB = self.luaftdi.Context()
Expand Down Expand Up @@ -150,6 +179,8 @@ function Ftdi2232H:__write_pins(uiOe, uiOut)
local luaftdi = self.luaftdi
local bit = self.bit
local aucPinMask = self.aucPinMask
local aucDefaultOut = self.aucDefaultOut
local aucDefaultOe = self.aucDefaultOe

-- print(string.format(
-- '%08x %08x %02x %02x %02x %02x',
Expand All @@ -165,17 +196,18 @@ function Ftdi2232H:__write_pins(uiOe, uiOut)
if bit.bor(aucPinMask[1], aucPinMask[2])~=0x00 then
local aucCmd = {}
if aucPinMask[1]~=0x00 then
table.insert(aucCmd, string.char(luaftdi.SET_BITS_LOW, bit.band(uiOut, 0xff), bit.band(uiOe, 0xff)))
table.insert(aucCmd, string.char(
luaftdi.SET_BITS_LOW,
bit.bor(bit.band(uiOut, 0xff), aucDefaultOut[1]),
bit.bor(bit.band(uiOe, 0xff), aucDefaultOe[1])
))
end
if aucPinMask[2]~=0x00 then
table.insert(
aucCmd,
string.char(
luaftdi.SET_BITS_HIGH,
bit.band(bit.rshift(uiOut, 8), 0xff),
bit.band(bit.rshift(uiOe, 8), 0xff)
)
)
table.insert(aucCmd, string.char(
luaftdi.SET_BITS_HIGH,
bit.bor(bit.band(bit.rshift(uiOut, 8), 0xff), aucDefaultOut[2]),
bit.bor(bit.band(bit.rshift(uiOe, 8), 0xff), aucDefaultOe[2])
))
end
table.insert(aucCmd, string.char(luaftdi.SEND_IMMEDIATE))

Expand All @@ -185,24 +217,18 @@ function Ftdi2232H:__write_pins(uiOe, uiOut)
if bit.bor(aucPinMask[3], aucPinMask[4])~=0x00 then
local aucCmd = {}
if aucPinMask[3]~=0x00 then
table.insert(
aucCmd,
string.char(
luaftdi.SET_BITS_LOW,
bit.band(bit.rshift(uiOut, 16), 0xff),
bit.band(bit.rshift(uiOe, 16), 0xff)
)
)
table.insert(aucCmd, string.char(
luaftdi.SET_BITS_LOW,
bit.bor(bit.band(bit.rshift(uiOut, 16), 0xff), aucDefaultOut[3]),
bit.bor(bit.band(bit.rshift(uiOe, 16), 0xff), aucDefaultOe[3])
))
end
if aucPinMask[4]~=0x00 then
table.insert(
aucCmd,
string.char(
luaftdi.SET_BITS_HIGH,
bit.band(bit.rshift(uiOut, 24), 0xff),
bit.band(bit.rshift(uiOe, 24), 0xff)
)
)
table.insert(aucCmd, string.char(
luaftdi.SET_BITS_HIGH,
bit.bor(bit.band(bit.rshift(uiOut, 24), 0xff), aucDefaultOut[4]),
bit.bor(bit.band(bit.rshift(uiOe, 24), 0xff), aucDefaultOe[4])
))
end
table.insert(aucCmd, string.char(luaftdi.SEND_IMMEDIATE))

Expand Down
88 changes: 88 additions & 0 deletions lua/test_class_iomatrix.lua
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,92 @@ function TestClassIoMatrix.parseCfg_StartElement(tParser, strName, atAttributes)
end
end

local aucDefaultOut
local strDefaultOut = atAttributes['defaultout']
if strDefaultOut~=nil then
-- The "default out" value must be one or more HEX bytes.
-- This means the number of digits must be a multiple of 2.
local sizDefaultOut = string.len(strDefaultOut)
if string.match(strDefaultOut, '^%x+$')==nil then
fOk = nil
aLxpAttr.tLog.error(
'Error in line %d, col %d: the attribute "defaultout" are no valid HEX dump: %s.',
iPosLine,
iPosColumn,
strDefaultOut
)
elseif math.fmod(sizDefaultOut, 2)~=0 then
fOk = nil
aLxpAttr.tLog.error(
'Error in line %d, col %d: the length of "defaultout" must be a multiple of 2. Here it is %d.',
iPosLine,
iPosColumn,
sizDefaultOut
)
else
aucDefaultOut = {}
for uiCnt=1, sizDefaultOut, 2 do
local strData = string.sub(strDefaultOut, uiCnt, uiCnt+1)
local ucData = tonumber(strData, 16)
if ucData==nil then
fOk = nil
aLxpAttr.tLog.error(
'Error in line %d, col %d: the attribute "defaultout" has an invalid HEX digit at offset %d: %s',
iPosLine,
iPosColumn,
uiCnt,
strData
)
break
end
table.insert(aucDefaultOut, ucData)
end
end
end

local aucDefaultOe
local strDefaultOe = atAttributes['defaultoe']
if strDefaultOe~=nil then
-- The "default oe" value must be one or more HEX bytes.
-- This means the number of digits must be a multiple of 2.
local sizDefaultOe = string.len(strDefaultOe)
if string.match(strDefaultOe, '^%x+$')==nil then
fOk = nil
aLxpAttr.tLog.error(
'Error in line %d, col %d: the attribute "defaultoe" are no valid HEX dump: %s.',
iPosLine,
iPosColumn,
strDefaultOe
)
elseif math.fmod(sizDefaultOe, 2)~=0 then
fOk = nil
aLxpAttr.tLog.error(
'Error in line %d, col %d: the length of "defaultoe" must be a multiple of 2. Here it is %d.',
iPosLine,
iPosColumn,
sizDefaultOe
)
else
aucDefaultOe = {}
for uiCnt=1, sizDefaultOe, 2 do
local strData = string.sub(strDefaultOe, uiCnt, uiCnt+1)
local ucData = tonumber(strData, 16)
if ucData==nil then
fOk = nil
aLxpAttr.tLog.error(
'Error in line %d, col %d: the attribute "defaultoe" has an invalid HEX digit at offset %d: %s',
iPosLine,
iPosColumn,
uiCnt,
strData
)
break
end
table.insert(aucDefaultOe, ucData)
end
end
end

local fSingle
local strSingle = atAttributes['single']
if strSingle~=nil then
Expand All @@ -293,6 +379,8 @@ function TestClassIoMatrix.parseCfg_StartElement(tParser, strName, atAttributes)
serial = strSerial,
moduleidx = uiModuleIndex,
pinmask = aucPinMask,
defaultout = aucDefaultOut,
defaultoe = aucDefaultOe,
single = fSingle
}
table.insert(aLxpAttr.tCurrentFTDIDevice, atDevice)
Expand Down

0 comments on commit 37d6721

Please sign in to comment.