39 #if defined(PIOS_INCLUDE_COM)
48 enum pios_com_dev_magic {
49 PIOS_COM_DEV_MAGIC = 0xaa55aa55,
53 enum pios_com_dev_magic
magic;
59 #if defined(PIOS_INCLUDE_RTOS)
67 static bool PIOS_COM_validate(
struct pios_com_dev *com_dev)
69 return (com_dev && (com_dev->magic == PIOS_COM_DEV_MAGIC));
72 static struct pios_com_dev *PIOS_COM_alloc(
void)
74 struct pios_com_dev *com_dev;
76 com_dev = (
struct pios_com_dev *)
PIOS_malloc(
sizeof(*com_dev));
77 if (!com_dev)
return (NULL);
79 memset(com_dev, 0,
sizeof(*com_dev));
80 com_dev->magic = PIOS_COM_DEV_MAGIC;
84 static uint16_t PIOS_COM_TxOutCallback(uintptr_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom,
bool * need_yield);
85 static uint16_t PIOS_COM_RxInCallback(uintptr_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom,
bool * need_yield);
86 static void PIOS_COM_UnblockRx(
struct pios_com_dev *com_dev,
bool * need_yield);
87 static void PIOS_COM_UnblockTx(
struct pios_com_dev *com_dev,
bool * need_yield);
96 int32_t
PIOS_COM_Init(uintptr_t * com_id,
const struct pios_com_driver * driver, uintptr_t lower_id, uint16_t rx_buffer_len, uint16_t tx_buffer_len)
105 struct pios_com_dev *com_dev;
107 com_dev = (
struct pios_com_dev *) PIOS_COM_alloc();
108 if (!com_dev)
goto out_fail;
110 com_dev->driver = driver;
111 com_dev->lower_id = lower_id;
118 if (!com_dev->rx)
goto out_fail;
119 #if defined(PIOS_INCLUDE_RTOS)
122 (com_dev->driver->bind_rx_cb)(lower_id, PIOS_COM_RxInCallback, (uintptr_t)com_dev);
123 if (com_dev->driver->rx_start) {
125 (com_dev->driver->rx_start)(com_dev->lower_id,
132 if (!com_dev->tx)
goto out_fail;
133 #if defined(PIOS_INCLUDE_RTOS)
136 (com_dev->driver->bind_tx_cb)(lower_id, PIOS_COM_TxOutCallback, (uintptr_t)com_dev);
138 #if defined(PIOS_INCLUDE_RTOS)
142 *com_id = (uintptr_t)com_dev;
149 static void PIOS_COM_UnblockRx(
struct pios_com_dev *com_dev,
bool * need_yield)
151 #if defined(PIOS_INCLUDE_RTOS)
159 static void PIOS_COM_UnblockTx(
struct pios_com_dev *com_dev,
bool * need_yield)
161 #if defined(PIOS_INCLUDE_RTOS)
169 static uint16_t PIOS_COM_RxInCallback(uintptr_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom,
bool * need_yield)
171 struct pios_com_dev *com_dev = (
struct pios_com_dev *)context;
173 bool valid = PIOS_COM_validate(com_dev);
180 if (bytes_into_fifo > 0) {
182 PIOS_COM_UnblockRx(com_dev, need_yield);
189 return (bytes_into_fifo);
192 static uint16_t PIOS_COM_TxOutCallback(uintptr_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom,
bool * need_yield)
194 struct pios_com_dev *com_dev = (
struct pios_com_dev *)context;
196 bool valid = PIOS_COM_validate(com_dev);
205 if (bytes_from_fifo > 0) {
207 PIOS_COM_UnblockTx(com_dev, need_yield);
214 return (bytes_from_fifo);
226 struct pios_com_dev *com_dev = (
struct pios_com_dev *)com_id;
228 if (!PIOS_COM_validate(com_dev)) {
234 if (com_dev->driver->set_baud) {
235 com_dev->driver->set_baud(com_dev->lower_id, baud);
241 static int32_t SendBufferNonBlockingImpl(uintptr_t com_id,
const uint8_t *buffer, uint16_t len,
bool all_or_nothing)
243 struct pios_com_dev *com_dev = (
struct pios_com_dev *)com_id;
245 if (!PIOS_COM_validate(com_dev)) {
252 #if defined(PIOS_INCLUDE_RTOS)
257 if (com_dev->driver->available && !com_dev->driver->available(com_dev->lower_id)) {
269 #if defined(PIOS_INCLUDE_RTOS)
276 if (all_or_nothing) {
281 if (len > tot_avail) {
282 #if defined(PIOS_INCLUDE_RTOS)
294 if (com_dev->driver->tx_start) {
298 com_dev->driver->tx_start(com_dev->lower_id,
302 #if defined(PIOS_INCLUDE_RTOS)
305 return (bytes_into_fifo);
322 return SendBufferNonBlockingImpl(com_id, buffer, len,
true);
337 struct pios_com_dev *com_dev = (
struct pios_com_dev *)com_id;
339 if (!PIOS_COM_validate(com_dev)) {
348 int32_t rc = SendBufferNonBlockingImpl(com_id, buffer,
353 }
else if (rc == 0) {
464 va_start(args, format);
465 vsprintf((
char *)buffer, format, args);
485 va_start(args, format);
486 vsprintf((
char *)buffer, format, args);
498 struct pios_com_dev *com_dev = (
struct pios_com_dev *)com_id;
500 if (!PIOS_COM_validate(com_dev)) {
511 if (rx_pending == 0) {
514 if (com_dev->driver->rx_start) {
515 uint16_t bytes_available = 0;
521 (com_dev->driver->rx_start)(com_dev->lower_id,
541 uint16_t bytes_from_fifo;
543 struct pios_com_dev *com_dev = (
struct pios_com_dev *)com_id;
545 if (!PIOS_COM_validate(com_dev)) {
552 if (com_dev->rx_sem) {
559 if (bytes_from_fifo == 0) {
562 if (com_dev->driver->rx_start) {
564 uint16_t rx_space_avail;
568 (com_dev->driver->rx_start)(com_dev->lower_id,
571 if (timeout_ms > 0) {
572 #if defined(PIOS_INCLUDE_RTOS)
587 return (bytes_from_fifo);
597 struct pios_com_dev *com_dev = (
struct pios_com_dev *)com_id;
599 if (!PIOS_COM_validate(com_dev)) {
605 if (com_dev->driver->available == NULL)
608 return (com_dev->driver->available)(com_dev->lower_id);
612 struct pios_com_dev *com_dev = (
struct pios_com_dev *)com_id;
614 if (!PIOS_COM_validate(com_dev)) {
618 return com_dev->lower_id;
int32_t PIOS_COM_SendString(uintptr_t com_id, const char *str)
uint16_t circ_queue_read_data(circ_queue_t q, void *buf, uint16_t num)
int32_t PIOS_COM_SendBufferNonBlocking(uintptr_t com_id, const uint8_t *buffer, uint16_t len)
Main PiOS header to include all the compiled in PiOS options.
int32_t PIOS_COM_SendFormattedStringNonBlocking(uintptr_t com_id, const char *format,...)
void(* bind_tx_cb)(uintptr_t id, pios_com_callback tx_out_cb, uintptr_t context)
uint16_t circ_queue_write_data(circ_queue_t q, const void *buf, uint16_t num)
void * PIOS_malloc(size_t size)
bool PIOS_Semaphore_Give_FromISR(struct pios_semaphore *sema, bool *woken)
void * circ_queue_write_pos(circ_queue_t q, uint16_t *contig, uint16_t *avail)
bool PIOS_Mutex_Unlock(struct pios_mutex *mtx)
struct pios_mutex * PIOS_Mutex_Create(void)
circ_queue_t circ_queue_new(uint16_t elem_size, uint16_t num_elem)
int32_t PIOS_COM_SendStringNonBlocking(uintptr_t com_id, const char *str)
int32_t PIOS_COM_SendChar(uintptr_t com_id, char c)
bool PIOS_IRQ_InISR(void)
uint16_t PIOS_COM_ReceiveBuffer(uintptr_t com_id, uint8_t *buf, uint16_t buf_len, uint32_t timeout_ms)
struct pios_semaphore * PIOS_Semaphore_Create(void)
Creates a binary semaphore.
uintptr_t PIOS_COM_GetDriverCtx(uintptr_t com_id)
bool PIOS_Semaphore_Give(struct pios_semaphore *sema)
Gives binary semaphore.
int32_t PIOS_COM_SendFormattedString(uintptr_t com_id, const char *format,...)
Public header for 1 reader, 1 writer circular queue.
uint16_t PIOS_COM_GetNumReceiveBytesPending(uintptr_t com_id)
PIOS_COM_SendBuffer(shub_global->frsky_port, shub_global->serial_buf, msg_length)
int32_t PIOS_COM_SendCharNonBlocking(uintptr_t com_id, char c)
int32_t PIOS_COM_Init(uintptr_t *com_id, const struct pios_com_driver *driver, uintptr_t lower_id, uint16_t rx_buffer_len, uint16_t tx_buffer_len)
bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms)
Takes binary semaphore.
int vsprintf(char *out, const char *format, va_list args)
void circ_queue_clear(circ_queue_t q)
int32_t PIOS_COM_SendBufferStallTimeout(uintptr_t com_id, const uint8_t *buffer, uint16_t len, uint32_t max_ms)
void(* bind_rx_cb)(uintptr_t id, pios_com_callback rx_in_cb, uintptr_t context)
#define PIOS_Assert(test)
void * circ_queue_read_pos(circ_queue_t q, uint16_t *contig, uint16_t *avail)
int32_t PIOS_DELAY_WaitmS(uint32_t mS)
int32_t PIOS_COM_ChangeBaud(uintptr_t com_id, uint32_t baud)
bool PIOS_COM_Available(uintptr_t com_id)
bool PIOS_Mutex_Lock(struct pios_mutex *mtx, uint32_t timeout_ms)