TxBuffer.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "TxBuffer.h" | ||
| 2 | #include "esp_log.h" | ||
| 3 | |||
| 4 | // Logged as part of the radio code it came from. | ||
| 5 | static const char *TAG = "Somfy"; | ||
| 6 | |||
| 7 | 38 | int8_t somfy_tx_queue_t::oldest() const { | |
| 8 | // The newest index is at position 0 so the oldest is the last one in use. | ||
| 9 | 160 | for(int8_t i = MAX_TX_BUFFER - 1; i >= 0; i--) { | |
| 10 | 155 | if(this->index[i] < MAX_TX_BUFFER) return i; | |
| 11 | } | ||
| 12 | 5 | return -1; | |
| 13 | } | ||
| 14 | 5 | bool somfy_tx_queue_t::peek(somfy_tx_t *tx) const { | |
| 15 | 5 | const int8_t i = this->oldest(); | |
| 16 | 5 | if(i < 0) return false; | |
| 17 | 3 | memcpy(tx, &this->items[this->index[i]], sizeof(somfy_tx_t)); | |
| 18 | 3 | return true; | |
| 19 | } | ||
| 20 | 33 | bool somfy_tx_queue_t::pop(somfy_tx_t *tx) { | |
| 21 | 33 | const int8_t i = this->oldest(); | |
| 22 | 33 | if(i < 0) return false; | |
| 23 | 30 | uint8_t ndx = this->index[i]; | |
| 24 | 30 | memcpy(tx, &this->items[ndx], sizeof(somfy_tx_t)); | |
| 25 | 30 | this->items[ndx].clear(); | |
| 26 | 30 | if(this->length > 0) this->length--; | |
| 27 | 30 | this->index[i] = 255; | |
| 28 | 30 | return true; | |
| 29 | } | ||
| 30 | 36 | void somfy_tx_queue_t::push(uint8_t hwsync, uint8_t *payload, uint8_t bit_length) { | |
| 31 | 36 | if(this->length >= MAX_TX_BUFFER) { | |
| 32 | // We have overflowed the buffer simply empty the last item | ||
| 33 | // in this instance we will simply throw it away. | ||
| 34 | 2 | uint8_t ndx = this->index[MAX_TX_BUFFER - 1]; | |
| 35 | 2 | if(ndx < MAX_TX_BUFFER) this->items[ndx].clear(); | |
| 36 | 2 | this->index[MAX_TX_BUFFER - 1] = 255; | |
| 37 | 2 | this->length--; | |
| 38 | } | ||
| 39 | 36 | uint8_t first = 0; | |
| 40 | // Place this record in the first empty slot. There will | ||
| 41 | // be one since we cleared a space above should there | ||
| 42 | // be an overflow. | ||
| 43 | 62 | for(uint8_t i = 0; i < MAX_TX_BUFFER; i++) { | |
| 44 | 62 | if(this->items[i].bit_length == 0) { | |
| 45 | 36 | first = i; | |
| 46 | 36 | this->items[i].bit_length = bit_length; | |
| 47 | 36 | this->items[i].hwsync = hwsync; | |
| 48 | 36 | memcpy(&this->items[i].payload, payload, sizeof(this->items[i].payload)); | |
| 49 | 36 | break; | |
| 50 | } | ||
| 51 | } | ||
| 52 | // Move the index so that it is the at position 0. The oldest item will fall off. | ||
| 53 | 180 | for(uint8_t i = MAX_TX_BUFFER - 1; i > 0; i--) { | |
| 54 | 144 | this->index[i] = this->index[i - 1]; | |
| 55 | } | ||
| 56 | 36 | this->length++; | |
| 57 | // When popping from the queue we always pull from the end | ||
| 58 | 36 | this->index[0] = first; | |
| 59 | 36 | } | |
| 60 | 49 | void encodeTxJob(somfy_tx_job_t &job, somfy_frame_t &frame, uint8_t repeat) { | |
| 61 | 49 | frame.encodeFrame(job.tx.payload); | |
| 62 | 49 | job.tx.hwsync = frame.bitLength == 56 ? 2 : 12; | |
| 63 | 49 | job.tx.bit_length = frame.bitLength; | |
| 64 | 49 | job.frame = frame; | |
| 65 | 49 | if(repeat > TX_MAX_REPEATS) { | |
| 66 | ESP_LOGW(TAG, "Limiting %u repeats to %u", repeat, TX_MAX_REPEATS); | ||
| 67 | 3 | repeat = TX_MAX_REPEATS; | |
| 68 | } | ||
| 69 | 49 | job.repeats = repeat; | |
| 70 | 49 | } | |
| 71 | 4 | void encodeRepeatJob(somfy_tx_job_t &job, somfy_frame_t &frame, uint8_t repeat) { | |
| 72 | 4 | encodeTxJob(job, frame, repeat); | |
| 73 | 4 | job.firstRepeat = frame.repeats + 2; | |
| 74 | 4 | } | |
| 75 | 2 | void noteRepeatQueued(somfy_frame_t &frame, const somfy_tx_job_t &job) { | |
| 76 | // Only advance the counter for frames that will go on air. | ||
| 77 | 2 | frame.repeats += job.repeats + 1; | |
| 78 | 2 | } | |
| 79 |