mirror of https://gerrit.osmocom.org/libosmocore
sercomm: Better integration of driver interface
We cannot assume a certain UART API like uart_baudrate() which only exists in OsmocomBB. Rather, use generic function prototypes (sercomm_drv_*) which are to be provided by the application / environment to the sercomm core. Change-Id: I01ea3067baf1791000c1a7d537ccce496a1ab1ee
This commit is contained in:
parent
a362ee90b4
commit
799bef5cf6
|
@ -58,12 +58,6 @@ struct osmo_sercomm_inst {
|
|||
};
|
||||
|
||||
|
||||
#ifdef EMBEDDED
|
||||
#include <uart.h>
|
||||
/* helper functions for target */
|
||||
void osmo_sercomm_change_speed(struct osmo_sercomm_inst *sercomm, enum uart_baudrate bdrt);
|
||||
#endif
|
||||
|
||||
void osmo_sercomm_init(struct osmo_sercomm_inst *sercomm);
|
||||
int osmo_sercomm_initialized(struct osmo_sercomm_inst *sercomm);
|
||||
|
||||
|
@ -74,11 +68,18 @@ unsigned int osmo_sercomm_tx_queue_depth(struct osmo_sercomm_inst *sercomm, uint
|
|||
/* User Interface: Rx */
|
||||
int osmo_sercomm_register_rx_cb(struct osmo_sercomm_inst *sercomm, uint8_t dlci, dlci_cb_t cb);
|
||||
|
||||
int osmo_sercomm_change_speed(struct osmo_sercomm_inst *sercomm, uint32_t bdrt);
|
||||
|
||||
/* Driver Interface */
|
||||
|
||||
int osmo_sercomm_drv_pull(struct osmo_sercomm_inst *sercomm, uint8_t *ch);
|
||||
int osmo_sercomm_drv_rx_char(struct osmo_sercomm_inst *sercomm, uint8_t ch);
|
||||
|
||||
extern void sercomm_drv_lock(unsigned long *flags);
|
||||
extern void sercomm_drv_unlock(unsigned long *flags);
|
||||
extern void sercomm_drv_start_tx(struct osmo_sercomm_inst *sercomm);
|
||||
extern int sercomm_drv_baudrate_chg(struct osmo_sercomm_inst *sercomm, uint32_t bdrt);
|
||||
|
||||
static inline struct msgb *osmo_sercomm_alloc_msgb(unsigned int len)
|
||||
{
|
||||
return msgb_alloc_headroom(len+4, 4, "sercomm_tx");
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
@ -30,31 +32,20 @@
|
|||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
#ifndef EMBEDDED
|
||||
|
||||
# define DEFAULT_RX_MSG_SIZE 2048
|
||||
static inline void sercomm_drv_lock(unsigned long __attribute__((unused)) *flags) {}
|
||||
static inline void sercomm_drv_unlock(unsigned long __attribute__((unused)) *flags) {}
|
||||
|
||||
void sercomm_drv_lock(unsigned long __attribute__((unused)) *flags) {}
|
||||
void sercomm_drv_unlock(unsigned long __attribute__((unused)) *flags) {}
|
||||
#else
|
||||
|
||||
# define DEFAULT_RX_MSG_SIZE 256
|
||||
# include <debug.h>
|
||||
# include <asm/system.h>
|
||||
#endif /* EMBEDDED */
|
||||
|
||||
static inline void sercomm_drv_lock(unsigned long *flags)
|
||||
/* weak symbols to be overridden by application */
|
||||
__attribute__((weak)) void sercomm_drv_start_tx(struct osmo_sercomm_inst *sercomm) {};
|
||||
__attribute__((weak)) int sercomm_drv_baudrate_chg(struct osmo_sercomm_inst *sercomm, uint32_t bdrt)
|
||||
{
|
||||
local_firq_save(*flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void sercomm_drv_unlock(unsigned long *flags)
|
||||
{
|
||||
local_irq_restore(*flags);
|
||||
}
|
||||
|
||||
# include <uart.h>
|
||||
|
||||
#endif
|
||||
|
||||
#define HDLC_FLAG 0x7E
|
||||
#define HDLC_ESCAPE 0x7D
|
||||
|
||||
|
@ -107,10 +98,8 @@ void osmo_sercomm_sendmsg(struct osmo_sercomm_inst *sercomm, uint8_t dlci, struc
|
|||
msgb_enqueue(&sercomm->tx.dlci_queues[dlci], msg);
|
||||
sercomm_drv_unlock(&flags);
|
||||
|
||||
#ifdef EMBEDDED
|
||||
/* tell UART that we have something to send */
|
||||
uart_irq_enable(sercomm->uart_id, UART_IRQ_TX_EMPTY, 1);
|
||||
#endif
|
||||
sercomm_drv_start_tx(sercomm);
|
||||
}
|
||||
|
||||
/* how deep is the Tx queue for a given DLCI */
|
||||
|
@ -126,10 +115,9 @@ unsigned int osmo_sercomm_tx_queue_depth(struct osmo_sercomm_inst *sercomm, uint
|
|||
return num;
|
||||
}
|
||||
|
||||
#ifdef EMBEDDED
|
||||
/* wait until everything has been transmitted, then grab the lock and
|
||||
* change the baud rate as requested */
|
||||
void osmo_sercomm_change_speed(struct osmo_sercomm_inst *sercomm, enum uart_baudrate bdrt)
|
||||
int osmo_sercomm_change_speed(struct osmo_sercomm_inst *sercomm, uint32_t bdrt)
|
||||
{
|
||||
unsigned int i, count;
|
||||
unsigned long flags;
|
||||
|
@ -138,7 +126,7 @@ void osmo_sercomm_change_speed(struct osmo_sercomm_inst *sercomm, enum uart_baud
|
|||
/* count the number of pending messages */
|
||||
count = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(sercomm->tx.dlci_queues); i++)
|
||||
count += sercomm_tx_queue_depth(i);
|
||||
count += osmo_sercomm_tx_queue_depth(sercomm, i);
|
||||
/* if we still have any in the queue, restart */
|
||||
if (count == 0)
|
||||
break;
|
||||
|
@ -149,15 +137,16 @@ void osmo_sercomm_change_speed(struct osmo_sercomm_inst *sercomm, enum uart_baud
|
|||
* stays that way */
|
||||
sercomm_drv_lock(&flags);
|
||||
if (!sercomm->tx.msg && !sercomm->tx.next_char) {
|
||||
int rc;
|
||||
/* change speed */
|
||||
uart_baudrate(sercomm->uart_id, bdrt);
|
||||
rc = sercomm_drv_baudrate_chg(sercomm, bdrt);
|
||||
sercomm_drv_unlock(&flags);
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
} else
|
||||
sercomm_drv_unlock(&flags);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \brief fetch one octet of to-be-transmitted serial data
|
||||
* \param[in] sercomm Sercomm Instance from which to fetch pending data
|
||||
|
|
Loading…
Reference in New Issue