Skip to content

Commit

Permalink
attempted crc work and blob usage
Browse files Browse the repository at this point in the history
  • Loading branch information
johntalton committed Jun 6, 2024
1 parent dbd6bf9 commit 7bc9234
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 61 deletions.
13 changes: 5 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
{
"name": "@johntalton/excamera-i2cdriver",
"version": "2.0.0",
"version": "2.0.1",
"type": "module",
"exports": {
".": "./src/i2c-driver.js",
"./capture": "./src/capture-generator/index.js",
"./package.json": "./package.json"
"./capture": "./src/capture-generator/index.js"
},
"files": [ "src/**/*.js"],
"scripts": {
},
"dependencies": {
}
"files": [
"src/**/*.js"
]
}
19 changes: 15 additions & 4 deletions src/crc-16-ccitt.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@

export const INITIAL_CRC = 0xffff

const LOOKUP_TABLE = [
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
Expand Down Expand Up @@ -33,11 +36,19 @@ const LOOKUP_TABLE = [
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
]

export function crcUpdate(startCRC = 0xffff, bufferSource) {
// todo ... validate buffersource
export function crcUpdate(startCRC = INITIAL_CRC, buffer, count) {

const u8 = ArrayBuffer.isView(buffer) ?
new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) :
new Uint8Array(buffer)

// console.log('up', [...u8])

if(u8.byteLength !== count) { throw new Error('count miss-match') }

return [ ...bufferSource ].reduce((crc, value) => {
const idx = ((crc >> 8) ^ value) & 0xff
return [ ...u8 ].reduce((crc, value) => {
const b = value & 0xff
const idx = ((crc >> 8) ^ b) & 0xff
return (LOOKUP_TABLE[idx] ^ (crc << 8)) & 0xffff
}, startCRC)
}
118 changes: 69 additions & 49 deletions src/i2c-driver.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { INITIAL_CRC, crcUpdate } from './crc-16-ccitt.js'
import { ResponseBufferParser } from './parse-buffers.js'

export const EXCAMERA_LABS_VENDOR_ID = 0x0403
Expand Down Expand Up @@ -43,8 +44,8 @@ const COMMAND_REBOOT = 0x5f // '_'

//
const COMMAND_EFF = 0x66 // 'f'
const COMMAND_UHOO = 0x76 // 'v'
const COMMAND_DUBU = 0x77 // 'w'
const COMMAND_UHOO = 0x76 // 'v' start weight
const COMMAND_DUBU = 0x77 // 'w' weight



Expand All @@ -56,6 +57,7 @@ const COMMAND_REPLY_LENGTH_INTERNAL_STATE = 80

export class ExcameraLabsI2CDriverI2C {
#port
#crc = INITIAL_CRC

static from(options) { return new ExcameraLabsI2CDriverI2C(options) }

Expand All @@ -64,18 +66,58 @@ export class ExcameraLabsI2CDriverI2C {
*/
constructor({ port }) { this.#port = port }

async start(dev, readMode) { return ExcameraLabsI2CDriver.start(this.#port, dev, readMode) }
get crc() { return this.#crc }
set crc(crc) { this.#crc = crc }

async start(dev, readMode) {
return ExcameraLabsI2CDriver.start(this.#port, dev, readMode)
// .then(buffer => {
// this.#crc = crcUpdate(this.#crc, Uint8Array.from([ dev ]), 1)
// return buffer
// })
}

async stop() { return ExcameraLabsI2CDriver.stop(this.#port) }
async readACKAll(count) { return ExcameraLabsI2CDriver.readACKAll(this.#port, count) }
async readNACKFinal(count) { return ExcameraLabsI2CDriver.readNACKFinal(this.#port, count) }
async write(count, bufferSource) { return ExcameraLabsI2CDriver.write(this.#port, count, bufferSource) }

async readRegister(dev, addr, count) { return ExcameraLabsI2CDriver.readRegister(this.#port, dev, addr, count) }
async readACKAll(count) {
return ExcameraLabsI2CDriver.readACKAll(this.#port, count)
// .then(buffer => {
// this.#crc = crcUpdate(this.#crc, buffer, count)
// return buffer
// })
}

async readNACKFinal(count) {
return ExcameraLabsI2CDriver.readNACKFinal(this.#port, count)
// .then(buffer => {
// this.#crc = crcUpdate(this.#crc, buffer, count)
// return buffer
// })
}

async write(count, bufferSource) {
return ExcameraLabsI2CDriver.write(this.#port, count, bufferSource)
// .then(state => {
// this.#crc = crcUpdate(this.#crc, bufferSource, count)
// return state
// })
}

async readRegister(dev, addr, count) {
return ExcameraLabsI2CDriver.readRegister(this.#port, dev, addr, count)
// .then(value => {
// const buffer = Uint8Array.from([ value ])
// this.#crc = crcUpdate(this.#crc, buffer, count)
// return value
// })
}

async resetBus() { return ExcameraLabsI2CDriver.resetBus(this.#port) }
async transmitStatusInfo() { return ExcameraLabsI2CDriver.transmitStatusInfo(this.#port) }
}



export class ExcameraLabsI2CDriver {
// static controlFrom({ port }) {
// return {
Expand Down Expand Up @@ -108,12 +150,13 @@ export class ExcameraLabsI2CDriver {
// }
// }

static READ_TIMEOUT_MS = 1000 * 2

static async #streamChunkRead(defaultReader, recvLength) {
const timer = setTimeout(() => {
console.log('timeout')
console.log('read timeout')
defaultReader.cancel()
}, 2000)
}, ExcameraLabsI2CDriver.READ_TIMEOUT_MS)

const scratch = {
accumulator: [],
Expand All @@ -127,19 +170,18 @@ export class ExcameraLabsI2CDriver {
scratch.accumulator.push(value)
scratch.length += value.length

if(scratch.length >= recvLength) {
if(scratch.length === recvLength) { break }

if(scratch.length > recvLength) {
// console.log('OVERSIZE')
break
}
}

clearTimeout(timer)

//console.log({ acc })
// return Uint8Array.from(acc.reduce((flat, a) => {
// return [ ...flat, ...a ]
// }, []))
return (new Blob(scratch.accumulator)).arrayBuffer()
const blob = new Blob(scratch.accumulator)
return blob.arrayBuffer()
}

static async #streamChunkRead_Alt(defaultReader, recvLength) {
Expand Down Expand Up @@ -172,65 +214,43 @@ export class ExcameraLabsI2CDriver {
static async sendRecvTextCommand(port, textCommand, sendBuffer, recvLength) {
const encoder = new TextEncoder()
const encoded = encoder.encode(textCommand, { stream: false })
if(encoded.byteLength !== 1) { throw new Error('unknown text command')}
// if(encoded.byteLength !== 1) { throw new Error('unknown text command')}

const command = encoded[0]
return this.sendRecvCommand(port, command, sendBuffer, recvLength)
}

/**
* @param {SerialPort} port
* @param {ArrayBufferLike|ArrayBufferView} sendBuffer
* @param {ArrayBufferLike|ArrayBufferView|undefined} sendBuffer
*/
static async sendRecvCommand(port, command, sendBuffer, recvLength) {
// console.log('reader state', port.readable.locked, command, sendBuffer, recvLength)
if(port.readable.locked) {
console.warn('locked reader ...')

return new ArrayBuffer(0)
//throw new Error('locked reader')
}
if(port.readable === null) { throw new Error('null readable') }
if(port.readable.locked) { throw new Error('locked reader') }

const defaultWriter = port.writable.getWriter()
const defaultReader = port.readable.getReader()

try {
//
// console.log('write encoded command', command)
await defaultWriter.ready

if(sendBuffer) {
const sb8 = ArrayBuffer.isView(sendBuffer) ?
new Uint8Array(sendBuffer.buffer, sendBuffer.byteOffset, sendBuffer.byteLength) :
new Uint8Array(sendBuffer)

// console.log('sending buffer', sb8)

await defaultWriter.write(Uint8Array.from([ command, ...sb8 ]))
}
else {
await defaultWriter.write(Uint8Array.from([ command ]))
}

//
// console.log('close writer')
// await defaultWriter.ready
// await defaultWriter.close()
const commandBuffer = Uint8Array.from([ command ])
const parts = sendBuffer !== undefined ? [ commandBuffer, sendBuffer ] : [ commandBuffer ]
const blob = new Blob(parts)
const buffer = await blob.arrayBuffer()
await defaultWriter.write(buffer)

// console.log({ recvLength })
if(recvLength === undefined || recvLength <= 0) {
// console.log('expect zero')
return Uint8Array.from([])
return new ArrayBuffer(0)
}

// return await here as otherwise the finally release the lock before the read
return await ExcameraLabsI2CDriver.#streamChunkRead(defaultReader, recvLength)
}
catch(e) {
console.warn(e)
return Uint8Array.from([])
throw e
}
finally {
// console.log('finally')
await defaultWriter.ready

await defaultReader.releaseLock()
Expand Down

0 comments on commit 7bc9234

Please sign in to comment.