Skip to content

Commit 0b29887

Browse files
committed
teensy40: cleanup misc items per review comments
1 parent f488e3f commit 0b29887

File tree

1 file changed

+48
-127
lines changed

1 file changed

+48
-127
lines changed

src/machine/machine_mimxrt1062_i2c.go

Lines changed: 48 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -53,24 +53,22 @@ type I2C struct {
5353
// instance is declared (e.g., in the board definition). see the godoc
5454
// comments on type muxSelect for more details.
5555
muxSDA, muxSCL muxSelect
56-
57-
// these are copied from I2CConfig, during (*I2C).Configure(I2CConfig), and
58-
// should be considered read-only for internal reference (i.e., modifying them
59-
// will have no desirable effect).
60-
sda, scl Pin
61-
frequency uint32
62-
63-
// auxiliary state data used internally
64-
configured bool
6556
}
6657

67-
type I2CDirection bool
58+
type i2cDirection bool
6859

6960
const (
70-
DirectionWrite I2CDirection = false
71-
DirectionRead I2CDirection = true
61+
directionWrite i2cDirection = false
62+
directionRead i2cDirection = true
7263
)
7364

65+
func (dir i2cDirection) shift(addr uint16) uint32 {
66+
if addr <<= 1; dir == directionRead {
67+
addr |= 1
68+
}
69+
return uint32(addr) & 0xFF
70+
}
71+
7472
// I2C enumerated types
7573
type (
7674
resultFlag uint32
@@ -156,36 +154,31 @@ const (
156154
func (i2c *I2C) Configure(config I2CConfig) {
157155

158156
// init pins
159-
i2c.sda, i2c.scl = config.getPins()
157+
sda, scl := config.getPins()
160158

161159
// configure the mux and pad control registers
162-
i2c.sda.Configure(PinConfig{Mode: PinModeI2CSDA})
163-
i2c.scl.Configure(PinConfig{Mode: PinModeI2CSCL})
160+
sda.Configure(PinConfig{Mode: PinModeI2CSDA})
161+
scl.Configure(PinConfig{Mode: PinModeI2CSCL})
164162

165163
// configure the mux input selector
166164
i2c.muxSDA.connect()
167165
i2c.muxSCL.connect()
168166

169-
i2c.frequency = config.Frequency
170-
if 0 == i2c.frequency {
171-
i2c.frequency = TWI_FREQ_DEFAULT
167+
freq := config.Frequency
168+
if 0 == freq {
169+
freq = TWI_FREQ_DEFAULT
172170
}
173171

174172
// reset clock and registers, and enable LPI2C module interface
175-
i2c.reset()
176-
177-
i2c.configured = true
173+
i2c.reset(freq)
178174
}
179175

180176
func (i2c I2C) Tx(addr uint16, w, r []byte) error {
181177

182-
// convert address to addressable
183-
a := address7Bit(addr)
184-
185178
// perform transmit transfer
186179
if nil != w {
187180
// generate start condition on bus
188-
if result := i2c.start(a, DirectionWrite); resultSuccess != result {
181+
if result := i2c.start(addr, directionWrite); resultSuccess != result {
189182
return errI2CSignalStartTimeout
190183
}
191184
// ensure TX FIFO is empty
@@ -205,7 +198,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
205198
// perform receive transfer
206199
if nil != r {
207200
// generate (repeated-)start condition on bus
208-
if result := i2c.start(a, DirectionRead); resultSuccess != result {
201+
if result := i2c.start(addr, directionRead); resultSuccess != result {
209202
return errI2CSignalStartTimeout
210203
}
211204
// read received data
@@ -230,11 +223,11 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
230223
// devices with 7-bit addresses, which is the vast majority.
231224
func (i2c I2C) WriteRegister(address uint8, register uint8, data []byte) error {
232225
option := transferOption{
233-
flags: transferDefault, // transfer options bit mask (0 = normal transfer)
234-
peripheral: address7Bit(address), // 7-bit peripheral address
235-
direction: DirectionWrite, // DirectionRead or DirectionWrite
236-
subaddress: uint16(register), // peripheral sub-address (transferred MSB first)
237-
subaddressSize: 1, // byte length of sub-address (maximum = 4 bytes)
226+
flags: transferDefault, // transfer options bit mask (0 = normal transfer)
227+
peripheral: uint16(address), // 7-bit peripheral address
228+
direction: directionWrite, // directionRead or directionWrite
229+
subaddress: uint16(register), // peripheral sub-address (transferred MSB first)
230+
subaddressSize: 1, // byte length of sub-address (maximum = 4 bytes)
238231
}
239232
if result := i2c.controllerTransferPoll(option, data); resultSuccess != result {
240233
return errI2CWriteTimeout
@@ -250,19 +243,19 @@ func (i2c I2C) WriteRegister(address uint8, register uint8, data []byte) error {
250243
// with 7-bit addresses, which is the vast majority.
251244
func (i2c I2C) ReadRegister(address uint8, register uint8, data []byte) error {
252245
option := transferOption{
253-
flags: transferDefault, // transfer options bit mask (0 = normal transfer)
254-
peripheral: address7Bit(address), // 7-bit peripheral address
255-
direction: DirectionRead, // DirectionRead or DirectionWrite
256-
subaddress: uint16(register), // peripheral sub-address (transferred MSB first)
257-
subaddressSize: 1, // byte length of sub-address (maximum = 4 bytes)
246+
flags: transferDefault, // transfer options bit mask (0 = normal transfer)
247+
peripheral: uint16(address), // 7-bit peripheral address
248+
direction: directionRead, // directionRead or directionWrite
249+
subaddress: uint16(register), // peripheral sub-address (transferred MSB first)
250+
subaddressSize: 1, // byte length of sub-address (maximum = 4 bytes)
258251
}
259252
if result := i2c.controllerTransferPoll(option, data); resultSuccess != result {
260253
return errI2CWriteTimeout
261254
}
262255
return nil
263256
}
264257

265-
func (i2c *I2C) reset() {
258+
func (i2c *I2C) reset(freq uint32) {
266259
// disable interface
267260
i2c.Bus.MCR.ClearBits(nxp.LPI2C_MCR_MEN)
268261

@@ -284,7 +277,7 @@ func (i2c *I2C) reset() {
284277
i2c.Bus.MFCR.Set(mfcr)
285278

286279
// configure clock using receiver frequency
287-
i2c.setFrequency(i2c.frequency)
280+
i2c.setFrequency(freq)
288281

289282
// clear reset, and enable the interface
290283
i2c.Bus.MCR.Set(nxp.LPI2C_MCR_MEN)
@@ -392,22 +385,6 @@ func (i2c *I2C) setFrequency(freq uint32) {
392385
}
393386
}
394387

395-
// cycles computes a cycle count for a given time in nanoseconds.
396-
func (i2c *I2C) cycles(width, maxCycles, prescalar uint32) uint32 {
397-
busCycles := 1000000 / (TWI_FREQ_BUS / prescalar / 1000)
398-
cycles := uint32(0)
399-
// search for the cycle count just below the desired glitch width
400-
for (((cycles + 1) * busCycles) < width) && (cycles+1 < maxCycles) {
401-
cycles++
402-
}
403-
// if we end up with zero cycles, then set the filter to a single cycle unless
404-
// the bus clock is greater than 10x the desired glitch width
405-
if (cycles == 0) && (busCycles <= (width * 10)) {
406-
cycles = 1
407-
}
408-
return cycles
409-
}
410-
411388
// checkStatus converts the status register to a resultFlag for return, and
412389
// clears any errors if present.
413390
func (i2c *I2C) checkStatus(status statusFlag) resultFlag {
@@ -478,49 +455,14 @@ func (i2c *I2C) isBusBusy() bool {
478455
return (0 != (status & statusBusBusy)) && (0 == (status & statusBusy))
479456
}
480457

481-
// addressable represents a type that can provide fully-formatted I2C peripheral
482-
// addresses for both read operations and write operations.
483-
type addressable interface {
484-
toRead() uint32
485-
toWrite() uint32
486-
bitSize() uint8
487-
shift(I2CDirection) uint32
488-
}
489-
490-
// address7Bit and address10Bit stores the unshifted original I2C peripheral
491-
// address in an unsigned integral data type and implements the addressable
492-
// interface to reformat addresses as required for read/write operations.
493-
// TODO:
494-
// add 10-bit address support
495-
type (
496-
address7Bit uint8
497-
//address10Bit uint16
498-
)
499-
500-
func (a address7Bit) toRead() uint32 { return uint32(((uint8(a) << 1) | 0x01) & 0xFF) }
501-
func (a address7Bit) toWrite() uint32 { return uint32(((uint8(a) << 1) & 0xFE) & 0xFF) }
502-
func (a address7Bit) bitSize() uint8 { return 7 } // 7-bit addresses
503-
func (a address7Bit) shift(dir I2CDirection) uint32 {
504-
if DirectionWrite == dir {
505-
return a.toWrite()
506-
}
507-
return a.toRead()
508-
}
509-
510-
//func (a address10Bit) toRead() uint32 {}
511-
//func (a address10Bit) toWrite() uint32 {}
512-
//func (a address10Bit) bitSize() uint8 { return 10 } // 10-bit addresses
513-
//func (a address10Bit) shift(dir I2CDirection) uint32 {
514-
//}
515-
516458
// start sends a START signal and peripheral address on the I2C bus.
517459
//
518460
// This function is used to initiate a new controller mode transfer. First, the
519461
// bus state is checked to ensure that another controller is not occupying the
520462
// bus. Then a START signal is transmitted, followed by the 7-bit peripheral
521463
// address. Note that this function does not actually wait until the START and
522464
// address are successfully sent on the bus before returning.
523-
func (i2c *I2C) start(address addressable, dir I2CDirection) resultFlag {
465+
func (i2c *I2C) start(address uint16, dir i2cDirection) resultFlag {
524466
// return an error if the bus is already in use by another controller
525467
if i2c.isBusBusy() {
526468
return resultBusy
@@ -535,7 +477,7 @@ func (i2c *I2C) start(address addressable, dir I2CDirection) resultFlag {
535477
}
536478

537479
// issue start command
538-
i2c.Bus.MTDR.Set(uint32(commandStart) | address.shift(dir))
480+
i2c.Bus.MTDR.Set(uint32(commandStart) | dir.shift(address))
539481
return resultSuccess
540482
}
541483

@@ -633,33 +575,10 @@ func (i2c *I2C) controllerTransmit(txBuffer []byte) resultFlag {
633575
return resultSuccess
634576
}
635577

636-
type commandBuffer struct {
637-
buffer []uint16
638-
curr uint
639-
size uint
640-
}
641-
642-
func newCommandBuffer(size uint) *commandBuffer {
643-
return &commandBuffer{
644-
buffer: make([]uint16, size),
645-
curr: 0,
646-
size: size,
647-
}
648-
}
649-
650-
func (cb *commandBuffer) add(cmd uint16) bool {
651-
if cb.curr < cb.size {
652-
cb.buffer[cb.curr] = cmd
653-
cb.curr++
654-
return true
655-
}
656-
return false
657-
}
658-
659578
type transferOption struct {
660579
flags transferFlag // transfer options bit mask (0 = normal transfer)
661-
peripheral addressable // 7-bit peripheral address
662-
direction I2CDirection // DirectionRead or DirectionWrite
580+
peripheral uint16 // 7-bit peripheral address
581+
direction i2cDirection // directionRead or directionWrite
663582
subaddress uint16 // peripheral sub-address (transferred MSB first)
664583
subaddressSize uint16 // byte length of sub-address (maximum = 4 bytes)
665584
}
@@ -674,45 +593,47 @@ func (i2c *I2C) controllerTransferPoll(option transferOption, data []byte) resul
674593
// turn off auto-stop
675594
i2c.Bus.MCFGR1.ClearBits(nxp.LPI2C_MCFGR1_AUTOSTOP)
676595

677-
cmd := newCommandBuffer(7)
596+
cmd := make([]uint16, 0, 7)
678597
size := len(data)
679598

680599
direction := option.direction
681600
if option.subaddressSize > 0 {
682-
direction = DirectionWrite
601+
direction = directionWrite
683602
}
684603
// peripheral address
685604
if 0 == (option.flags & transferNoStart) {
686-
cmd.add(uint16(uint32(commandStart) | option.peripheral.shift(direction)))
605+
addr := direction.shift(option.peripheral)
606+
cmd = append(cmd, uint16(uint32(commandStart)|addr))
687607
}
688608
// sub-address (MSB-first)
689609
rem := option.subaddressSize
690610
for rem > 0 {
691611
rem--
692-
cmd.add((option.subaddress >> (8 * rem)) & 0xFF)
612+
cmd = append(cmd, (option.subaddress>>(8*rem))&0xFF)
693613
}
694614
// need to send repeated start if switching directions to read
695-
if (0 != size) && (DirectionRead == option.direction) {
696-
if DirectionWrite == direction {
697-
cmd.add(uint16(uint32(commandStart) | option.peripheral.toRead()))
615+
if (0 != size) && (directionRead == option.direction) {
616+
if directionWrite == direction {
617+
addr := directionRead.shift(option.peripheral)
618+
cmd = append(cmd, uint16(uint32(commandStart)|addr))
698619
}
699620
}
700621
// send command buffer
701622
result := resultSuccess
702-
for i := uint(0); i < cmd.curr; i++ {
623+
for _, c := range cmd {
703624
// wait until there is room in the FIFO
704625
if result = i2c.waitForTxReady(); resultSuccess != result {
705626
return result
706627
}
707628
// write byte into LPI2C controller data register
708-
i2c.Bus.MTDR.Set(uint32(cmd.buffer[i]))
629+
i2c.Bus.MTDR.Set(uint32(c))
709630
}
710631
// send data
711-
if option.direction == DirectionWrite && size > 0 {
632+
if option.direction == directionWrite && size > 0 {
712633
result = i2c.controllerTransmit(data)
713634
}
714635
// receive data
715-
if option.direction == DirectionRead && size > 0 {
636+
if option.direction == directionRead && size > 0 {
716637
result = i2c.controllerReceive(data)
717638
}
718639
if resultSuccess != result {

0 commit comments

Comments
 (0)