MCPcopy Create free account
hub / github.com/TactilityProject/Tactility / start

Function start

Drivers/m5pm1-module/source/m5pm1.cpp:64–130  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

62// ---------------------------------------------------------------------------
63
64static error_t start(Device* device) {
65 Device* i2c = device_get_parent(device);
66 if (device_get_type(i2c) != &I2C_CONTROLLER_TYPE) {
67 LOG_E(TAG, "Parent is not an I2C controller");
68 return ERROR_RESOURCE;
69 }
70
71 const uint8_t addr = GET_CONFIG(device)->address;
72
73 // M5PM1 enters I2C sleep after inactivity. The first transaction after sleep
74 // is ignored as the chip wakes up. Retry with increasing delays until ACK.
75 bool awake = false;
76 for (int attempt = 0; attempt < 5; attempt++) {
77 uint8_t chip_id = 0;
78 if (i2c_controller_register8_get(i2c, addr, REG_DEVICE_ID, &chip_id, TIMEOUT) == ERROR_NONE) {
79 LOG_I(TAG, "M5PM1 online (chip_id=0x%02X)", chip_id);
80 awake = true;
81 break;
82 }
83 vTaskDelay(pdMS_TO_TICKS(20 * (attempt + 1)));
84 }
85
86 if (!awake) {
87 LOG_E(TAG, "M5PM1 not responding — LCD power will not be enabled");
88 return ERROR_NONE; // non-fatal: don't crash the kernel
89 }
90
91 // Disable I2C idle sleep so the PMIC stays reachable on battery power
92 if (i2c_controller_register8_set(i2c, addr, REG_I2C_CFG, 0x00, TIMEOUT) != ERROR_NONE) {
93 LOG_W(TAG, "Failed to disable I2C sleep (non-fatal)");
94 }
95
96 // BOOST_EN → EXT_5V / Grove / Hat power rail always on
97 if (i2c_controller_register8_set_bits(i2c, addr, REG_PWR_CFG, PWR_CFG_BOOST_EN, TIMEOUT) == ERROR_NONE) {
98 LOG_I(TAG, "EXT_5V boost enabled");
99 } else {
100 LOG_W(TAG, "Failed to enable EXT_5V boost (non-fatal)");
101 }
102
103 // PM1_G2 → LCD power enable (L3B rail on StickS3)
104 // Sequence matches M5GFX: clear FUNC0 bit2, set MODE bit2 output, clear DRV bit2 push-pull, set OUT bit2 high
105 bool lcd_ok =
106 i2c_controller_register8_reset_bits(i2c, addr, REG_GPIO_FUNC0, LCD_POWER_BIT, TIMEOUT) == ERROR_NONE &&
107 i2c_controller_register8_set_bits (i2c, addr, REG_GPIO_MODE, LCD_POWER_BIT, TIMEOUT) == ERROR_NONE &&
108 i2c_controller_register8_reset_bits(i2c, addr, REG_GPIO_DRV, LCD_POWER_BIT, TIMEOUT) == ERROR_NONE &&
109 i2c_controller_register8_set_bits (i2c, addr, REG_GPIO_OUT, LCD_POWER_BIT, TIMEOUT) == ERROR_NONE;
110
111 if (lcd_ok) {
112 LOG_I(TAG, "LCD power enabled via PM1_G2");
113 } else {
114 LOG_E(TAG, "Failed to enable LCD power via PM1_G2");
115 }
116
117 // PM1_G3 → speaker amp EN, initially LOW (amp off until audio starts)
118 bool spk_ok =
119 i2c_controller_register8_reset_bits(i2c, addr, REG_GPIO_FUNC0, SPEAKER_AMP_FUNC_MASK, TIMEOUT) == ERROR_NONE &&
120 i2c_controller_register8_set_bits (i2c, addr, REG_GPIO_MODE, SPEAKER_AMP_BIT, TIMEOUT) == ERROR_NONE &&
121 i2c_controller_register8_reset_bits(i2c, addr, REG_GPIO_DRV, SPEAKER_AMP_BIT, TIMEOUT) == ERROR_NONE &&

Callers 2

startLvglMethod · 0.50
startLvglMethod · 0.50

Tested by

no test coverage detected