@ -52,22 +52,22 @@ func (i2c *I2C) Configure(config I2CConfig) error {
//go:inline
func ( i2c * I2C ) initClock ( config I2CConfig ) {
// reset I2C clock
esp . SYSTEM . SetPERIP_RST_EN0_EXT0_RST ( 1 )
esp . SYSTEM . SetPERIP_CLK_EN0_EXT0_CLK_EN ( 1 )
esp . SYSTEM . SetPERIP_RST_EN0_EXT0_RST ( 0 )
esp . SYSTEM . SetPERIP_RST_EN0_I2C_ EXT0_RST ( 1 )
esp . SYSTEM . SetPERIP_CLK_EN0_I2C_ EXT0_CLK_EN ( 1 )
esp . SYSTEM . SetPERIP_RST_EN0_I2C_ EXT0_RST ( 0 )
// disable interrupts
esp . I2C . INT_ENA . ClearBits ( 0x3fff )
esp . I2C . INT_CLR . ClearBits ( 0x3fff )
esp . I2C0 . INT_ENA . ClearBits ( 0x3fff )
esp . I2C0 . INT_CLR . ClearBits ( 0x3fff )
esp . I2C . SetCLK_CONF_SCLK_SEL ( i2cClkSource )
esp . I2C . SetCLK_CONF_SCLK_ACTIVE ( 1 )
esp . I2C . SetCLK_CONF_SCLK_DIV_NUM ( i2cClkSourceFrequency / ( config . Frequency * 1024 ) )
esp . I2C . SetCTR_CLK_EN ( 1 )
esp . I2C0 . SetCLK_CONF_SCLK_SEL ( i2cClkSource )
esp . I2C0 . SetCLK_CONF_SCLK_ACTIVE ( 1 )
esp . I2C0 . SetCLK_CONF_SCLK_DIV_NUM ( i2cClkSourceFrequency / ( config . Frequency * 1024 ) )
esp . I2C0 . SetCTR_CLK_EN ( 1 )
}
//go:inline
func ( i2c * I2C ) initNoiseFilter ( ) {
esp . I2C . FILTER_CFG . Set ( 0x377 )
esp . I2C0 . FILTER_CFG . Set ( 0x377 )
}
//go:inline
@ -83,13 +83,13 @@ func (i2c *I2C) initPins(config I2CConfig) {
muxConfig |= 1 << esp . IO_MUX_GPIO_FUN_DRV_Pos
config . SDA . mux ( ) . Set ( muxConfig )
config . SDA . outFunc ( ) . Set ( 54 )
inFunc ( 54 ) . Set ( uint32 ( esp . GPIO_FUNC_IN_SEL_CFG_SIG_IN_S EL | config . SDA ) )
inFunc ( 54 ) . Set ( uint32 ( esp . GPIO_FUNC_IN_SEL_CFG_SEL | config . SDA ) )
config . SDA . Set ( true )
// Configure the pad with the given IO mux configuration.
config . SDA . pinReg ( ) . SetBits ( esp . GPIO_PIN_PIN_P AD_DRIVER )
config . SDA . pinReg ( ) . SetBits ( esp . GPIO_PIN_PAD_DRIVER )
esp . GPIO . ENABLE . SetBits ( 1 << int ( config . SDA ) )
esp . I2C . SetCTR_SDA_FORCE_OUT ( 1 )
esp . I2C0 . SetCTR_SDA_FORCE_OUT ( 1 )
// SCL
muxConfig = function << esp . IO_MUX_GPIO_MCU_SEL_Pos
@ -102,10 +102,10 @@ func (i2c *I2C) initPins(config I2CConfig) {
inFunc ( 53 ) . Set ( uint32 ( config . SCL ) )
config . SCL . Set ( true )
// Configure the pad with the given IO mux configuration.
config . SCL . pinReg ( ) . SetBits ( esp . GPIO_PIN_PIN_P AD_DRIVER )
config . SCL . pinReg ( ) . SetBits ( esp . GPIO_PIN_PAD_DRIVER )
esp . GPIO . ENABLE . SetBits ( 1 << int ( config . SCL ) )
esp . I2C . SetCTR_SCL_FORCE_OUT ( 1 )
esp . I2C0 . SetCTR_SCL_FORCE_OUT ( 1 )
}
//go:inline
@ -127,48 +127,48 @@ func (i2c *I2C) initFrequency(config I2CConfig) {
setup := halfCycle
hold := halfCycle
esp . I2C . SetSCL_LOW_PERIOD ( sclLow - 1 )
esp . I2C . SetSCL_HIGH_PERIOD ( sclHigh )
esp . I2C . SetSCL_HIGH_PERIOD_SCL_WAIT_HIGH_PERIOD ( 25 )
esp . I2C . SetSCL_RSTART_SETUP_TIME ( setup )
esp . I2C . SetSCL_STOP_SETUP_TIME ( setup )
esp . I2C . SetSCL_START_HOLD_TIME ( hold - 1 )
esp . I2C . SetSCL_STOP_HOLD_TIME ( hold - 1 )
esp . I2C . SetSDA_SAMPLE_TIME ( sda_sample )
esp . I2C . SetSDA_HOLD_TIME ( sdaHold )
esp . I2C0 . SetSCL_LOW_PERIOD ( sclLow - 1 )
esp . I2C0 . SetSCL_HIGH_PERIOD ( sclHigh )
esp . I2C0 . SetSCL_HIGH_PERIOD_SCL_WAIT_HIGH_PERIOD ( 25 )
esp . I2C0 . SetSCL_RSTART_SETUP_TIME ( setup )
esp . I2C0 . SetSCL_STOP_SETUP_TIME ( setup )
esp . I2C0 . SetSCL_START_HOLD_TIME ( hold - 1 )
esp . I2C0 . SetSCL_STOP_HOLD_TIME ( hold - 1 )
esp . I2C0 . SetSDA_SAMPLE_TIME ( sda_sample )
esp . I2C0 . SetSDA_HOLD_TIME ( sdaHold )
}
//go:inline
func ( i2c * I2C ) startMaster ( ) {
// FIFO mode for data
esp . I2C . SetFIFO_CONF_NONFIFO_EN ( 0 )
esp . I2C0 . SetFIFO_CONF_NONFIFO_EN ( 0 )
// Reset TX & RX buffers
esp . I2C . SetFIFO_CONF_RX_FIFO_RST ( 1 )
esp . I2C . SetFIFO_CONF_RX_FIFO_RST ( 0 )
esp . I2C . SetFIFO_CONF_TX_FIFO_RST ( 1 )
esp . I2C . SetFIFO_CONF_TX_FIFO_RST ( 0 )
esp . I2C0 . SetFIFO_CONF_RX_FIFO_RST ( 1 )
esp . I2C0 . SetFIFO_CONF_RX_FIFO_RST ( 0 )
esp . I2C0 . SetFIFO_CONF_TX_FIFO_RST ( 1 )
esp . I2C0 . SetFIFO_CONF_TX_FIFO_RST ( 0 )
// set timeout value
esp . I2C . TO . Set ( 0x10 )
esp . I2C0 . TO . Set ( 0x10 )
// enable master mode
esp . I2C . CTR . Set ( 0x113 )
esp . I2C . SetCTR_CONF_UPGATE ( 1 )
esp . I2C0 . CTR . Set ( 0x113 )
esp . I2C0 . SetCTR_CONF_UPGATE ( 1 )
resetMaster ( )
}
//go:inline
func resetMaster ( ) {
// reset FSM
esp . I2C . SetCTR_FSM_RST ( 1 )
esp . I2C0 . SetCTR_FSM_RST ( 1 )
// clear the bus
esp . I2C . SetSCL_SP_CONF_SCL_RST_SLV_NUM ( 9 )
esp . I2C . SetSCL_SP_CONF_SCL_RST_SLV_EN ( 1 )
esp . I2C . SetSCL_STRETCH_CONF_SLAVE_SCL_STRETCH_EN ( 1 )
esp . I2C . SetCTR_CONF_UPGATE ( 1 )
esp . I2C . FILTER_CFG . Set ( 0x377 )
esp . I2C0 . SetSCL_SP_CONF_SCL_RST_SLV_NUM ( 9 )
esp . I2C0 . SetSCL_SP_CONF_SCL_RST_SLV_EN ( 1 )
esp . I2C0 . SetSCL_STRETCH_CONF_SLAVE_SCL_STRETCH_EN ( 1 )
esp . I2C0 . SetCTR_CONF_UPGATE ( 1 )
esp . I2C0 . FILTER_CFG . Set ( 0x377 )
// wait for SCL_RST_SLV_EN
for esp . I2C . GetSCL_SP_CONF_SCL_RST_SLV_EN ( ) != 0 {
for esp . I2C0 . GetSCL_SP_CONF_SCL_RST_SLV_EN ( ) != 0 {
}
esp . I2C . SetSCL_SP_CONF_SCL_RST_SLV_NUM ( 0 )
esp . I2C0 . SetSCL_SP_CONF_SCL_RST_SLV_NUM ( 0 )
}
type i2cCommandType = uint32
@ -194,13 +194,13 @@ func nanotime() int64
func ( i2c * I2C ) transmit ( addr uint16 , cmd [ ] i2cCommand , timeoutMS int ) error {
const intMask = esp . I2C_INT_STATUS_END_DETECT_INT_ST_Msk | esp . I2C_INT_STATUS_TRANS_COMPLETE_INT_ST_Msk | esp . I2C_INT_STATUS_TIME_OUT_INT_ST_Msk | esp . I2C_INT_STATUS_NACK_INT_ST_Msk
esp . I2C . INT_CLR . SetBits ( intMask )
esp . I2C . INT_ENA . SetBits ( intMask )
esp . I2C . SetCTR_CONF_UPGATE ( 1 )
esp . I2C0 . INT_CLR . SetBits ( intMask )
esp . I2C0 . INT_ENA . SetBits ( intMask )
esp . I2C0 . SetCTR_CONF_UPGATE ( 1 )
defer func ( ) {
esp . I2C . INT_CLR . SetBits ( intMask )
esp . I2C . INT_ENA . ClearBits ( intMask )
esp . I2C0 . INT_CLR . SetBits ( intMask )
esp . I2C0 . INT_ENA . ClearBits ( intMask )
} ( )
timeoutNS := int64 ( timeoutMS ) * 1000000
@ -208,7 +208,7 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
needRestart := false
readLast := false
var readTo [ ] byte
for cmdIdx , reg := 0 , & esp . I2C . COMD0 ; cmdIdx < len ( cmd ) ; {
for cmdIdx , reg := 0 , & esp . I2C0 . COMD0 ; cmdIdx < len ( cmd ) ; {
c := & cmd [ cmdIdx ]
switch c . cmd {
@ -221,13 +221,13 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
count := 32
if needAddress {
needAddress = false
esp . I2C . SetFIFO_ DATA_FIFO_RDATA ( ( uint32 ( addr ) & 0x7f ) << 1 )
esp . I2C0 . SetDATA_FIFO_RDATA ( ( uint32 ( addr ) & 0x7f ) << 1 )
count --
esp . I2C . SLAVE_ADDR . Set ( uint32 ( addr ) )
esp . I2C . SetCTR_CONF_UPGATE ( 1 )
esp . I2C0 . SLAVE_ADDR . Set ( uint32 ( addr ) )
esp . I2C0 . SetCTR_CONF_UPGATE ( 1 )
}
for ; count > 0 && c . head < len ( c . data ) ; count , c . head = count - 1 , c . head + 1 {
esp . I2C . SetFIFO_ DATA_FIFO_RDATA ( uint32 ( c . data [ c . head ] ) )
esp . I2C0 . SetDATA_FIFO_RDATA ( uint32 ( c . data [ c . head ] ) )
}
reg . Set ( i2cCMD_WRITE | uint32 ( 32 - count ) )
reg = nextAddress ( reg )
@ -243,8 +243,8 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
case i2cCMD_READ :
if needAddress {
needAddress = false
esp . I2C . SetFIFO_ DATA_FIFO_RDATA ( ( uint32 ( addr ) & 0x7f ) << 1 | 1 )
esp . I2C . SLAVE_ADDR . Set ( uint32 ( addr ) )
esp . I2C0 . SetDATA_FIFO_RDATA ( ( uint32 ( addr ) & 0x7f ) << 1 | 1 )
esp . I2C0 . SLAVE_ADDR . Set ( uint32 ( addr ) )
reg . Set ( i2cCMD_WRITE | 1 )
reg = nextAddress ( reg )
}
@ -256,7 +256,7 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
reg . Set ( i2cCMD_WRITE | 1 )
reg = nextAddress ( reg )
esp . I2C . SetFIFO_ DATA_FIFO_RDATA ( ( uint32 ( addr ) & 0x7f ) << 1 | 1 )
esp . I2C0 . SetDATA_FIFO_RDATA ( ( uint32 ( addr ) & 0x7f ) << 1 | 1 )
needRestart = false
}
count := 32
@ -291,11 +291,11 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
}
if reg == nil {
// transmit now
esp . I2C . SetCTR_CONF_UPGATE ( 1 )
esp . I2C . SetCTR_TRANS_START ( 1 )
esp . I2C0 . SetCTR_CONF_UPGATE ( 1 )
esp . I2C0 . SetCTR_TRANS_START ( 1 )
end := nanotime ( ) + timeoutNS
var mask uint32
for mask = esp . I2C . INT_STATUS . Get ( ) ; mask & intMask == 0 ; mask = esp . I2C . INT_STATUS . Get ( ) {
for mask = esp . I2C0 . INT_STATUS . Get ( ) ; mask & intMask == 0 ; mask = esp . I2C0 . INT_STATUS . Get ( ) {
if nanotime ( ) > end {
if readTo != nil {
return errI2CReadTimeout
@ -312,13 +312,13 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
}
return errI2CWriteTimeout
}
esp . I2C . INT_CLR . SetBits ( intMask )
esp . I2C0 . INT_CLR . SetBits ( intMask )
for i := 0 ; i < len ( readTo ) ; i ++ {
readTo [ i ] = byte ( esp . I2C . GetFIFO_ DATA_FIFO_RDATA ( ) & 0xff )
readTo [ i ] = byte ( esp . I2C0 . GetDATA_FIFO_RDATA ( ) & 0xff )
c . head ++
}
readTo = nil
reg = & esp . I2C . COMD0
reg = & esp . I2C0 . COMD0
}
}
return nil