UNPKG

i2c-ftdi-d2xx

Version:

i2c protocol implementation with ftdi-d2xx on standard boards that features no level translators on SDA and SCL

114 lines (102 loc) 4.65 kB
const _ = require('lodash'); const TARGET_KIND = { ADDRESS: 'address', REGISTER: 'register', FIELD: 'field' } const sleep = (ms) => { return new Promise((resolve) => { setTimeout(resolve, ms); }); } const generateMask8Bit = (offset, size) => { const mask = parseInt([...Array(8)].map((_, i) => i < 8 - offset && i >= 8 - offset - size ? 1 : 0).join(''), 2); return mask; } const extractData = (data, offset, size) => { const mask = generateMask8Bit(offset, size); const result = (mask & data) >> offset return result; } const insertData = (data, offset, size, read) => { const binaryData = data.toString(2).padStart(8, '0'); const slicedData = binaryData.slice(binaryData.length - size); const shiftedData = parseInt(slicedData, 2) << offset; const mask = generateMask8Bit(offset, size); const fieldData = (mask & shiftedData); const sideData = (~mask & read); return fieldData + sideData; } const addAdressProgressionIndex = (oderedTargets) => { let index = 0; oderedTargets.forEach((r, i) => { if(i === 0) { oderedTargets[i] = {...r, index: index} } else if ((r.address === oderedTargets[i-1].address) || (r.address === oderedTargets[i-1].address + 1)) { oderedTargets[i] = {...r, index: index} } else { index++; oderedTargets[i] = {...r, index: index} } }); } const getNon8BitFieldsFromHybridTarget = (req, regmap) => { const fields = Object.values(regmap).flatMap(r => Object.entries(r.fields)).filter(f => f[1].size < 8).map(f => f[0]); const nonFullFields = Object.keys(req).filter(f => fields.includes(f)) return nonFullFields; } const buildWriteInfo = (req, data, regmap) => { const addresses = Object.entries(req).filter(r => !isNaN(Number(r[0]))).map((r) => {return {target:r[0], address:Number(r[0]), kind: TARGET_KIND.ADDRESS, data: r[1]}}); let registerAddresses = []; let fieldsAddresses = []; if (regmap) { registerKeys = Object.keys(regmap); fieldKeys = Object.entries(regmap).flatMap(g => Object.keys(g[1].fields)); registerNames = Object.entries(req).filter(r => registerKeys.includes(r[0])); fieldNames = Object.entries(req).filter(r => fieldKeys.includes(r[0])); registerAddresses = registerNames.map(r => {return {target: r[0], address: regmap[r[0]].address, kind: TARGET_KIND.REGISTER, data: r[1]}}); fieldsAddresses = fieldNames.map(f => { const fieldRegister = Object.values(regmap).find(r => Object.keys(r.fields).includes(f[0])); const field = fieldRegister.fields[f[0]]; let modifiedData; if(field.size < 8) { modifiedData = insertData(f[1], field.offset, field.size, data[f[0]]); } return {target: f[0], address: fieldRegister.address, kind: TARGET_KIND.FIELD, data: modifiedData ? modifiedData : f[1]}; }) } const orderedRequest = [...addresses, ...registerAddresses, ...fieldsAddresses].sort((a, b) => a.address - b.address); addAdressProgressionIndex(orderedRequest); info = _.groupBy(orderedRequest, (r) => r.index); return info; } const buildReadInfo = (req, regmap) => { const addresses = req.filter(r => !isNaN(Number(r))).map((r) => {return {target:r, address:Number(r), kind: TARGET_KIND.ADDRESS}}); let registerAddresses = []; let fieldsAddresses = []; if (regmap) { registerKeys = Object.keys(regmap); fieldKeys = Object.entries(regmap).flatMap(g => Object.keys(g[1].fields)); registerNames = req.filter(r => registerKeys.includes(r)); fieldNames = req.filter(r => fieldKeys.includes(r)); registerAddresses = registerNames.map(r => {return {target:r, address:regmap[r].address, kind: TARGET_KIND.REGISTER}}); fieldsAddresses = fieldNames.map(f => { const fieldRegister = Object.values(regmap).find(r => Object.keys(r.fields).includes(f)); return {target:f, address:fieldRegister.address, kind: TARGET_KIND.FIELD}; }) } const orderedRequest = [...addresses, ...registerAddresses, ...fieldsAddresses].sort((a, b) => a.address - b.address); addAdressProgressionIndex(orderedRequest); info = _.groupBy(orderedRequest, (r) => r.index); return info; } module.exports.sleep = sleep; module.exports.TARGET_KIND = TARGET_KIND module.exports.generateMask8Bit = generateMask8Bit; module.exports.extractData = extractData; module.exports.insertData = insertData; module.exports.buildWriteInfo = buildWriteInfo; module.exports.buildReadInfo = buildReadInfo; module.exports.getNon8BitFieldsFromHybridTarget = getNon8BitFieldsFromHybridTarget;