machine: make machine.I2C0 and similar objects pointers

This makes it possible to assign I2C objects (machine.I2C0,
machine.I2C1, etc.) without needing to take a pointer.

This is important especially in the future when I2C may be driven using
DMA and the machine.I2C type needs to store some state.
Этот коммит содержится в:
Ayke van Laethem 2021-02-06 12:37:15 +01:00 коммит произвёл Ron Evans
родитель 71bbe93ab2
коммит 90b42799a2
41 изменённых файлов: 129 добавлений и 136 удалений

Просмотреть файл

@ -32,7 +32,7 @@ func init() {
// I2C on the Arduino Nano 33. // I2C on the Arduino Nano 33.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM4_I2CM, Bus: sam.SERCOM4_I2CM,
SERCOM: 4, SERCOM: 4,
} }

Просмотреть файл

@ -23,12 +23,12 @@ func init() {
// I2C on the Circuit Playground Express. // I2C on the Circuit Playground Express.
var ( var (
// external device // external device
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM5_I2CM, Bus: sam.SERCOM5_I2CM,
SERCOM: 5, SERCOM: 5,
} }
// internal device // internal device
I2C1 = I2C{ I2C1 = &I2C{
Bus: sam.SERCOM1_I2CM, Bus: sam.SERCOM1_I2CM,
SERCOM: 1, SERCOM: 1,
} }

Просмотреть файл

@ -75,7 +75,7 @@ const (
// I2C on the Feather M0. // I2C on the Feather M0.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM3_I2CM, Bus: sam.SERCOM3_I2CM,
SERCOM: 3, SERCOM: 3,
} }

Просмотреть файл

@ -28,7 +28,7 @@ func init() {
// I2C on the Feather M4. // I2C on the Feather M4.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM2_I2CM, Bus: sam.SERCOM2_I2CM,
SERCOM: 2, SERCOM: 2,
} }

Просмотреть файл

@ -230,15 +230,15 @@ const (
) )
var ( var (
I2C1 = I2C{ I2C1 = &I2C{
Bus: stm32.I2C1, Bus: stm32.I2C1,
AltFuncSelector: AF4_I2C1_2_3, AltFuncSelector: AF4_I2C1_2_3,
} }
I2C2 = I2C{ I2C2 = &I2C{
Bus: stm32.I2C2, Bus: stm32.I2C2,
AltFuncSelector: AF4_I2C1_2_3, AltFuncSelector: AF4_I2C1_2_3,
} }
I2C3 = I2C{ I2C3 = &I2C{
Bus: stm32.I2C1, Bus: stm32.I2C1,
AltFuncSelector: AF4_I2C1_2_3, AltFuncSelector: AF4_I2C1_2_3,
} }

Просмотреть файл

@ -40,11 +40,11 @@ var (
// I2C on the Grand Central M4 // I2C on the Grand Central M4
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM3_I2CM, Bus: sam.SERCOM3_I2CM,
SERCOM: 3, SERCOM: 3,
} }
I2C1 = I2C{ I2C1 = &I2C{
Bus: sam.SERCOM6_I2CM, Bus: sam.SERCOM6_I2CM,
SERCOM: 6, SERCOM: 6,
} }

Просмотреть файл

@ -10,10 +10,3 @@ var (
Bus: sifive.QSPI1, Bus: sifive.QSPI1,
} }
) )
// I2C on the HiFive1 rev B.
var (
I2C0 = I2C{
Bus: sifive.I2C0,
}
)

Просмотреть файл

@ -75,7 +75,7 @@ const (
// I2C on the ItsyBitsy M0. // I2C on the ItsyBitsy M0.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM3_I2CM, Bus: sam.SERCOM3_I2CM,
SERCOM: 3, SERCOM: 3,
} }

Просмотреть файл

@ -28,7 +28,7 @@ func init() {
// I2C on the ItsyBitsy M4. // I2C on the ItsyBitsy M4.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM2_I2CM, Bus: sam.SERCOM2_I2CM,
SERCOM: 2, SERCOM: 2,
} }

Просмотреть файл

@ -13,16 +13,3 @@ var (
Bus: kendryte.SPI1, Bus: kendryte.SPI1,
} }
) )
// I2C on the MAix Bit.
var (
I2C0 = I2C{
Bus: kendryte.I2C0,
}
I2C1 = I2C{
Bus: kendryte.I2C1,
}
I2C2 = I2C{
Bus: kendryte.I2C2,
}
)

Просмотреть файл

@ -29,7 +29,7 @@ func init() {
// I2C on the MatrixPortal M4 // I2C on the MatrixPortal M4
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM5_I2CM, Bus: sam.SERCOM5_I2CM,
SERCOM: 5, SERCOM: 5,
} }

Просмотреть файл

@ -28,7 +28,7 @@ func init() {
// I2C on the Metro M4. // I2C on the Metro M4.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM5_I2CM, Bus: sam.SERCOM5_I2CM,
SERCOM: 5, SERCOM: 5,
} }

Просмотреть файл

@ -22,7 +22,7 @@ func init() {
// I2C on the P1AM-100. // I2C on the P1AM-100.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM0_I2CM, Bus: sam.SERCOM0_I2CM,
SERCOM: 0, SERCOM: 0,
} }

Просмотреть файл

@ -28,7 +28,7 @@ func init() {
// I2C on the ItsyBitsy M4. // I2C on the ItsyBitsy M4.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM2_I2CM, Bus: sam.SERCOM2_I2CM,
SERCOM: 2, SERCOM: 2,
} }

Просмотреть файл

@ -99,7 +99,7 @@ const (
// I2C on the PyGamer. // I2C on the PyGamer.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM2_I2CM, Bus: sam.SERCOM2_I2CM,
SERCOM: 2, SERCOM: 2,
} }

Просмотреть файл

@ -21,7 +21,7 @@ func init() {
// I2C on the PyPortal. // I2C on the PyPortal.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM5_I2CM, Bus: sam.SERCOM5_I2CM,
SERCOM: 5, SERCOM: 5,
} }

Просмотреть файл

@ -93,7 +93,7 @@ const (
// I2C on the QT Py M0. // I2C on the QT Py M0.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM2_I2CM, Bus: sam.SERCOM2_I2CM,
SERCOM: 2, SERCOM: 2,
} }

Просмотреть файл

@ -74,7 +74,7 @@ const (
) )
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: stm32.I2C1, Bus: stm32.I2C1,
AltFuncSelector: AF4_I2C1_2_3, AltFuncSelector: AF4_I2C1_2_3,
} }

Просмотреть файл

@ -81,7 +81,7 @@ const (
// I2C on the Trinket M0. // I2C on the Trinket M0.
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM2_I2CM, Bus: sam.SERCOM2_I2CM,
SERCOM: 2, SERCOM: 2,
} }

Просмотреть файл

@ -29,12 +29,12 @@ func init() {
// I2C on the Wio Terminal // I2C on the Wio Terminal
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM4_I2CM, Bus: sam.SERCOM4_I2CM,
SERCOM: 4, SERCOM: 4,
} }
I2C1 = I2C{ I2C1 = &I2C{
Bus: sam.SERCOM4_I2CM, Bus: sam.SERCOM4_I2CM,
SERCOM: 4, SERCOM: 4,
} }

Просмотреть файл

@ -81,7 +81,7 @@ const (
// I2C on the Xiao // I2C on the Xiao
var ( var (
I2C0 = I2C{ I2C0 = &I2C{
Bus: sam.SERCOM2_I2CM, Bus: sam.SERCOM2_I2CM,
SERCOM: 2, SERCOM: 2,
} }

Просмотреть файл

@ -29,7 +29,7 @@ var (
// Many I2C-compatible devices are organized in terms of registers. This method // Many I2C-compatible devices are organized in terms of registers. This method
// is a shortcut to easily write to such registers. Also, it only works for // is a shortcut to easily write to such registers. Also, it only works for
// devices with 7-bit addresses, which is the vast majority. // devices with 7-bit addresses, which is the vast majority.
func (i2c I2C) WriteRegister(address uint8, register uint8, data []byte) error { func (i2c *I2C) WriteRegister(address uint8, register uint8, data []byte) error {
buf := make([]uint8, len(data)+1) buf := make([]uint8, len(data)+1)
buf[0] = register buf[0] = register
copy(buf[1:], data) copy(buf[1:], data)
@ -42,6 +42,6 @@ func (i2c I2C) WriteRegister(address uint8, register uint8, data []byte) error {
// Many I2C-compatible devices are organized in terms of registers. This method // Many I2C-compatible devices are organized in terms of registers. This method
// is a shortcut to easily read such registers. Also, it only works for devices // is a shortcut to easily read such registers. Also, it only works for devices
// with 7-bit addresses, which is the vast majority. // with 7-bit addresses, which is the vast majority.
func (i2c I2C) ReadRegister(address uint8, register uint8, data []byte) error { func (i2c *I2C) ReadRegister(address uint8, register uint8, data []byte) error {
return i2c.Tx(uint16(address), []byte{register}, data) return i2c.Tx(uint16(address), []byte{register}, data)
} }

Просмотреть файл

@ -14,7 +14,7 @@ type I2C struct {
} }
// I2C0 is the only I2C interface on most AVRs. // I2C0 is the only I2C interface on most AVRs.
var I2C0 = I2C{} var I2C0 *I2C = nil
// I2CConfig is used to store config info for I2C. // I2CConfig is used to store config info for I2C.
type I2CConfig struct { type I2CConfig struct {
@ -22,7 +22,7 @@ type I2CConfig struct {
} }
// Configure is intended to setup the I2C interface. // Configure is intended to setup the I2C interface.
func (i2c I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
// Default I2C bus speed is 100 kHz. // Default I2C bus speed is 100 kHz.
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = TWI_FREQ_100KHZ config.Frequency = TWI_FREQ_100KHZ
@ -49,7 +49,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
// Tx does a single I2C transaction at the specified address. // Tx does a single I2C transaction at the specified address.
// It clocks out the given address, writes the bytes in w, reads back len(r) // It clocks out the given address, writes the bytes in w, reads back len(r)
// bytes and stores them in r, and generates a stop condition on the bus. // bytes and stores them in r, and generates a stop condition on the bus.
func (i2c I2C) Tx(addr uint16, w, r []byte) error { func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
if len(w) != 0 { if len(w) != 0 {
i2c.start(uint8(addr), true) // start transmission for writing i2c.start(uint8(addr), true) // start transmission for writing
for _, b := range w { for _, b := range w {
@ -70,7 +70,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
} }
// start starts an I2C communication session. // start starts an I2C communication session.
func (i2c I2C) start(address uint8, write bool) { func (i2c *I2C) start(address uint8, write bool) {
// Clear TWI interrupt flag, put start condition on SDA, and enable TWI. // Clear TWI interrupt flag, put start condition on SDA, and enable TWI.
avr.TWCR.Set((avr.TWCR_TWINT | avr.TWCR_TWSTA | avr.TWCR_TWEN)) avr.TWCR.Set((avr.TWCR_TWINT | avr.TWCR_TWSTA | avr.TWCR_TWEN))
@ -87,7 +87,7 @@ func (i2c I2C) start(address uint8, write bool) {
} }
// stop ends an I2C communication session. // stop ends an I2C communication session.
func (i2c I2C) stop() { func (i2c *I2C) stop() {
// Send stop condition. // Send stop condition.
avr.TWCR.Set(avr.TWCR_TWEN | avr.TWCR_TWINT | avr.TWCR_TWSTO) avr.TWCR.Set(avr.TWCR_TWEN | avr.TWCR_TWINT | avr.TWCR_TWSTO)
@ -97,7 +97,7 @@ func (i2c I2C) stop() {
} }
// writeByte writes a single byte to the I2C bus. // writeByte writes a single byte to the I2C bus.
func (i2c I2C) writeByte(data byte) { func (i2c *I2C) writeByte(data byte) {
// Write data to register. // Write data to register.
avr.TWDR.Set(data) avr.TWDR.Set(data)
@ -110,7 +110,7 @@ func (i2c I2C) writeByte(data byte) {
} }
// readByte reads a single byte from the I2C bus. // readByte reads a single byte from the I2C bus.
func (i2c I2C) readByte() byte { func (i2c *I2C) readByte() byte {
// Clear TWI interrupt flag and enable TWI. // Clear TWI interrupt flag and enable TWI.
avr.TWCR.Set(avr.TWCR_TWEN | avr.TWCR_TWINT | avr.TWCR_TWEA) avr.TWCR.Set(avr.TWCR_TWEN | avr.TWCR_TWINT | avr.TWCR_TWEA)

Просмотреть файл

@ -669,7 +669,7 @@ const (
const i2cTimeout = 1000 const i2cTimeout = 1000
// Configure is intended to setup the I2C interface. // Configure is intended to setup the I2C interface.
func (i2c I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
// Default I2C bus speed is 100 kHz. // Default I2C bus speed is 100 kHz.
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = TWI_FREQ_100KHZ config.Frequency = TWI_FREQ_100KHZ
@ -725,7 +725,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
} }
// SetBaudRate sets the communication speed for the I2C. // SetBaudRate sets the communication speed for the I2C.
func (i2c I2C) SetBaudRate(br uint32) { func (i2c *I2C) SetBaudRate(br uint32) {
// Synchronous arithmetic baudrate, via Arduino SAMD implementation: // Synchronous arithmetic baudrate, via Arduino SAMD implementation:
// SystemCoreClock / ( 2 * baudrate) - 5 - (((SystemCoreClock / 1000000) * WIRE_RISE_TIME_NANOSECONDS) / (2 * 1000)); // SystemCoreClock / ( 2 * baudrate) - 5 - (((SystemCoreClock / 1000000) * WIRE_RISE_TIME_NANOSECONDS) / (2 * 1000));
baud := CPUFrequency()/(2*br) - 5 - (((CPUFrequency() / 1000000) * riseTimeNanoseconds) / (2 * 1000)) baud := CPUFrequency()/(2*br) - 5 - (((CPUFrequency() / 1000000) * riseTimeNanoseconds) / (2 * 1000))
@ -735,7 +735,7 @@ func (i2c I2C) SetBaudRate(br uint32) {
// Tx does a single I2C transaction at the specified address. // Tx does a single I2C transaction at the specified address.
// It clocks out the given address, writes the bytes in w, reads back len(r) // It clocks out the given address, writes the bytes in w, reads back len(r)
// bytes and stores them in r, and generates a stop condition on the bus. // bytes and stores them in r, and generates a stop condition on the bus.
func (i2c I2C) Tx(addr uint16, w, r []byte) error { func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
var err error var err error
if len(w) != 0 { if len(w) != 0 {
// send start/address for write // send start/address for write
@ -812,7 +812,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
} }
// WriteByte writes a single byte to the I2C bus. // WriteByte writes a single byte to the I2C bus.
func (i2c I2C) WriteByte(data byte) error { func (i2c *I2C) WriteByte(data byte) error {
// Send data byte // Send data byte
i2c.Bus.DATA.Set(data) i2c.Bus.DATA.Set(data)
@ -837,7 +837,7 @@ func (i2c I2C) WriteByte(data byte) error {
} }
// sendAddress sends the address and start signal // sendAddress sends the address and start signal
func (i2c I2C) sendAddress(address uint16, write bool) error { func (i2c *I2C) sendAddress(address uint16, write bool) error {
data := (address << 1) data := (address << 1)
if !write { if !write {
data |= 1 // set read flag data |= 1 // set read flag
@ -857,7 +857,7 @@ func (i2c I2C) sendAddress(address uint16, write bool) error {
return nil return nil
} }
func (i2c I2C) signalStop() error { func (i2c *I2C) signalStop() error {
i2c.Bus.CTRLB.SetBits(wireCmdStop << sam.SERCOM_I2CM_CTRLB_CMD_Pos) // Stop command i2c.Bus.CTRLB.SetBits(wireCmdStop << sam.SERCOM_I2CM_CTRLB_CMD_Pos) // Stop command
timeout := i2cTimeout timeout := i2cTimeout
for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) { for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) {
@ -869,7 +869,7 @@ func (i2c I2C) signalStop() error {
return nil return nil
} }
func (i2c I2C) signalRead() error { func (i2c *I2C) signalRead() error {
i2c.Bus.CTRLB.SetBits(wireCmdRead << sam.SERCOM_I2CM_CTRLB_CMD_Pos) // Read command i2c.Bus.CTRLB.SetBits(wireCmdRead << sam.SERCOM_I2CM_CTRLB_CMD_Pos) // Read command
timeout := i2cTimeout timeout := i2cTimeout
for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) { for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) {
@ -881,7 +881,7 @@ func (i2c I2C) signalRead() error {
return nil return nil
} }
func (i2c I2C) readByte() byte { func (i2c *I2C) readByte() byte {
for !i2c.Bus.INTFLAG.HasBits(sam.SERCOM_I2CM_INTFLAG_SB) { for !i2c.Bus.INTFLAG.HasBits(sam.SERCOM_I2CM_INTFLAG_SB) {
} }
return byte(i2c.Bus.DATA.Get()) return byte(i2c.Bus.DATA.Get())

Просмотреть файл

@ -1104,7 +1104,7 @@ const (
const i2cTimeout = 1000 const i2cTimeout = 1000
// Configure is intended to setup the I2C interface. // Configure is intended to setup the I2C interface.
func (i2c I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
// Default I2C bus speed is 100 kHz. // Default I2C bus speed is 100 kHz.
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = TWI_FREQ_100KHZ config.Frequency = TWI_FREQ_100KHZ
@ -1163,7 +1163,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
} }
// SetBaudRate sets the communication speed for the I2C. // SetBaudRate sets the communication speed for the I2C.
func (i2c I2C) SetBaudRate(br uint32) { func (i2c *I2C) SetBaudRate(br uint32) {
// Synchronous arithmetic baudrate, via Adafruit SAMD51 implementation: // Synchronous arithmetic baudrate, via Adafruit SAMD51 implementation:
// sercom->I2CM.BAUD.bit.BAUD = SERCOM_FREQ_REF / ( 2 * baudrate) - 1 ; // sercom->I2CM.BAUD.bit.BAUD = SERCOM_FREQ_REF / ( 2 * baudrate) - 1 ;
baud := SERCOM_FREQ_REF/(2*br) - 1 baud := SERCOM_FREQ_REF/(2*br) - 1
@ -1173,7 +1173,7 @@ func (i2c I2C) SetBaudRate(br uint32) {
// Tx does a single I2C transaction at the specified address. // Tx does a single I2C transaction at the specified address.
// It clocks out the given address, writes the bytes in w, reads back len(r) // It clocks out the given address, writes the bytes in w, reads back len(r)
// bytes and stores them in r, and generates a stop condition on the bus. // bytes and stores them in r, and generates a stop condition on the bus.
func (i2c I2C) Tx(addr uint16, w, r []byte) error { func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
var err error var err error
if len(w) != 0 { if len(w) != 0 {
// send start/address for write // send start/address for write
@ -1250,7 +1250,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
} }
// WriteByte writes a single byte to the I2C bus. // WriteByte writes a single byte to the I2C bus.
func (i2c I2C) WriteByte(data byte) error { func (i2c *I2C) WriteByte(data byte) error {
// Send data byte // Send data byte
i2c.Bus.DATA.Set(data) i2c.Bus.DATA.Set(data)
@ -1275,7 +1275,7 @@ func (i2c I2C) WriteByte(data byte) error {
} }
// sendAddress sends the address and start signal // sendAddress sends the address and start signal
func (i2c I2C) sendAddress(address uint16, write bool) error { func (i2c *I2C) sendAddress(address uint16, write bool) error {
data := (address << 1) data := (address << 1)
if !write { if !write {
data |= 1 // set read flag data |= 1 // set read flag
@ -1295,7 +1295,7 @@ func (i2c I2C) sendAddress(address uint16, write bool) error {
return nil return nil
} }
func (i2c I2C) signalStop() error { func (i2c *I2C) signalStop() error {
i2c.Bus.CTRLB.SetBits(wireCmdStop << sam.SERCOM_I2CM_CTRLB_CMD_Pos) // Stop command i2c.Bus.CTRLB.SetBits(wireCmdStop << sam.SERCOM_I2CM_CTRLB_CMD_Pos) // Stop command
timeout := i2cTimeout timeout := i2cTimeout
for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) { for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) {
@ -1307,7 +1307,7 @@ func (i2c I2C) signalStop() error {
return nil return nil
} }
func (i2c I2C) signalRead() error { func (i2c *I2C) signalRead() error {
i2c.Bus.CTRLB.SetBits(wireCmdRead << sam.SERCOM_I2CM_CTRLB_CMD_Pos) // Read command i2c.Bus.CTRLB.SetBits(wireCmdRead << sam.SERCOM_I2CM_CTRLB_CMD_Pos) // Read command
timeout := i2cTimeout timeout := i2cTimeout
for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) { for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) {
@ -1319,7 +1319,7 @@ func (i2c I2C) signalRead() error {
return nil return nil
} }
func (i2c I2C) readByte() byte { func (i2c *I2C) readByte() byte {
for !i2c.Bus.INTFLAG.HasBits(sam.SERCOM_I2CM_INTFLAG_SB) { for !i2c.Bus.INTFLAG.HasBits(sam.SERCOM_I2CM_INTFLAG_SB) {
} }
return byte(i2c.Bus.DATA.Get()) return byte(i2c.Bus.DATA.Get())

Просмотреть файл

@ -5,6 +5,7 @@ package machine
import ( import (
"device/sifive" "device/sifive"
"runtime/interrupt" "runtime/interrupt"
"unsafe"
) )
func CPUFrequency() uint32 { func CPUFrequency() uint32 {
@ -185,9 +186,13 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// I2C on the FE310-G002. // I2C on the FE310-G002.
type I2C struct { type I2C struct {
Bus *sifive.I2C_Type Bus sifive.I2C_Type
} }
var (
I2C0 = (*I2C)(unsafe.Pointer(sifive.I2C0))
)
// I2CConfig is used to store config info for I2C. // I2CConfig is used to store config info for I2C.
type I2CConfig struct { type I2CConfig struct {
Frequency uint32 Frequency uint32
@ -196,7 +201,7 @@ type I2CConfig struct {
} }
// Configure is intended to setup the I2C interface. // Configure is intended to setup the I2C interface.
func (i2c I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
var i2cClockFrequency uint32 = 32000000 var i2cClockFrequency uint32 = 32000000
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = TWI_FREQ_100KHZ config.Frequency = TWI_FREQ_100KHZ
@ -228,7 +233,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
// Tx does a single I2C transaction at the specified address. // Tx does a single I2C transaction at the specified address.
// It clocks out the given address, writes the bytes in w, reads back len(r) // It clocks out the given address, writes the bytes in w, reads back len(r)
// bytes and stores them in r, and generates a stop condition on the bus. // bytes and stores them in r, and generates a stop condition on the bus.
func (i2c I2C) Tx(addr uint16, w, r []byte) error { func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
var err error var err error
if len(w) != 0 { if len(w) != 0 {
// send start/address for write // send start/address for write
@ -276,7 +281,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
} }
// Writes a single byte to the I2C bus. // Writes a single byte to the I2C bus.
func (i2c I2C) writeByte(data byte) error { func (i2c *I2C) writeByte(data byte) error {
// Send data byte // Send data byte
i2c.Bus.TXR_RXR.Set(uint32(data)) i2c.Bus.TXR_RXR.Set(uint32(data))
@ -295,7 +300,7 @@ func (i2c I2C) writeByte(data byte) error {
} }
// Reads a single byte from the I2C bus. // Reads a single byte from the I2C bus.
func (i2c I2C) readByte() byte { func (i2c *I2C) readByte() byte {
i2c.Bus.CR_SR.Set(sifive.I2C_CR_RD) i2c.Bus.CR_SR.Set(sifive.I2C_CR_RD)
// wait until transmission complete // wait until transmission complete
@ -306,7 +311,7 @@ func (i2c I2C) readByte() byte {
} }
// Sends the address and start signal. // Sends the address and start signal.
func (i2c I2C) sendAddress(address uint16, write bool) error { func (i2c *I2C) sendAddress(address uint16, write bool) error {
data := (address << 1) data := (address << 1)
if !write { if !write {
data |= 1 // set read flag in transmit register data |= 1 // set read flag in transmit register

Просмотреть файл

@ -6,7 +6,7 @@ package machine
var ( var (
SPI0 = SPI{0} SPI0 = SPI{0}
I2C0 = I2C{0} I2C0 = &I2C{0}
UART0 = UART{0} UART0 = UART{0}
) )
@ -115,13 +115,13 @@ type I2CConfig struct {
} }
// Configure is intended to setup the I2C interface. // Configure is intended to setup the I2C interface.
func (i2c I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
i2cConfigure(i2c.Bus, config.SCL, config.SDA) i2cConfigure(i2c.Bus, config.SCL, config.SDA)
return nil return nil
} }
// Tx does a single I2C transaction at the specified address. // Tx does a single I2C transaction at the specified address.
func (i2c I2C) Tx(addr uint16, w, r []byte) error { func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
i2cTransfer(i2c.Bus, &w[0], len(w), &r[0], len(r)) i2cTransfer(i2c.Bus, &w[0], len(w), &r[0], len(r))
// TODO: do something with the returned error code. // TODO: do something with the returned error code.
return nil return nil

Просмотреть файл

@ -7,6 +7,7 @@ import (
"device/riscv" "device/riscv"
"errors" "errors"
"runtime/interrupt" "runtime/interrupt"
"unsafe"
) )
func CPUFrequency() uint32 { func CPUFrequency() uint32 {
@ -493,9 +494,15 @@ func (spi SPI) Transfer(w byte) (byte, error) {
// I2C on the K210. // I2C on the K210.
type I2C struct { type I2C struct {
Bus *kendryte.I2C_Type Bus kendryte.I2C_Type
} }
var (
I2C0 = (*I2C)(unsafe.Pointer(kendryte.I2C0))
I2C1 = (*I2C)(unsafe.Pointer(kendryte.I2C1))
I2C2 = (*I2C)(unsafe.Pointer(kendryte.I2C2))
)
// I2CConfig is used to store config info for I2C. // I2CConfig is used to store config info for I2C.
type I2CConfig struct { type I2CConfig struct {
Frequency uint32 Frequency uint32
@ -504,7 +511,7 @@ type I2CConfig struct {
} }
// Configure is intended to setup the I2C interface. // Configure is intended to setup the I2C interface.
func (i2c I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = TWI_FREQ_100KHZ config.Frequency = TWI_FREQ_100KHZ
@ -518,7 +525,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
// Enable APB0 clock. // Enable APB0 clock.
kendryte.SYSCTL.CLK_EN_CENT.SetBits(kendryte.SYSCTL_CLK_EN_CENT_APB0_CLK_EN) kendryte.SYSCTL.CLK_EN_CENT.SetBits(kendryte.SYSCTL_CLK_EN_CENT_APB0_CLK_EN)
switch i2c.Bus { switch &i2c.Bus {
case kendryte.I2C0: case kendryte.I2C0:
// Initialize I2C0 clock. // Initialize I2C0 clock.
kendryte.SYSCTL.CLK_EN_PERI.SetBits(kendryte.SYSCTL_CLK_EN_PERI_I2C0_CLK_EN) kendryte.SYSCTL.CLK_EN_PERI.SetBits(kendryte.SYSCTL_CLK_EN_PERI_I2C0_CLK_EN)
@ -567,7 +574,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
// Tx does a single I2C transaction at the specified address. // Tx does a single I2C transaction at the specified address.
// It clocks out the given address, writes the bytes in w, reads back len(r) // It clocks out the given address, writes the bytes in w, reads back len(r)
// bytes and stores them in r, and generates a stop condition on the bus. // bytes and stores them in r, and generates a stop condition on the bus.
func (i2c I2C) Tx(addr uint16, w, r []byte) error { func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
// Set peripheral address. // Set peripheral address.
i2c.Bus.TAR.Set(uint32(addr)) i2c.Bus.TAR.Set(uint32(addr))
// Enable controller. // Enable controller.

Просмотреть файл

@ -6,6 +6,7 @@ import (
"device/nrf" "device/nrf"
"errors" "errors"
"runtime/interrupt" "runtime/interrupt"
"unsafe"
) )
var ( var (
@ -203,13 +204,13 @@ func (uart *UART) handleInterrupt(interrupt.Interrupt) {
// I2C on the NRF. // I2C on the NRF.
type I2C struct { type I2C struct {
Bus *nrf.TWI_Type Bus nrf.TWI_Type
} }
// There are 2 I2C interfaces on the NRF. // There are 2 I2C interfaces on the NRF.
var ( var (
I2C0 = I2C{Bus: nrf.TWI0} I2C0 = (*I2C)(unsafe.Pointer(nrf.TWI0))
I2C1 = I2C{Bus: nrf.TWI1} I2C1 = (*I2C)(unsafe.Pointer(nrf.TWI1))
) )
// I2CConfig is used to store config info for I2C. // I2CConfig is used to store config info for I2C.
@ -220,7 +221,7 @@ type I2CConfig struct {
} }
// Configure is intended to setup the I2C interface. // Configure is intended to setup the I2C interface.
func (i2c I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
// Default I2C bus speed is 100 kHz. // Default I2C bus speed is 100 kHz.
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = TWI_FREQ_100KHZ config.Frequency = TWI_FREQ_100KHZ
@ -261,7 +262,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
// Tx does a single I2C transaction at the specified address. // Tx does a single I2C transaction at the specified address.
// It clocks out the given address, writes the bytes in w, reads back len(r) // It clocks out the given address, writes the bytes in w, reads back len(r)
// bytes and stores them in r, and generates a stop condition on the bus. // bytes and stores them in r, and generates a stop condition on the bus.
func (i2c I2C) Tx(addr uint16, w, r []byte) (err error) { func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
i2c.Bus.ADDRESS.Set(uint32(addr)) i2c.Bus.ADDRESS.Set(uint32(addr))
if len(w) != 0 { if len(w) != 0 {
@ -299,7 +300,7 @@ cleanUp:
// signalStop sends a stop signal when writing or tells the I2C peripheral that // signalStop sends a stop signal when writing or tells the I2C peripheral that
// it must generate a stop condition after the next character is retrieved when // it must generate a stop condition after the next character is retrieved when
// reading. // reading.
func (i2c I2C) signalStop() { func (i2c *I2C) signalStop() {
i2c.Bus.TASKS_STOP.Set(1) i2c.Bus.TASKS_STOP.Set(1)
for i2c.Bus.EVENTS_STOPPED.Get() == 0 { for i2c.Bus.EVENTS_STOPPED.Get() == 0 {
} }
@ -307,7 +308,7 @@ func (i2c I2C) signalStop() {
} }
// writeByte writes a single byte to the I2C bus. // writeByte writes a single byte to the I2C bus.
func (i2c I2C) writeByte(data byte) error { func (i2c *I2C) writeByte(data byte) error {
i2c.Bus.TXD.Set(uint32(data)) i2c.Bus.TXD.Set(uint32(data))
for i2c.Bus.EVENTS_TXDSENT.Get() == 0 { for i2c.Bus.EVENTS_TXDSENT.Get() == 0 {
if e := i2c.Bus.EVENTS_ERROR.Get(); e != 0 { if e := i2c.Bus.EVENTS_ERROR.Get(); e != 0 {
@ -320,7 +321,7 @@ func (i2c I2C) writeByte(data byte) error {
} }
// readByte reads a single byte from the I2C bus. // readByte reads a single byte from the I2C bus.
func (i2c I2C) readByte() (byte, error) { func (i2c *I2C) readByte() (byte, error) {
for i2c.Bus.EVENTS_RXDREADY.Get() == 0 { for i2c.Bus.EVENTS_RXDREADY.Get() == 0 {
if e := i2c.Bus.EVENTS_ERROR.Get(); e != 0 { if e := i2c.Bus.EVENTS_ERROR.Get(); e != 0 {
i2c.Bus.EVENTS_ERROR.Set(0) i2c.Bus.EVENTS_ERROR.Set(0)

Просмотреть файл

@ -24,7 +24,7 @@ func (uart UART) setPins(tx, rx Pin) {
nrf.UART0.PSELRXD.Set(uint32(rx)) nrf.UART0.PSELRXD.Set(uint32(rx))
} }
func (i2c I2C) setPins(scl, sda Pin) { func (i2c *I2C) setPins(scl, sda Pin) {
i2c.Bus.PSELSCL.Set(uint32(scl)) i2c.Bus.PSELSCL.Set(uint32(scl))
i2c.Bus.PSELSDA.Set(uint32(sda)) i2c.Bus.PSELSDA.Set(uint32(sda))
} }

Просмотреть файл

@ -56,7 +56,7 @@ func (uart UART) setPins(tx, rx Pin) {
nrf.UART0.PSELRXD.Set(uint32(rx)) nrf.UART0.PSELRXD.Set(uint32(rx))
} }
func (i2c I2C) setPins(scl, sda Pin) { func (i2c *I2C) setPins(scl, sda Pin) {
i2c.Bus.PSELSCL.Set(uint32(scl)) i2c.Bus.PSELSCL.Set(uint32(scl))
i2c.Bus.PSELSDA.Set(uint32(sda)) i2c.Bus.PSELSDA.Set(uint32(sda))
} }

Просмотреть файл

@ -76,7 +76,7 @@ func (uart UART) setPins(tx, rx Pin) {
nrf.UART0.PSEL.RXD.Set(uint32(rx)) nrf.UART0.PSEL.RXD.Set(uint32(rx))
} }
func (i2c I2C) setPins(scl, sda Pin) { func (i2c *I2C) setPins(scl, sda Pin) {
i2c.Bus.PSEL.SCL.Set(uint32(scl)) i2c.Bus.PSEL.SCL.Set(uint32(scl))
i2c.Bus.PSEL.SDA.Set(uint32(sda)) i2c.Bus.PSEL.SDA.Set(uint32(sda))
} }

Просмотреть файл

@ -72,7 +72,7 @@ func (uart UART) setPins(tx, rx Pin) {
nrf.UART0.PSEL.RXD.Set(uint32(rx)) nrf.UART0.PSEL.RXD.Set(uint32(rx))
} }
func (i2c I2C) setPins(scl, sda Pin) { func (i2c *I2C) setPins(scl, sda Pin) {
i2c.Bus.PSEL.SCL.Set(uint32(scl)) i2c.Bus.PSEL.SCL.Set(uint32(scl))
i2c.Bus.PSEL.SDA.Set(uint32(sda)) i2c.Bus.PSEL.SDA.Set(uint32(sda))
} }

Просмотреть файл

@ -29,7 +29,7 @@ const (
flagMSL = 0x00100001 flagMSL = 0x00100001
) )
func (i2c I2C) hasFlag(flag uint32) bool { func (i2c *I2C) hasFlag(flag uint32) bool {
const mask = 0x0000FFFF const mask = 0x0000FFFF
if uint8(flag>>16) == 1 { if uint8(flag>>16) == 1 {
return i2c.Bus.SR1.HasBits(flag & mask) return i2c.Bus.SR1.HasBits(flag & mask)
@ -38,18 +38,18 @@ func (i2c I2C) hasFlag(flag uint32) bool {
} }
} }
func (i2c I2C) clearFlag(flag uint32) { func (i2c *I2C) clearFlag(flag uint32) {
const mask = 0x0000FFFF const mask = 0x0000FFFF
i2c.Bus.SR1.Set(^(flag & mask)) i2c.Bus.SR1.Set(^(flag & mask))
} }
// clearFlagADDR reads both status registers to clear any pending ADDR flags. // clearFlagADDR reads both status registers to clear any pending ADDR flags.
func (i2c I2C) clearFlagADDR() { func (i2c *I2C) clearFlagADDR() {
i2c.Bus.SR1.Get() i2c.Bus.SR1.Get()
i2c.Bus.SR2.Get() i2c.Bus.SR2.Get()
} }
func (i2c I2C) waitForFlag(flag uint32, set bool) bool { func (i2c *I2C) waitForFlag(flag uint32, set bool) bool {
const tryMax = 10000 const tryMax = 10000
hasFlag := false hasFlag := false
for i := 0; !hasFlag && i < tryMax; i++ { for i := 0; !hasFlag && i < tryMax; i++ {
@ -58,7 +58,7 @@ func (i2c I2C) waitForFlag(flag uint32, set bool) bool {
return hasFlag return hasFlag
} }
func (i2c I2C) waitForFlagOrError(flag uint32, set bool) bool { func (i2c *I2C) waitForFlagOrError(flag uint32, set bool) bool {
const tryMax = 10000 const tryMax = 10000
hasFlag := false hasFlag := false
for i := 0; !hasFlag && i < tryMax; i++ { for i := 0; !hasFlag && i < tryMax; i++ {
@ -107,7 +107,7 @@ type I2CConfig struct {
} }
// Configure is intended to setup the STM32 I2C interface. // Configure is intended to setup the STM32 I2C interface.
func (i2c I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
// The following is the required sequence in controller mode. // The following is the required sequence in controller mode.
// 1. Program the peripheral input clock in I2C_CR2 Register in order to // 1. Program the peripheral input clock in I2C_CR2 Register in order to
@ -157,7 +157,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
return nil return nil
} }
func (i2c I2C) Tx(addr uint16, w, r []byte) error { func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
if err := i2c.controllerTransmit(addr, w); nil != err { if err := i2c.controllerTransmit(addr, w); nil != err {
return err return err
@ -172,7 +172,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
return nil return nil
} }
func (i2c I2C) controllerTransmit(addr uint16, w []byte) error { func (i2c *I2C) controllerTransmit(addr uint16, w []byte) error {
if !i2c.waitForFlag(flagBUSY, false) { if !i2c.waitForFlag(flagBUSY, false) {
return errI2CBusReadyTimeout return errI2CBusReadyTimeout
@ -224,7 +224,7 @@ func (i2c I2C) controllerTransmit(addr uint16, w []byte) error {
return nil return nil
} }
func (i2c I2C) controllerRequestWrite(addr uint16, option transferOption) error { func (i2c *I2C) controllerRequestWrite(addr uint16, option transferOption) error {
if frameFirstAndLast == option || frameFirst == option || frameNoOption == option { if frameFirstAndLast == option || frameFirst == option || frameNoOption == option {
// generate start condition // generate start condition
@ -250,7 +250,7 @@ func (i2c I2C) controllerRequestWrite(addr uint16, option transferOption) error
return nil return nil
} }
func (i2c I2C) controllerReceive(addr uint16, r []byte) error { func (i2c *I2C) controllerReceive(addr uint16, r []byte) error {
if !i2c.waitForFlag(flagBUSY, false) { if !i2c.waitForFlag(flagBUSY, false) {
return errI2CBusReadyTimeout return errI2CBusReadyTimeout
@ -400,7 +400,7 @@ func (i2c I2C) controllerReceive(addr uint16, r []byte) error {
return nil return nil
} }
func (i2c I2C) controllerRequestRead(addr uint16, option transferOption) error { func (i2c *I2C) controllerRequestRead(addr uint16, option transferOption) error {
// enable ACK // enable ACK
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_ACK) i2c.Bus.CR1.SetBits(stm32.I2C_CR1_ACK)

Просмотреть файл

@ -46,7 +46,7 @@ type I2CConfig struct {
SDA Pin SDA Pin
} }
func (i2c I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
// disable I2C interface before any configuration changes // disable I2C interface before any configuration changes
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_PE) i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_PE)
@ -81,7 +81,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
return nil return nil
} }
func (i2c I2C) Tx(addr uint16, w, r []byte) error { func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
if len(w) > 0 { if len(w) > 0 {
if err := i2c.controllerTransmit(addr, w); nil != err { if err := i2c.controllerTransmit(addr, w); nil != err {
return err return err
@ -97,12 +97,12 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
return nil return nil
} }
func (i2c I2C) configurePins(config I2CConfig) { func (i2c *I2C) configurePins(config I2CConfig) {
config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, i2c.AltFuncSelector) config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, i2c.AltFuncSelector)
config.SDA.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSDA}, i2c.AltFuncSelector) config.SDA.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSDA}, i2c.AltFuncSelector)
} }
func (i2c I2C) controllerTransmit(addr uint16, w []byte) error { func (i2c *I2C) controllerTransmit(addr uint16, w []byte) error {
start := ticks() start := ticks()
if !i2c.waitOnFlagUntilTimeout(flagBUSY, false, start) { if !i2c.waitOnFlagUntilTimeout(flagBUSY, false, start) {
@ -161,7 +161,7 @@ func (i2c I2C) controllerTransmit(addr uint16, w []byte) error {
return nil return nil
} }
func (i2c I2C) controllerReceive(addr uint16, r []byte) error { func (i2c *I2C) controllerReceive(addr uint16, r []byte) error {
start := ticks() start := ticks()
if !i2c.waitOnFlagUntilTimeout(flagBUSY, false, start) { if !i2c.waitOnFlagUntilTimeout(flagBUSY, false, start) {
@ -220,7 +220,7 @@ func (i2c I2C) controllerReceive(addr uint16, r []byte) error {
return nil return nil
} }
func (i2c I2C) waitOnFlagUntilTimeout(flag uint32, set bool, startTicks int64) bool { func (i2c *I2C) waitOnFlagUntilTimeout(flag uint32, set bool, startTicks int64) bool {
for i2c.hasFlag(flag) != set { for i2c.hasFlag(flag) != set {
if (ticks() - startTicks) > TIMEOUT_TICKS { if (ticks() - startTicks) > TIMEOUT_TICKS {
return false return false
@ -229,7 +229,7 @@ func (i2c I2C) waitOnFlagUntilTimeout(flag uint32, set bool, startTicks int64) b
return true return true
} }
func (i2c I2C) waitOnRXNEFlagUntilTimeout(startTicks int64) bool { func (i2c *I2C) waitOnRXNEFlagUntilTimeout(startTicks int64) bool {
for !i2c.hasFlag(flagRXNE) { for !i2c.hasFlag(flagRXNE) {
if i2c.isAcknowledgeFailed(startTicks) { if i2c.isAcknowledgeFailed(startTicks) {
return false return false
@ -249,7 +249,7 @@ func (i2c I2C) waitOnRXNEFlagUntilTimeout(startTicks int64) bool {
return true return true
} }
func (i2c I2C) waitOnTXISFlagUntilTimeout(startTicks int64) bool { func (i2c *I2C) waitOnTXISFlagUntilTimeout(startTicks int64) bool {
for !i2c.hasFlag(flagTXIS) { for !i2c.hasFlag(flagTXIS) {
if i2c.isAcknowledgeFailed(startTicks) { if i2c.isAcknowledgeFailed(startTicks) {
return false return false
@ -263,7 +263,7 @@ func (i2c I2C) waitOnTXISFlagUntilTimeout(startTicks int64) bool {
return true return true
} }
func (i2c I2C) waitOnStopFlagUntilTimeout(startTicks int64) bool { func (i2c *I2C) waitOnStopFlagUntilTimeout(startTicks int64) bool {
for !i2c.hasFlag(flagSTOPF) { for !i2c.hasFlag(flagSTOPF) {
if i2c.isAcknowledgeFailed(startTicks) { if i2c.isAcknowledgeFailed(startTicks) {
return false return false
@ -277,7 +277,7 @@ func (i2c I2C) waitOnStopFlagUntilTimeout(startTicks int64) bool {
return true return true
} }
func (i2c I2C) isAcknowledgeFailed(startTicks int64) bool { func (i2c *I2C) isAcknowledgeFailed(startTicks int64) bool {
if i2c.hasFlag(flagAF) { if i2c.hasFlag(flagAF) {
// Wait until STOP Flag is reset // Wait until STOP Flag is reset
// AutoEnd should be initiate after AF // AutoEnd should be initiate after AF
@ -298,7 +298,7 @@ func (i2c I2C) isAcknowledgeFailed(startTicks int64) bool {
return false return false
} }
func (i2c I2C) flushTXDR() { func (i2c *I2C) flushTXDR() {
// If a pending TXIS flag is set, write a dummy data in TXDR to clear it // If a pending TXIS flag is set, write a dummy data in TXDR to clear it
if i2c.hasFlag(flagTXIS) { if i2c.hasFlag(flagTXIS) {
i2c.Bus.TXDR.Set(0) i2c.Bus.TXDR.Set(0)
@ -310,7 +310,7 @@ func (i2c I2C) flushTXDR() {
} }
} }
func (i2c I2C) resetCR2() { func (i2c *I2C) resetCR2() {
i2c.Bus.CR2.ClearBits(stm32.I2C_CR2_SADD_Msk | i2c.Bus.CR2.ClearBits(stm32.I2C_CR2_SADD_Msk |
stm32.I2C_CR2_HEAD10R_Msk | stm32.I2C_CR2_HEAD10R_Msk |
stm32.I2C_CR2_NBYTES_Msk | stm32.I2C_CR2_NBYTES_Msk |
@ -318,7 +318,7 @@ func (i2c I2C) resetCR2() {
stm32.I2C_CR2_RD_WRN_Msk) stm32.I2C_CR2_RD_WRN_Msk)
} }
func (i2c I2C) transferConfig(addr uint16, size uint8, mode uint32, request uint32) { func (i2c *I2C) transferConfig(addr uint16, size uint8, mode uint32, request uint32) {
mask := uint32(stm32.I2C_CR2_SADD_Msk | mask := uint32(stm32.I2C_CR2_SADD_Msk |
stm32.I2C_CR2_NBYTES_Msk | stm32.I2C_CR2_NBYTES_Msk |
stm32.I2C_CR2_RELOAD_Msk | stm32.I2C_CR2_RELOAD_Msk |
@ -334,11 +334,11 @@ func (i2c I2C) transferConfig(addr uint16, size uint8, mode uint32, request uint
i2c.Bus.CR2.ReplaceBits(value, mask, 0) i2c.Bus.CR2.ReplaceBits(value, mask, 0)
} }
func (i2c I2C) hasFlag(flag uint32) bool { func (i2c *I2C) hasFlag(flag uint32) bool {
return i2c.Bus.ISR.HasBits(flag) return i2c.Bus.ISR.HasBits(flag)
} }
func (i2c I2C) clearFlag(flag uint32) { func (i2c *I2C) clearFlag(flag uint32) {
if flag == stm32.I2C_ISR_TXE { if flag == stm32.I2C_ISR_TXE {
i2c.Bus.ISR.SetBits(flag) i2c.Bus.ISR.SetBits(flag)
} else { } else {

Просмотреть файл

@ -201,7 +201,7 @@ func (spi SPI) configurePins(config SPIConfig) {
// Since the first interface is named I2C1, both I2C0 and I2C1 refer to I2C1. // Since the first interface is named I2C1, both I2C0 and I2C1 refer to I2C1.
// TODO: implement I2C2. // TODO: implement I2C2.
var ( var (
I2C1 = I2C{Bus: stm32.I2C1} I2C1 = (*I2C)(unsafe.Pointer(stm32.I2C1))
I2C0 = I2C1 I2C0 = I2C1
) )
@ -209,7 +209,7 @@ type I2C struct {
Bus *stm32.I2C_Type Bus *stm32.I2C_Type
} }
func (i2c I2C) configurePins(config I2CConfig) { func (i2c *I2C) configurePins(config I2CConfig) {
if config.SDA == PB9 { if config.SDA == PB9 {
// use alternate I2C1 pins PB8/PB9 via AFIO mapping // use alternate I2C1 pins PB8/PB9 via AFIO mapping
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_AFIOEN) stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_AFIOEN)
@ -220,7 +220,7 @@ func (i2c I2C) configurePins(config I2CConfig) {
config.SCL.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltOpenDrain}) config.SCL.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltOpenDrain})
} }
func (i2c I2C) getFreqRange(config I2CConfig) uint32 { func (i2c *I2C) getFreqRange(config I2CConfig) uint32 {
// pclk1 clock speed is main frequency divided by PCLK1 prescaler (div 2) // pclk1 clock speed is main frequency divided by PCLK1 prescaler (div 2)
pclk1 := CPUFrequency() / 2 pclk1 := CPUFrequency() / 2
@ -229,7 +229,7 @@ func (i2c I2C) getFreqRange(config I2CConfig) uint32 {
return pclk1 / 1000000 return pclk1 / 1000000
} }
func (i2c I2C) getRiseTime(config I2CConfig) uint32 { func (i2c *I2C) getRiseTime(config I2CConfig) uint32 {
// These bits must be programmed with the maximum SCL rise time given in the // These bits must be programmed with the maximum SCL rise time given in the
// I2C bus specification, incremented by 1. // I2C bus specification, incremented by 1.
// For instance: in Sm mode, the maximum allowed SCL rise time is 1000 ns. // For instance: in Sm mode, the maximum allowed SCL rise time is 1000 ns.
@ -245,7 +245,7 @@ func (i2c I2C) getRiseTime(config I2CConfig) uint32 {
return (freqRange + 1) << stm32.I2C_TRISE_TRISE_Pos return (freqRange + 1) << stm32.I2C_TRISE_TRISE_Pos
} }
func (i2c I2C) getSpeed(config I2CConfig) uint32 { func (i2c *I2C) getSpeed(config I2CConfig) uint32 {
ccr := func(pclk uint32, freq uint32, coeff uint32) uint32 { ccr := func(pclk uint32, freq uint32, coeff uint32) uint32 {
return (((pclk - 1) / (freq * coeff)) + 1) & stm32.I2C_CCR_CCR_Msk return (((pclk - 1) / (freq * coeff)) + 1) & stm32.I2C_CCR_CCR_Msk
} }

Просмотреть файл

@ -116,12 +116,12 @@ type I2C struct {
AltFuncSelector uint8 AltFuncSelector uint8
} }
func (i2c I2C) configurePins(config I2CConfig) { func (i2c *I2C) configurePins(config I2CConfig) {
config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, i2c.AltFuncSelector) config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, i2c.AltFuncSelector)
config.SDA.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSDA}, i2c.AltFuncSelector) config.SDA.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSDA}, i2c.AltFuncSelector)
} }
func (i2c I2C) getFreqRange(config I2CConfig) uint32 { func (i2c *I2C) getFreqRange(config I2CConfig) uint32 {
// all I2C interfaces are on APB1 (42 MHz) // all I2C interfaces are on APB1 (42 MHz)
clock := CPUFrequency() / 4 clock := CPUFrequency() / 4
// convert to MHz // convert to MHz
@ -139,7 +139,7 @@ func (i2c I2C) getFreqRange(config I2CConfig) uint32 {
return clock << stm32.I2C_CR2_FREQ_Pos return clock << stm32.I2C_CR2_FREQ_Pos
} }
func (i2c I2C) getRiseTime(config I2CConfig) uint32 { func (i2c *I2C) getRiseTime(config I2CConfig) uint32 {
// These bits must be programmed with the maximum SCL rise time given in the // These bits must be programmed with the maximum SCL rise time given in the
// I2C bus specification, incremented by 1. // I2C bus specification, incremented by 1.
// For instance: in Sm mode, the maximum allowed SCL rise time is 1000 ns. // For instance: in Sm mode, the maximum allowed SCL rise time is 1000 ns.
@ -155,7 +155,7 @@ func (i2c I2C) getRiseTime(config I2CConfig) uint32 {
return (freqRange + 1) << stm32.I2C_TRISE_TRISE_Pos return (freqRange + 1) << stm32.I2C_TRISE_TRISE_Pos
} }
func (i2c I2C) getSpeed(config I2CConfig) uint32 { func (i2c *I2C) getSpeed(config I2CConfig) uint32 {
ccr := func(pclk uint32, freq uint32, coeff uint32) uint32 { ccr := func(pclk uint32, freq uint32, coeff uint32) uint32 {
return (((pclk - 1) / (freq * coeff)) + 1) & stm32.I2C_CCR_CCR_Msk return (((pclk - 1) / (freq * coeff)) + 1) & stm32.I2C_CCR_CCR_Msk
} }

Просмотреть файл

@ -128,12 +128,12 @@ type I2C struct {
AltFuncSelector uint8 AltFuncSelector uint8
} }
func (i2c I2C) configurePins(config I2CConfig) { func (i2c *I2C) configurePins(config I2CConfig) {
config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, i2c.AltFuncSelector) config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, i2c.AltFuncSelector)
config.SDA.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSDA}, i2c.AltFuncSelector) config.SDA.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSDA}, i2c.AltFuncSelector)
} }
func (i2c I2C) getFreqRange(config I2CConfig) uint32 { func (i2c *I2C) getFreqRange(config I2CConfig) uint32 {
// all I2C interfaces are on APB1 (42 MHz) // all I2C interfaces are on APB1 (42 MHz)
clock := CPUFrequency() / 4 clock := CPUFrequency() / 4
// convert to MHz // convert to MHz
@ -151,7 +151,7 @@ func (i2c I2C) getFreqRange(config I2CConfig) uint32 {
return clock << stm32.I2C_CR2_FREQ_Pos return clock << stm32.I2C_CR2_FREQ_Pos
} }
func (i2c I2C) getRiseTime(config I2CConfig) uint32 { func (i2c *I2C) getRiseTime(config I2CConfig) uint32 {
// These bits must be programmed with the maximum SCL rise time given in the // These bits must be programmed with the maximum SCL rise time given in the
// I2C bus specification, incremented by 1. // I2C bus specification, incremented by 1.
// For instance: in Sm mode, the maximum allowed SCL rise time is 1000 ns. // For instance: in Sm mode, the maximum allowed SCL rise time is 1000 ns.
@ -167,7 +167,7 @@ func (i2c I2C) getRiseTime(config I2CConfig) uint32 {
return (freqRange + 1) << stm32.I2C_TRISE_TRISE_Pos return (freqRange + 1) << stm32.I2C_TRISE_TRISE_Pos
} }
func (i2c I2C) getSpeed(config I2CConfig) uint32 { func (i2c *I2C) getSpeed(config I2CConfig) uint32 {
ccr := func(pclk uint32, freq uint32, coeff uint32) uint32 { ccr := func(pclk uint32, freq uint32, coeff uint32) uint32 {
return (((pclk - 1) / (freq * coeff)) + 1) & stm32.I2C_CCR_CCR_Msk return (((pclk - 1) / (freq * coeff)) + 1) & stm32.I2C_CCR_CCR_Msk
} }

Просмотреть файл

@ -45,7 +45,7 @@ func (uart *UART) setRegisters() {
//---------- I2C related code //---------- I2C related code
// Gets the value for TIMINGR register // Gets the value for TIMINGR register
func (i2c I2C) getFreqRange() uint32 { func (i2c *I2C) getFreqRange() uint32 {
// This is a 'magic' value calculated by STM32CubeMX // This is a 'magic' value calculated by STM32CubeMX
// for 27MHz PCLK1 (216MHz CPU Freq / 8). // for 27MHz PCLK1 (216MHz CPU Freq / 8).
// TODO: Do calculations based on PCLK1 // TODO: Do calculations based on PCLK1

Просмотреть файл

@ -38,7 +38,7 @@ func (uart *UART) setRegisters() {
//---------- I2C related code //---------- I2C related code
// Gets the value for TIMINGR register // Gets the value for TIMINGR register
func (i2c I2C) getFreqRange() uint32 { func (i2c *I2C) getFreqRange() uint32 {
// This is a 'magic' value calculated by STM32CubeMX // This is a 'magic' value calculated by STM32CubeMX
// for 80MHz PCLK1. // for 80MHz PCLK1.
// TODO: Do calculations based on PCLK1 // TODO: Do calculations based on PCLK1

Просмотреть файл

@ -43,7 +43,7 @@ func (uart *UART) setRegisters() {
//---------- I2C related code //---------- I2C related code
// Gets the value for TIMINGR register // Gets the value for TIMINGR register
func (i2c I2C) getFreqRange() uint32 { func (i2c *I2C) getFreqRange() uint32 {
// This is a 'magic' value calculated by STM32CubeMX // This is a 'magic' value calculated by STM32CubeMX
// for 110MHz PCLK1. // for 110MHz PCLK1.
// TODO: Do calculations based on PCLK1 // TODO: Do calculations based on PCLK1