forked from arendst/Tasmota
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Berry drivers for PCA9535 (generic and in SenseCAP D1) (arendst#22451)
- Loading branch information
1 parent
ec4aec9
commit 3336777
Showing
4 changed files
with
126 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/******************************************************************** | ||
* Tasmota LVGL lv_signal_bars widget | ||
* Drivers for AXP192 and AXP202 I2C Solidified | ||
*******************************************************************/ | ||
#include "solidify/solidified_i2c_axp192.h" | ||
#include "solidify/solidified_i2c_axp202.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
################################################################################# | ||
# Generic driver for PCA9535 - solidified | ||
# | ||
# I2C IO Expander, similar to PCA9557 | ||
# Datasheet: https://www.nxp.com/docs/en/data-sheet/PCA9535_PCA9535C.pdf | ||
# | ||
# This expander is used in SeedStudio SenseCAP D1 | ||
################################################################################# | ||
|
||
#@ solidify:PCA9535 | ||
class PCA9535 : I2C_Driver | ||
var last_read # time when last read (avoid reading too often) | ||
var input_port # shadow of registers 0+1 with state of input registers | ||
var output_port # shadow of registers 2+3 with known outputs | ||
var inversion_port # shadow of registers 4+5 with input inversion | ||
var config_port # shadow of registers 6+7 with Input/Output configurations | ||
|
||
def init(address) | ||
if (address == nil) address = 0x20 end # default address is 0x20 | ||
super(self).init("PCA9535", address) | ||
self.last_read = 0 | ||
if self.wire | ||
# if detected | ||
self.read_all() | ||
end | ||
end | ||
|
||
def read_all() | ||
var now = tasmota.millis() | ||
if (now - self.last_read > 10) # if last read was more than 10 ms in the past | ||
self.input_port = self.read16LE(0x00) | ||
self.output_port = self.read16LE(0x02) | ||
self.inversion_port = self.read16LE(0x04) | ||
self.config_port = self.read16LE(0x06) | ||
self.last_read = tasmota.millis() | ||
if tasmota.loglevel(4) | ||
log(f"I2C: PCA9535 read input(0x{self.input_port:04X}) output(0x{self.output_port:04X}) inversion(0x{self.inversion_port:04X}) config(0x{self.config_port:04X})") | ||
end | ||
end | ||
end | ||
|
||
def config_all(v) | ||
self.config_port = int(v) | ||
self.write16LE(0x06, self.config_port) | ||
end | ||
# port: 0..15 | ||
# mode: 0=output 1=input | ||
def config_gpio(port, mode) | ||
self.read_all() | ||
if (mode != 0 && mode != 1) raise "value_error", f"mode muste be 0 or 1" end | ||
var config_new = self._bit_set_to(self.config_port, port, mode) | ||
# write only if value changed | ||
if config_new != self.config_port | ||
self.config_all(config_new) | ||
end | ||
end | ||
|
||
def read_gpio(port) | ||
self.read_all() | ||
return (self.input_port & (1 << port)) ? 1 : 0 | ||
end | ||
|
||
def write_gpio(port, v) | ||
self.read_all() | ||
v = (v ? 1 : 0) # ensure we have only 0/1 as values | ||
var output_new = self._bit_set_to(self.output_port, port, v) | ||
if output_new != self.output_port | ||
self.output_port = output_new | ||
self.write16LE(0x02, self.output_port) | ||
end | ||
end | ||
|
||
# inspired from https://stackoverflow.com/questions/47981/how-to-set-clear-and-toggle-a-single-bit | ||
# num: int value | ||
# n: bit to change | ||
# x: value 0/1 | ||
static def _bit_set_to(num, n, x) | ||
return (num & ~(1 << n)) | (x << n) | ||
end | ||
end | ||
|
||
return PCA9535 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
################################################################################# | ||
# Specialized driver for SeedStudio SenseCAP D1 display | ||
################################################################################# | ||
|
||
import PCA9535 | ||
|
||
class PCA9535_SenseCAP_D1 : PCA9535 | ||
def init() | ||
super(self).init(0x20) | ||
|
||
if self.wire | ||
self.write_gpio(0x05, 1) # set IO0.5 (LCD_RESET) high | ||
self.write_gpio(0x07, 1) # set IO0.7 (TOUCH_RESET) high | ||
self.write_gpio(0x08, 1) # set IO1.0 (RP2040_RESET) high | ||
self.config_gpio(0x05, 0) # configure IO0.5 (LCD_RESET) as output | ||
self.config_gpio(0x07, 0) # configure IO0.7 (TOUCH_RESET) as output | ||
self.config_gpio(0x08, 0) # configure IO1.0 (RP2040_RESET) as output | ||
# reset display at boot | ||
self.reset_display() | ||
end | ||
end | ||
|
||
# hardware reset for the MCU RP2040 | ||
def reset_RP2040() | ||
self.write_gpio(0x08, 0) # drive RESET Low | ||
tasmota.delay(2) # the recommended delay is 1ms, we take some margin | ||
self.write_gpio(0x08, 1) # drive RESET High | ||
end | ||
|
||
# reset both display and touch screen | ||
def reset_display() | ||
self.write_gpio(0x05, 0) | ||
self.write_gpio(0x07, 0) | ||
tasmota.delay(2) | ||
self.write_gpio(0x05, 1) | ||
self.write_gpio(0x07, 1) | ||
tasmota.delay(50) | ||
end | ||
|
||
end | ||
|
||
return PCA9535_SenseCAP_D1() |