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.
Этот коммит содержится в:
родитель
71bbe93ab2
коммит
90b42799a2
41 изменённых файлов: 129 добавлений и 136 удалений
|
@ -32,7 +32,7 @@ func init() {
|
|||
|
||||
// I2C on the Arduino Nano 33.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM4_I2CM,
|
||||
SERCOM: 4,
|
||||
}
|
||||
|
|
|
@ -23,12 +23,12 @@ func init() {
|
|||
// I2C on the Circuit Playground Express.
|
||||
var (
|
||||
// external device
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM5_I2CM,
|
||||
SERCOM: 5,
|
||||
}
|
||||
// internal device
|
||||
I2C1 = I2C{
|
||||
I2C1 = &I2C{
|
||||
Bus: sam.SERCOM1_I2CM,
|
||||
SERCOM: 1,
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ const (
|
|||
|
||||
// I2C on the Feather M0.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM3_I2CM,
|
||||
SERCOM: 3,
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ func init() {
|
|||
|
||||
// I2C on the Feather M4.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM2_I2CM,
|
||||
SERCOM: 2,
|
||||
}
|
||||
|
|
|
@ -230,15 +230,15 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
I2C1 = I2C{
|
||||
I2C1 = &I2C{
|
||||
Bus: stm32.I2C1,
|
||||
AltFuncSelector: AF4_I2C1_2_3,
|
||||
}
|
||||
I2C2 = I2C{
|
||||
I2C2 = &I2C{
|
||||
Bus: stm32.I2C2,
|
||||
AltFuncSelector: AF4_I2C1_2_3,
|
||||
}
|
||||
I2C3 = I2C{
|
||||
I2C3 = &I2C{
|
||||
Bus: stm32.I2C1,
|
||||
AltFuncSelector: AF4_I2C1_2_3,
|
||||
}
|
||||
|
|
|
@ -40,11 +40,11 @@ var (
|
|||
|
||||
// I2C on the Grand Central M4
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM3_I2CM,
|
||||
SERCOM: 3,
|
||||
}
|
||||
I2C1 = I2C{
|
||||
I2C1 = &I2C{
|
||||
Bus: sam.SERCOM6_I2CM,
|
||||
SERCOM: 6,
|
||||
}
|
||||
|
|
|
@ -10,10 +10,3 @@ var (
|
|||
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.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM3_I2CM,
|
||||
SERCOM: 3,
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ func init() {
|
|||
|
||||
// I2C on the ItsyBitsy M4.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM2_I2CM,
|
||||
SERCOM: 2,
|
||||
}
|
||||
|
|
|
@ -13,16 +13,3 @@ var (
|
|||
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
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM5_I2CM,
|
||||
SERCOM: 5,
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ func init() {
|
|||
|
||||
// I2C on the Metro M4.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM5_I2CM,
|
||||
SERCOM: 5,
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ func init() {
|
|||
|
||||
// I2C on the P1AM-100.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM0_I2CM,
|
||||
SERCOM: 0,
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ func init() {
|
|||
|
||||
// I2C on the ItsyBitsy M4.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM2_I2CM,
|
||||
SERCOM: 2,
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ const (
|
|||
|
||||
// I2C on the PyGamer.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM2_I2CM,
|
||||
SERCOM: 2,
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ func init() {
|
|||
|
||||
// I2C on the PyPortal.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM5_I2CM,
|
||||
SERCOM: 5,
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ const (
|
|||
|
||||
// I2C on the QT Py M0.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM2_I2CM,
|
||||
SERCOM: 2,
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: stm32.I2C1,
|
||||
AltFuncSelector: AF4_I2C1_2_3,
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ const (
|
|||
|
||||
// I2C on the Trinket M0.
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM2_I2CM,
|
||||
SERCOM: 2,
|
||||
}
|
||||
|
|
|
@ -29,12 +29,12 @@ func init() {
|
|||
|
||||
// I2C on the Wio Terminal
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM4_I2CM,
|
||||
SERCOM: 4,
|
||||
}
|
||||
|
||||
I2C1 = I2C{
|
||||
I2C1 = &I2C{
|
||||
Bus: sam.SERCOM4_I2CM,
|
||||
SERCOM: 4,
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ const (
|
|||
|
||||
// I2C on the Xiao
|
||||
var (
|
||||
I2C0 = I2C{
|
||||
I2C0 = &I2C{
|
||||
Bus: sam.SERCOM2_I2CM,
|
||||
SERCOM: 2,
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ var (
|
|||
// 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
|
||||
// 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[0] = register
|
||||
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
|
||||
// is a shortcut to easily read such registers. Also, it only works for devices
|
||||
// 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)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ type I2C struct {
|
|||
}
|
||||
|
||||
// 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.
|
||||
type I2CConfig struct {
|
||||
|
@ -22,7 +22,7 @@ type I2CConfig struct {
|
|||
}
|
||||
|
||||
// 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.
|
||||
if config.Frequency == 0 {
|
||||
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.
|
||||
// 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.
|
||||
func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
||||
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||
if len(w) != 0 {
|
||||
i2c.start(uint8(addr), true) // start transmission for writing
|
||||
for _, b := range w {
|
||||
|
@ -70,7 +70,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
|||
}
|
||||
|
||||
// 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.
|
||||
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.
|
||||
func (i2c I2C) stop() {
|
||||
func (i2c *I2C) stop() {
|
||||
// Send stop condition.
|
||||
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.
|
||||
func (i2c I2C) writeByte(data byte) {
|
||||
func (i2c *I2C) writeByte(data byte) {
|
||||
// Write data to register.
|
||||
avr.TWDR.Set(data)
|
||||
|
||||
|
@ -110,7 +110,7 @@ func (i2c I2C) writeByte(data byte) {
|
|||
}
|
||||
|
||||
// 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.
|
||||
avr.TWCR.Set(avr.TWCR_TWEN | avr.TWCR_TWINT | avr.TWCR_TWEA)
|
||||
|
||||
|
|
|
@ -669,7 +669,7 @@ const (
|
|||
const i2cTimeout = 1000
|
||||
|
||||
// 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.
|
||||
if config.Frequency == 0 {
|
||||
config.Frequency = TWI_FREQ_100KHZ
|
||||
|
@ -725,7 +725,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
|
|||
}
|
||||
|
||||
// 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:
|
||||
// SystemCoreClock / ( 2 * baudrate) - 5 - (((SystemCoreClock / 1000000) * WIRE_RISE_TIME_NANOSECONDS) / (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.
|
||||
// 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.
|
||||
func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
||||
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||
var err error
|
||||
if len(w) != 0 {
|
||||
// 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.
|
||||
func (i2c I2C) WriteByte(data byte) error {
|
||||
func (i2c *I2C) WriteByte(data byte) error {
|
||||
// Send data byte
|
||||
i2c.Bus.DATA.Set(data)
|
||||
|
||||
|
@ -837,7 +837,7 @@ func (i2c I2C) WriteByte(data byte) error {
|
|||
}
|
||||
|
||||
// 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)
|
||||
if !write {
|
||||
data |= 1 // set read flag
|
||||
|
@ -857,7 +857,7 @@ func (i2c I2C) sendAddress(address uint16, write bool) error {
|
|||
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
|
||||
timeout := i2cTimeout
|
||||
for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) {
|
||||
|
@ -869,7 +869,7 @@ func (i2c I2C) signalStop() error {
|
|||
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
|
||||
timeout := i2cTimeout
|
||||
for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) {
|
||||
|
@ -881,7 +881,7 @@ func (i2c I2C) signalRead() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (i2c I2C) readByte() byte {
|
||||
func (i2c *I2C) readByte() byte {
|
||||
for !i2c.Bus.INTFLAG.HasBits(sam.SERCOM_I2CM_INTFLAG_SB) {
|
||||
}
|
||||
return byte(i2c.Bus.DATA.Get())
|
||||
|
|
|
@ -1104,7 +1104,7 @@ const (
|
|||
const i2cTimeout = 1000
|
||||
|
||||
// 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.
|
||||
if config.Frequency == 0 {
|
||||
config.Frequency = TWI_FREQ_100KHZ
|
||||
|
@ -1163,7 +1163,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
|
|||
}
|
||||
|
||||
// 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:
|
||||
// sercom->I2CM.BAUD.bit.BAUD = SERCOM_FREQ_REF / ( 2 * baudrate) - 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.
|
||||
// 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.
|
||||
func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
||||
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||
var err error
|
||||
if len(w) != 0 {
|
||||
// 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.
|
||||
func (i2c I2C) WriteByte(data byte) error {
|
||||
func (i2c *I2C) WriteByte(data byte) error {
|
||||
// Send data byte
|
||||
i2c.Bus.DATA.Set(data)
|
||||
|
||||
|
@ -1275,7 +1275,7 @@ func (i2c I2C) WriteByte(data byte) error {
|
|||
}
|
||||
|
||||
// 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)
|
||||
if !write {
|
||||
data |= 1 // set read flag
|
||||
|
@ -1295,7 +1295,7 @@ func (i2c I2C) sendAddress(address uint16, write bool) error {
|
|||
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
|
||||
timeout := i2cTimeout
|
||||
for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) {
|
||||
|
@ -1307,7 +1307,7 @@ func (i2c I2C) signalStop() error {
|
|||
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
|
||||
timeout := i2cTimeout
|
||||
for i2c.Bus.SYNCBUSY.HasBits(sam.SERCOM_I2CM_SYNCBUSY_SYSOP) {
|
||||
|
@ -1319,7 +1319,7 @@ func (i2c I2C) signalRead() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (i2c I2C) readByte() byte {
|
||||
func (i2c *I2C) readByte() byte {
|
||||
for !i2c.Bus.INTFLAG.HasBits(sam.SERCOM_I2CM_INTFLAG_SB) {
|
||||
}
|
||||
return byte(i2c.Bus.DATA.Get())
|
||||
|
|
|
@ -5,6 +5,7 @@ package machine
|
|||
import (
|
||||
"device/sifive"
|
||||
"runtime/interrupt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func CPUFrequency() uint32 {
|
||||
|
@ -185,9 +186,13 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
|||
|
||||
// I2C on the FE310-G002.
|
||||
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.
|
||||
type I2CConfig struct {
|
||||
Frequency uint32
|
||||
|
@ -196,7 +201,7 @@ type I2CConfig struct {
|
|||
}
|
||||
|
||||
// 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
|
||||
if config.Frequency == 0 {
|
||||
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.
|
||||
// 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.
|
||||
func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
||||
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||
var err error
|
||||
if len(w) != 0 {
|
||||
// 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.
|
||||
func (i2c I2C) writeByte(data byte) error {
|
||||
func (i2c *I2C) writeByte(data byte) error {
|
||||
// Send data byte
|
||||
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.
|
||||
func (i2c I2C) readByte() byte {
|
||||
func (i2c *I2C) readByte() byte {
|
||||
i2c.Bus.CR_SR.Set(sifive.I2C_CR_RD)
|
||||
|
||||
// wait until transmission complete
|
||||
|
@ -306,7 +311,7 @@ func (i2c I2C) readByte() byte {
|
|||
}
|
||||
|
||||
// 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)
|
||||
if !write {
|
||||
data |= 1 // set read flag in transmit register
|
||||
|
|
|
@ -6,7 +6,7 @@ package machine
|
|||
|
||||
var (
|
||||
SPI0 = SPI{0}
|
||||
I2C0 = I2C{0}
|
||||
I2C0 = &I2C{0}
|
||||
UART0 = UART{0}
|
||||
)
|
||||
|
||||
|
@ -115,13 +115,13 @@ type I2CConfig struct {
|
|||
}
|
||||
|
||||
// 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)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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))
|
||||
// TODO: do something with the returned error code.
|
||||
return nil
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"device/riscv"
|
||||
"errors"
|
||||
"runtime/interrupt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func CPUFrequency() uint32 {
|
||||
|
@ -493,9 +494,15 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
|||
|
||||
// I2C on the K210.
|
||||
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.
|
||||
type I2CConfig struct {
|
||||
Frequency uint32
|
||||
|
@ -504,7 +511,7 @@ type I2CConfig struct {
|
|||
}
|
||||
|
||||
// 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 {
|
||||
config.Frequency = TWI_FREQ_100KHZ
|
||||
|
@ -518,7 +525,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
|
|||
// Enable APB0 clock.
|
||||
kendryte.SYSCTL.CLK_EN_CENT.SetBits(kendryte.SYSCTL_CLK_EN_CENT_APB0_CLK_EN)
|
||||
|
||||
switch i2c.Bus {
|
||||
switch &i2c.Bus {
|
||||
case kendryte.I2C0:
|
||||
// Initialize I2C0 clock.
|
||||
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.
|
||||
// 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.
|
||||
func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
||||
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||
// Set peripheral address.
|
||||
i2c.Bus.TAR.Set(uint32(addr))
|
||||
// Enable controller.
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"device/nrf"
|
||||
"errors"
|
||||
"runtime/interrupt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -203,13 +204,13 @@ func (uart *UART) handleInterrupt(interrupt.Interrupt) {
|
|||
|
||||
// I2C on the NRF.
|
||||
type I2C struct {
|
||||
Bus *nrf.TWI_Type
|
||||
Bus nrf.TWI_Type
|
||||
}
|
||||
|
||||
// There are 2 I2C interfaces on the NRF.
|
||||
var (
|
||||
I2C0 = I2C{Bus: nrf.TWI0}
|
||||
I2C1 = I2C{Bus: nrf.TWI1}
|
||||
I2C0 = (*I2C)(unsafe.Pointer(nrf.TWI0))
|
||||
I2C1 = (*I2C)(unsafe.Pointer(nrf.TWI1))
|
||||
)
|
||||
|
||||
// I2CConfig is used to store config info for I2C.
|
||||
|
@ -220,7 +221,7 @@ type I2CConfig struct {
|
|||
}
|
||||
|
||||
// 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.
|
||||
if config.Frequency == 0 {
|
||||
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.
|
||||
// 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.
|
||||
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))
|
||||
|
||||
if len(w) != 0 {
|
||||
|
@ -299,7 +300,7 @@ cleanUp:
|
|||
// 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
|
||||
// reading.
|
||||
func (i2c I2C) signalStop() {
|
||||
func (i2c *I2C) signalStop() {
|
||||
i2c.Bus.TASKS_STOP.Set(1)
|
||||
for i2c.Bus.EVENTS_STOPPED.Get() == 0 {
|
||||
}
|
||||
|
@ -307,7 +308,7 @@ func (i2c I2C) signalStop() {
|
|||
}
|
||||
|
||||
// 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))
|
||||
for i2c.Bus.EVENTS_TXDSENT.Get() == 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.
|
||||
func (i2c I2C) readByte() (byte, error) {
|
||||
func (i2c *I2C) readByte() (byte, error) {
|
||||
for i2c.Bus.EVENTS_RXDREADY.Get() == 0 {
|
||||
if e := i2c.Bus.EVENTS_ERROR.Get(); e != 0 {
|
||||
i2c.Bus.EVENTS_ERROR.Set(0)
|
||||
|
|
|
@ -24,7 +24,7 @@ func (uart UART) setPins(tx, rx Pin) {
|
|||
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.PSELSDA.Set(uint32(sda))
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ func (uart UART) setPins(tx, rx Pin) {
|
|||
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.PSELSDA.Set(uint32(sda))
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ func (uart UART) setPins(tx, rx Pin) {
|
|||
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.SDA.Set(uint32(sda))
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ func (uart UART) setPins(tx, rx Pin) {
|
|||
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.SDA.Set(uint32(sda))
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ const (
|
|||
flagMSL = 0x00100001
|
||||
)
|
||||
|
||||
func (i2c I2C) hasFlag(flag uint32) bool {
|
||||
func (i2c *I2C) hasFlag(flag uint32) bool {
|
||||
const mask = 0x0000FFFF
|
||||
if uint8(flag>>16) == 1 {
|
||||
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
|
||||
i2c.Bus.SR1.Set(^(flag & mask))
|
||||
}
|
||||
|
||||
// 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.SR2.Get()
|
||||
}
|
||||
|
||||
func (i2c I2C) waitForFlag(flag uint32, set bool) bool {
|
||||
func (i2c *I2C) waitForFlag(flag uint32, set bool) bool {
|
||||
const tryMax = 10000
|
||||
hasFlag := false
|
||||
for i := 0; !hasFlag && i < tryMax; i++ {
|
||||
|
@ -58,7 +58,7 @@ func (i2c I2C) waitForFlag(flag uint32, set bool) bool {
|
|||
return hasFlag
|
||||
}
|
||||
|
||||
func (i2c I2C) waitForFlagOrError(flag uint32, set bool) bool {
|
||||
func (i2c *I2C) waitForFlagOrError(flag uint32, set bool) bool {
|
||||
const tryMax = 10000
|
||||
hasFlag := false
|
||||
for i := 0; !hasFlag && i < tryMax; i++ {
|
||||
|
@ -107,7 +107,7 @@ type I2CConfig struct {
|
|||
}
|
||||
|
||||
// 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.
|
||||
// 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
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
|
@ -172,7 +172,7 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
|||
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) {
|
||||
return errI2CBusReadyTimeout
|
||||
|
@ -224,7 +224,7 @@ func (i2c I2C) controllerTransmit(addr uint16, w []byte) error {
|
|||
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 {
|
||||
// generate start condition
|
||||
|
@ -250,7 +250,7 @@ func (i2c I2C) controllerRequestWrite(addr uint16, option transferOption) error
|
|||
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) {
|
||||
return errI2CBusReadyTimeout
|
||||
|
@ -400,7 +400,7 @@ func (i2c I2C) controllerReceive(addr uint16, r []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (i2c I2C) controllerRequestRead(addr uint16, option transferOption) error {
|
||||
func (i2c *I2C) controllerRequestRead(addr uint16, option transferOption) error {
|
||||
|
||||
// enable ACK
|
||||
i2c.Bus.CR1.SetBits(stm32.I2C_CR1_ACK)
|
||||
|
|
|
@ -46,7 +46,7 @@ type I2CConfig struct {
|
|||
SDA Pin
|
||||
}
|
||||
|
||||
func (i2c I2C) Configure(config I2CConfig) error {
|
||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||
// disable I2C interface before any configuration changes
|
||||
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_PE)
|
||||
|
||||
|
@ -81,7 +81,7 @@ func (i2c I2C) Configure(config I2CConfig) error {
|
|||
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 err := i2c.controllerTransmit(addr, w); nil != err {
|
||||
return err
|
||||
|
@ -97,12 +97,12 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (i2c I2C) configurePins(config I2CConfig) {
|
||||
func (i2c *I2C) configurePins(config I2CConfig) {
|
||||
config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, 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()
|
||||
|
||||
if !i2c.waitOnFlagUntilTimeout(flagBUSY, false, start) {
|
||||
|
@ -161,7 +161,7 @@ func (i2c I2C) controllerTransmit(addr uint16, w []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (i2c I2C) controllerReceive(addr uint16, r []byte) error {
|
||||
func (i2c *I2C) controllerReceive(addr uint16, r []byte) error {
|
||||
start := ticks()
|
||||
|
||||
if !i2c.waitOnFlagUntilTimeout(flagBUSY, false, start) {
|
||||
|
@ -220,7 +220,7 @@ func (i2c I2C) controllerReceive(addr uint16, r []byte) error {
|
|||
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 {
|
||||
if (ticks() - startTicks) > TIMEOUT_TICKS {
|
||||
return false
|
||||
|
@ -229,7 +229,7 @@ func (i2c I2C) waitOnFlagUntilTimeout(flag uint32, set bool, startTicks int64) b
|
|||
return true
|
||||
}
|
||||
|
||||
func (i2c I2C) waitOnRXNEFlagUntilTimeout(startTicks int64) bool {
|
||||
func (i2c *I2C) waitOnRXNEFlagUntilTimeout(startTicks int64) bool {
|
||||
for !i2c.hasFlag(flagRXNE) {
|
||||
if i2c.isAcknowledgeFailed(startTicks) {
|
||||
return false
|
||||
|
@ -249,7 +249,7 @@ func (i2c I2C) waitOnRXNEFlagUntilTimeout(startTicks int64) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (i2c I2C) waitOnTXISFlagUntilTimeout(startTicks int64) bool {
|
||||
func (i2c *I2C) waitOnTXISFlagUntilTimeout(startTicks int64) bool {
|
||||
for !i2c.hasFlag(flagTXIS) {
|
||||
if i2c.isAcknowledgeFailed(startTicks) {
|
||||
return false
|
||||
|
@ -263,7 +263,7 @@ func (i2c I2C) waitOnTXISFlagUntilTimeout(startTicks int64) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (i2c I2C) waitOnStopFlagUntilTimeout(startTicks int64) bool {
|
||||
func (i2c *I2C) waitOnStopFlagUntilTimeout(startTicks int64) bool {
|
||||
for !i2c.hasFlag(flagSTOPF) {
|
||||
if i2c.isAcknowledgeFailed(startTicks) {
|
||||
return false
|
||||
|
@ -277,7 +277,7 @@ func (i2c I2C) waitOnStopFlagUntilTimeout(startTicks int64) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (i2c I2C) isAcknowledgeFailed(startTicks int64) bool {
|
||||
func (i2c *I2C) isAcknowledgeFailed(startTicks int64) bool {
|
||||
if i2c.hasFlag(flagAF) {
|
||||
// Wait until STOP Flag is reset
|
||||
// AutoEnd should be initiate after AF
|
||||
|
@ -298,7 +298,7 @@ func (i2c I2C) isAcknowledgeFailed(startTicks int64) bool {
|
|||
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 i2c.hasFlag(flagTXIS) {
|
||||
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 |
|
||||
stm32.I2C_CR2_HEAD10R_Msk |
|
||||
stm32.I2C_CR2_NBYTES_Msk |
|
||||
|
@ -318,7 +318,7 @@ func (i2c I2C) resetCR2() {
|
|||
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 |
|
||||
stm32.I2C_CR2_NBYTES_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)
|
||||
}
|
||||
|
||||
func (i2c I2C) hasFlag(flag uint32) bool {
|
||||
func (i2c *I2C) hasFlag(flag uint32) bool {
|
||||
return i2c.Bus.ISR.HasBits(flag)
|
||||
}
|
||||
|
||||
func (i2c I2C) clearFlag(flag uint32) {
|
||||
func (i2c *I2C) clearFlag(flag uint32) {
|
||||
if flag == stm32.I2C_ISR_TXE {
|
||||
i2c.Bus.ISR.SetBits(flag)
|
||||
} 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.
|
||||
// TODO: implement I2C2.
|
||||
var (
|
||||
I2C1 = I2C{Bus: stm32.I2C1}
|
||||
I2C1 = (*I2C)(unsafe.Pointer(stm32.I2C1))
|
||||
I2C0 = I2C1
|
||||
)
|
||||
|
||||
|
@ -209,7 +209,7 @@ type I2C struct {
|
|||
Bus *stm32.I2C_Type
|
||||
}
|
||||
|
||||
func (i2c I2C) configurePins(config I2CConfig) {
|
||||
func (i2c *I2C) configurePins(config I2CConfig) {
|
||||
if config.SDA == PB9 {
|
||||
// use alternate I2C1 pins PB8/PB9 via AFIO mapping
|
||||
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})
|
||||
}
|
||||
|
||||
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 := CPUFrequency() / 2
|
||||
|
||||
|
@ -229,7 +229,7 @@ func (i2c I2C) getFreqRange(config I2CConfig) uint32 {
|
|||
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
|
||||
// I2C bus specification, incremented by 1.
|
||||
// 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
|
||||
}
|
||||
|
||||
func (i2c I2C) getSpeed(config I2CConfig) uint32 {
|
||||
func (i2c *I2C) getSpeed(config I2CConfig) uint32 {
|
||||
ccr := func(pclk uint32, freq uint32, coeff uint32) uint32 {
|
||||
return (((pclk - 1) / (freq * coeff)) + 1) & stm32.I2C_CCR_CCR_Msk
|
||||
}
|
||||
|
|
|
@ -116,12 +116,12 @@ type I2C struct {
|
|||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
func (i2c I2C) configurePins(config I2CConfig) {
|
||||
func (i2c *I2C) configurePins(config I2CConfig) {
|
||||
config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, 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)
|
||||
clock := CPUFrequency() / 4
|
||||
// convert to MHz
|
||||
|
@ -139,7 +139,7 @@ func (i2c I2C) getFreqRange(config I2CConfig) uint32 {
|
|||
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
|
||||
// I2C bus specification, incremented by 1.
|
||||
// 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
|
||||
}
|
||||
|
||||
func (i2c I2C) getSpeed(config I2CConfig) uint32 {
|
||||
func (i2c *I2C) getSpeed(config I2CConfig) uint32 {
|
||||
ccr := func(pclk uint32, freq uint32, coeff uint32) uint32 {
|
||||
return (((pclk - 1) / (freq * coeff)) + 1) & stm32.I2C_CCR_CCR_Msk
|
||||
}
|
||||
|
|
|
@ -128,12 +128,12 @@ type I2C struct {
|
|||
AltFuncSelector uint8
|
||||
}
|
||||
|
||||
func (i2c I2C) configurePins(config I2CConfig) {
|
||||
func (i2c *I2C) configurePins(config I2CConfig) {
|
||||
config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, 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)
|
||||
clock := CPUFrequency() / 4
|
||||
// convert to MHz
|
||||
|
@ -151,7 +151,7 @@ func (i2c I2C) getFreqRange(config I2CConfig) uint32 {
|
|||
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
|
||||
// I2C bus specification, incremented by 1.
|
||||
// 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
|
||||
}
|
||||
|
||||
func (i2c I2C) getSpeed(config I2CConfig) uint32 {
|
||||
func (i2c *I2C) getSpeed(config I2CConfig) uint32 {
|
||||
ccr := func(pclk uint32, freq uint32, coeff uint32) uint32 {
|
||||
return (((pclk - 1) / (freq * coeff)) + 1) & stm32.I2C_CCR_CCR_Msk
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ func (uart *UART) setRegisters() {
|
|||
//---------- I2C related code
|
||||
|
||||
// Gets the value for TIMINGR register
|
||||
func (i2c I2C) getFreqRange() uint32 {
|
||||
func (i2c *I2C) getFreqRange() uint32 {
|
||||
// This is a 'magic' value calculated by STM32CubeMX
|
||||
// for 27MHz PCLK1 (216MHz CPU Freq / 8).
|
||||
// TODO: Do calculations based on PCLK1
|
||||
|
|
|
@ -38,7 +38,7 @@ func (uart *UART) setRegisters() {
|
|||
//---------- I2C related code
|
||||
|
||||
// Gets the value for TIMINGR register
|
||||
func (i2c I2C) getFreqRange() uint32 {
|
||||
func (i2c *I2C) getFreqRange() uint32 {
|
||||
// This is a 'magic' value calculated by STM32CubeMX
|
||||
// for 80MHz PCLK1.
|
||||
// TODO: Do calculations based on PCLK1
|
||||
|
|
|
@ -43,7 +43,7 @@ func (uart *UART) setRegisters() {
|
|||
//---------- I2C related code
|
||||
|
||||
// Gets the value for TIMINGR register
|
||||
func (i2c I2C) getFreqRange() uint32 {
|
||||
func (i2c *I2C) getFreqRange() uint32 {
|
||||
// This is a 'magic' value calculated by STM32CubeMX
|
||||
// for 110MHz PCLK1.
|
||||
// TODO: Do calculations based on PCLK1
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче