File syn_i2c_queue.c¶
File List > drivers > syn_i2c_queue.c
Go to the documentation of this file
#include "syn_i2c_queue.h"
#include "../port/syn_port_i2c.h"
#include <string.h>
SYN_Status syn_i2c_queue_init(SYN_I2C_Queue *q, uint8_t bus)
{
if (q == NULL) {
return SYN_INVALID_PARAM;
}
memset(q, 0, sizeof(*q));
q->bus = bus;
q->initialized = true;
return SYN_OK;
}
SYN_Status syn_i2c_queue_enqueue(SYN_I2C_Queue *q, const SYN_I2C_Transaction *tx)
{
if (q == NULL || !q->initialized || tx == NULL) {
return SYN_INVALID_PARAM;
}
if (q->count >= SYN_I2C_QUEUE_MAX_DEPTH) {
return SYN_BUSY;
}
q->ring[q->tail] = *tx;
q->tail = (uint16_t)((q->tail + 1) % SYN_I2C_QUEUE_MAX_DEPTH);
q->count++;
return syn_i2c_queue_process(q);
}
SYN_Status syn_i2c_queue_process(SYN_I2C_Queue *q)
{
if (q == NULL || !q->initialized) {
return SYN_INVALID_PARAM;
}
if (q->active) {
return SYN_OK;
}
while (q->count > 0 && !q->active) {
SYN_I2C_Transaction tx = q->ring[q->head];
q->head = (uint16_t)((q->head + 1) % SYN_I2C_QUEUE_MAX_DEPTH);
q->count--;
q->active = true;
SYN_Status status =
syn_port_i2c_transfer(q->bus, tx.addr, tx.tx_data, tx.tx_len, tx.rx_data, tx.rx_len);
q->active = false;
if (tx.callback != NULL) {
tx.callback(q->bus, status, tx.user_data);
}
}
return SYN_OK;
}
SYN_Status syn_i2c_queue_cancel_all(SYN_I2C_Queue *q)
{
if (q == NULL || !q->initialized) {
return SYN_INVALID_PARAM;
}
q->head = 0;
q->tail = 0;
q->count = 0;
q->active = false;
return SYN_OK;
}
size_t syn_i2c_queue_count(const SYN_I2C_Queue *q)
{
if (q == NULL || !q->initialized) {
return 0;
}
return (size_t)q->count;
}