diff options
author | Stefan Adolfsson <sadolfsson@chromium.org> | 2018-05-25 14:47:32 +0200 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-08-22 08:16:01 -0700 |
commit | e8252556d52f897f2ea443e1cdd1bb0ebf7174ab (patch) | |
tree | dabe6d6811a71f5839ef6590a389be47da1b44ce /chip | |
parent | 913a697b7b385f3b03ac16e9c96313139eab3578 (diff) | |
download | chrome-ec-e8252556d52f897f2ea443e1cdd1bb0ebf7174ab.tar.gz |
CEC: Make buffer handling code unit testable
Moving code to common/ to be able to write some unit test. The
API in cec.h will be refactored in a later commit since it does
not look so nice for a common API. However, it is better to do the
refactoring after the unit tests are in place
Signed-off-by: Stefan Adolfsson <sadolfsson@chromium.org>
BUG=b:80288314
BRANCH=none
TEST=emerge-fizz chromeos-ec
Change-Id: I2d675689cc40248d74bf812bd6c86125d681767d
Reviewed-on: https://chromium-review.googlesource.com/1073414
Commit-Ready: Stefan Adolfsson <sadolfsson@chromium.org>
Tested-by: Stefan Adolfsson <sadolfsson@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/npcx/cec.c | 159 |
1 files changed, 1 insertions, 158 deletions
diff --git a/chip/npcx/cec.c b/chip/npcx/cec.c index 73a1c7c1cf..7d4fc3be78 100644 --- a/chip/npcx/cec.c +++ b/chip/npcx/cec.c @@ -4,6 +4,7 @@ */ #include "atomic.h" +#include "cec.h" #include "clock_chip.h" #include "console.h" #include "ec_commands.h" @@ -47,15 +48,6 @@ */ #define CEC_MAX_RESENDS 5 -/* Size of circular buffer used to store incoming CEC messages */ -#define CEC_CIRCBUF_SIZE 20 -#if CEC_CIRCBUF_SIZE < MAX_CEC_MSG_LEN + 1 -#error "Buffer must fit at least a CEC message and a length byte" -#endif -#if CEC_CIRCBUF_SIZE > 255 -#error "Buffer size must not exceed 255 since offsets are uint8_t" -#endif - /* * Free time timing (us). Our free-time is calculated from the end of * the last bit (not from the start). We compensate by having one @@ -190,32 +182,6 @@ enum cap_edge { CAP_EDGE_RISING }; -/* CEC message during transfer */ -struct cec_msg_transfer { - /* The CEC message */ - uint8_t buf[MAX_CEC_MSG_LEN]; - /* Bit offset */ - uint8_t bit; - /* Byte offset */ - uint8_t byte; -}; - -/* - * Circular buffer of completed incoming CEC messages - * ready to be read out by AP - */ -struct cec_rx_cb { - /* Cicular buffer data */ - uint8_t buf[CEC_CIRCBUF_SIZE]; - /* - * Write offset. Updated from interrupt context when we - * have received a complete message. - */ - uint8_t write_offset; - /* Read offset. Updated when AP sends CEC read command */ - uint8_t read_offset; -}; - /* Receive buffer and states */ struct cec_rx { /* @@ -288,12 +254,6 @@ static uint32_t cec_events; /* APB1 frequency. Store divided by 10k to avoid some runtime divisions */ static uint32_t apb1_freq_div_10k; -/* - * Mutex for the read-offset of the circular buffer. Needed since the - * buffer is read and flushed from different contexts - */ -static struct mutex circbuf_readoffset_mutex; - static void send_mkbp_event(uint32_t event) { atomic_or(&cec_events, event); @@ -374,123 +334,6 @@ static void tmr2_stop(void) SET_FIELD(NPCX_TCKC(mdl), NPCX_TCKC_C2CSEL_FIELD, 0); } -static int msgt_get_bit(const struct cec_msg_transfer *msgt) -{ - if (msgt->byte >= MAX_CEC_MSG_LEN) - return 0; - - return msgt->buf[msgt->byte] & (0x80 >> msgt->bit); -} - -static void msgt_set_bit(struct cec_msg_transfer *msgt, int val) -{ - uint8_t bit_flag; - - if (msgt->byte >= MAX_CEC_MSG_LEN) - return; - bit_flag = 0x80 >> msgt->bit; - msgt->buf[msgt->byte] &= ~bit_flag; - if (val) - msgt->buf[msgt->byte] |= bit_flag; -} - -static void msgt_inc_bit(struct cec_msg_transfer *msgt) -{ - if (++(msgt->bit) == 8) { - if (msgt->byte >= MAX_CEC_MSG_LEN) - return; - msgt->bit = 0; - msgt->byte++; - } -} - -static int msgt_is_eom(const struct cec_msg_transfer *msgt, int len) -{ - if (msgt->bit) - return 0; - return (msgt->byte == len); -} - -static void rx_circbuf_flush(struct cec_rx_cb *cb) -{ - mutex_lock(&circbuf_readoffset_mutex); - cb->read_offset = 0; - mutex_unlock(&circbuf_readoffset_mutex); - cb->write_offset = 0; -} - -static int rx_circbuf_push(struct cec_rx_cb *cb, uint8_t *msg, uint8_t msg_len) -{ - int i; - uint32_t offset; - - if (msg_len > MAX_CEC_MSG_LEN || msg_len == 0) - return EC_ERROR_INVAL; - - offset = cb->write_offset; - /* Fill in message length last, if successful. Set to zero for now */ - cb->buf[offset] = 0; - offset = (offset + 1) % CEC_CIRCBUF_SIZE; - - for (i = 0 ; i < msg_len; i++) { - if (offset == cb->read_offset) { - /* Buffer full */ - return EC_ERROR_OVERFLOW; - } - - cb->buf[offset] = msg[i]; - offset = (offset + 1) % CEC_CIRCBUF_SIZE; - } - - /* - * Don't commit if we caught up with read-offset - * since that would indicate an empty buffer - */ - if (offset == cb->read_offset) { - /* Buffer full */ - return EC_ERROR_OVERFLOW; - } - - /* Commit the push */ - cb->buf[cb->write_offset] = msg_len; - cb->write_offset = offset; - - return EC_SUCCESS; -} - -static int rx_circbuf_pop(struct cec_rx_cb *cb, uint8_t *msg, uint8_t *msg_len) -{ - int i; - - mutex_lock(&circbuf_readoffset_mutex); - if (cb->read_offset == cb->write_offset) { - /* Circular buffer empty */ - mutex_unlock(&circbuf_readoffset_mutex); - *msg_len = 0; - return -1; - } - - /* The first byte in the buffer is the message length */ - *msg_len = cb->buf[cb->read_offset]; - if (*msg_len == 0 || *msg_len > MAX_CEC_MSG_LEN) { - mutex_unlock(&circbuf_readoffset_mutex); - *msg_len = 0; - CPRINTF("Invalid CEC msg size: %u\n", *msg_len); - return -1; - } - - cb->read_offset = (cb->read_offset + 1) % CEC_CIRCBUF_SIZE; - for (i = 0; i < *msg_len; i++) { - msg[i] = cb->buf[cb->read_offset]; - cb->read_offset = (cb->read_offset + 1) % CEC_CIRCBUF_SIZE; - - } - - mutex_unlock(&circbuf_readoffset_mutex); - - return 0; -} - void enter_state(enum cec_state new_state) { int gpio = -1, timeout = -1; |