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. | // 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 | ||||||
|  |  | ||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче
	
	 Ayke van Laethem
						Ayke van Laethem