Skip to content

Commit

Permalink
Reduce IRAM consumption of HDMI CEC to 1453 bytes (#19452)
Browse files Browse the repository at this point in the history
* Reduce IRAM consumption of HDMI CEC to 1453 bytes

* Add changelog
  • Loading branch information
s-hadinger committed Sep 3, 2023
1 parent bb4d991 commit c6938e2
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 26 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.

### Changed
- Berry fast_loop is now called every 5ms whatever the Sleep value
- Reduce IRAM consumption of HDMI CEC to 1453 bytes

### Fixed
- PCF8574 mode 1 with base relays exception 3/28 regression from v12.4.0.4 (#19408)
Expand Down
2 changes: 1 addition & 1 deletion tasmota/my_user_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@
#endif // USE_SPI

// -- One wire sensors ----------------------------
// #define USE_HDMI_CEC // Add support for HDMI CEC bus (+7k code)
// #define USE_HDMI_CEC // Add support for HDMI CEC bus (+7k code, 1456 bytes IRAM)

// -- Serial sensors ------------------------------
//#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
Expand Down
46 changes: 21 additions & 25 deletions tasmota/tasmota_xdrv_driver/xdrv_70_0_hdmi_cec.ino
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#endif

volatile uint32_t cec_isr_count = 0;
volatile uint32_t cec_isr_rcv_count = 0;

/*********************************************************************************************\
* Ring buffer class that allows the ISR to publish logs and messages to the main event loop
Expand Down Expand Up @@ -91,31 +90,35 @@ public:
// returns true if ok, false if full
bool IRAM_ATTR push(const volatile uint8_t *buf, uint8_t len, CEC_MSG_TYPE type, bool ack) {
// AddLog(LOG_LEVEL_INFO, ">>>: push len=%i type=%i ack=%i", len, type, ack);
if (_msg[_cur_idx].type != MSG_EMPTY) {
uint32_t cur_idx = _cur_idx; // read only once the volatile value
CEC_msg_t *msg = &_msg[cur_idx];
if (msg->type != MSG_EMPTY) {
return false;
}
memmove(_msg[_cur_idx].buf, (uint8_t*) buf, CEC_BUF_SIZE);
_msg[_cur_idx].ack = ack;
_msg[_cur_idx].len = len;
_msg[_cur_idx].type = type;
_cur_idx = (_cur_idx + 1) % CEC_RING_SIZE;
memmove(&msg->buf, (uint8_t*) buf, CEC_BUF_SIZE);
msg->ack = ack;
msg->len = len;
msg->type = type;
_cur_idx = (cur_idx + 1) % CEC_RING_SIZE;
return true;
}

// returns true if ok, false if full
bool IRAM_ATTR log(uint32_t timing_expected_low, uint32_t timing_expected_high, uint32_t timing, uint16_t code, uint8_t state, bool line) {
#ifdef HDMI_DEBUG
if (_msg[_cur_idx].type != MSG_EMPTY) {
uint32_t cur_idx = _cur_idx; // read only once the volatile value
CEC_msg_t *msg = &_msg[cur_idx];
if (msg->type != MSG_EMPTY) {
return false;
}
_msg[_cur_idx].type = MSG_LOG;
_msg[_cur_idx].timing_expected_low = timing_expected_low;
_msg[_cur_idx].timing_expected_high = timing_expected_high;
_msg[_cur_idx].timing = timing;
_msg[_cur_idx].code = code;
_msg[_cur_idx].state = state;
_msg[_cur_idx].line = line;
_cur_idx = (_cur_idx + 1) % CEC_RING_SIZE;
msg->type = MSG_LOG;
msg->timing_expected_low = timing_expected_low;
msg->timing_expected_high = timing_expected_high;
msg->timing = timing;
msg->code = code;
msg->state = state;
msg->line = line;
_cur_idx = (cur_idx + 1) % CEC_RING_SIZE;
#endif
return true;
}
Expand Down Expand Up @@ -248,7 +251,7 @@ public:
void checkMessages(); // check regularly for mailbox
// signal to Tasmota to exit the normal sleep and trigger a new tick event in the next millisecond
void enableISR(void);
void IRAM_ATTR serviceGpioISR(void); // handle the ISR on the CEC GPIO
inline void IRAM_ATTR serviceGpioISR(void) { runReceiveISR(); }; // handle the ISR on the CEC GPIO
bool transmitRaw(const unsigned char* buffer, unsigned int count);

// Getters
Expand Down Expand Up @@ -474,7 +477,7 @@ void CEC_Device::start(void) {
///
/// The state machine works in blocking mode
///
void IRAM_ATTR CEC_Device::runTransmit() {
void CEC_Device::runTransmit() {
if (!_xmit_wait_ms) {
// we haven't waited for the signal to stabilize yet
// compute the number of milliseconds to wait for in fast loop
Expand Down Expand Up @@ -716,7 +719,6 @@ void IRAM_ATTR CEC_Device::runTransmit() {
void IRAM_ATTR CEC_Device::runReceiveISR() {
if (isTransmitting()) { return; } // ignore any interrupt caused or during active transmission

cec_isr_rcv_count += 1;
// update timing information for new iteration
uint32_t now = micros();
if (!now) { now = 1; } // avoid now == 0 which has a special meaning
Expand Down Expand Up @@ -1055,12 +1057,6 @@ void CEC_Device::enableISR(void) {
}
}

// Service gpio ISR
void IRAM_ATTR CEC_Device::serviceGpioISR(void) {
cec_isr_count += 1;
runReceiveISR();
}

/*********************************************************************************************\
* General methods
\*********************************************************************************************/
Expand Down

0 comments on commit c6938e2

Please sign in to comment.