summaryrefslogtreecommitdiffstats
path: root/Src/osmocom-bb/src/target/firmware/comm
diff options
context:
space:
mode:
Diffstat (limited to 'Src/osmocom-bb/src/target/firmware/comm')
-rw-r--r--Src/osmocom-bb/src/target/firmware/comm/Makefile5
-rw-r--r--Src/osmocom-bb/src/target/firmware/comm/msgb.c73
-rw-r--r--Src/osmocom-bb/src/target/firmware/comm/sercomm.c277
-rw-r--r--Src/osmocom-bb/src/target/firmware/comm/sercomm_cons.c140
-rw-r--r--Src/osmocom-bb/src/target/firmware/comm/timer.c217
5 files changed, 0 insertions, 712 deletions
diff --git a/Src/osmocom-bb/src/target/firmware/comm/Makefile b/Src/osmocom-bb/src/target/firmware/comm/Makefile
deleted file mode 100644
index 25fbb98..0000000
--- a/Src/osmocom-bb/src/target/firmware/comm/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-
-LIBRARIES+=comm
-comm_DIR=comm
-comm_SRCS=msgb.c sercomm.c sercomm_cons.c timer.c
-
diff --git a/Src/osmocom-bb/src/target/firmware/comm/msgb.c b/Src/osmocom-bb/src/target/firmware/comm/msgb.c
deleted file mode 100644
index 792abc6..0000000
--- a/Src/osmocom-bb/src/target/firmware/comm/msgb.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include <debug.h>
-#include <delay.h>
-
-#include <osmocom/core/msgb.h>
-
-#include <calypso/backlight.h>
-
-#define NO_TALLOC
-
-void *tall_msgb_ctx;
-
-#ifdef NO_TALLOC
-/* This is a poor mans static allocator for msgb objects */
-#define MSGB_DATA_SIZE 256+4
-#define MSGB_NUM 32
-struct supermsg {
- uint8_t allocated;
- struct msgb msg;
- uint8_t buf[MSGB_DATA_SIZE];
-};
-static struct supermsg msgs[MSGB_NUM];
-void *_talloc_zero(void *ctx, unsigned int size, const char *name)
-{
- unsigned int i;
- if (size > sizeof(struct msgb) + MSGB_DATA_SIZE)
- goto panic;
-
- while (1) {
- for (i = 0; i < ARRAY_SIZE(msgs); i++) {
- if (!msgs[i].allocated) {
- msgs[i].allocated = 1;
- memset(&msgs[i].msg, 0, sizeof(&msgs[i].msg));
- memset(&msgs[i].buf, 0, sizeof(&msgs[i].buf));
- return &msgs[i].msg;
- }
- }
- cons_puts("unable to allocate msgb\n");
- delay_ms(50);
- }
-panic:
- return NULL;
-}
-void talloc_free(void *msg)
-{
- struct supermsg *smsg = container_of(msg, struct supermsg, msg);
- smsg->allocated = 0;
-}
-#endif
diff --git a/Src/osmocom-bb/src/target/firmware/comm/sercomm.c b/Src/osmocom-bb/src/target/firmware/comm/sercomm.c
deleted file mode 100644
index f9d5bfa..0000000
--- a/Src/osmocom-bb/src/target/firmware/comm/sercomm.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/* Serial communications layer, based on HDLC */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include <osmocom/core/msgb.h>
-
-#ifdef HOST_BUILD
-#define SERCOMM_RX_MSG_SIZE 2048
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
-#endif
-#include <sercomm.h>
-#define local_irq_save(x) (void) x
-#define local_fiq_disable()
-#define local_irq_restore(x) (void) x
-
-#else
-#define SERCOMM_RX_MSG_SIZE 256
-#include <debug.h>
-#include <osmocom/core/linuxlist.h>
-#include <asm/system.h>
-
-#include <comm/sercomm.h>
-#include <uart.h>
-#endif
-
-
-enum rx_state {
- RX_ST_WAIT_START,
- RX_ST_ADDR,
- RX_ST_CTRL,
- RX_ST_DATA,
- RX_ST_ESCAPE,
-};
-
-static struct {
- int initialized;
-
- /* transmit side */
- struct {
- struct llist_head dlci_queues[_SC_DLCI_MAX];
- struct msgb *msg;
- enum rx_state state;
- uint8_t *next_char;
- } tx;
-
- /* receive side */
- struct {
- dlci_cb_t dlci_handler[_SC_DLCI_MAX];
- struct msgb *msg;
- enum rx_state state;
- uint8_t dlci;
- uint8_t ctrl;
- } rx;
-
-} sercomm;
-
-void sercomm_init(void)
-{
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(sercomm.tx.dlci_queues); i++)
- INIT_LLIST_HEAD(&sercomm.tx.dlci_queues[i]);
-
- sercomm.rx.msg = NULL;
- sercomm.initialized = 1;
-
- /* set up the echo dlci */
- sercomm_register_rx_cb(SC_DLCI_ECHO, &sercomm_sendmsg);
-}
-
-int sercomm_initialized(void)
-{
- return sercomm.initialized;
-}
-
-/* user interface for transmitting messages for a given DLCI */
-void sercomm_sendmsg(uint8_t dlci, struct msgb *msg)
-{
- unsigned long flags;
- uint8_t *hdr;
-
- /* prepend address + control octet */
- hdr = msgb_push(msg, 2);
- hdr[0] = dlci;
- hdr[1] = HDLC_C_UI;
-
- /* This functiion can be called from any context: FIQ, IRQ
- * and supervisor context. Proper locking is important! */
- local_irq_save(flags);
- local_fiq_disable();
- msgb_enqueue(&sercomm.tx.dlci_queues[dlci], msg);
- local_irq_restore(flags);
-
-#ifndef HOST_BUILD
- /* tell UART that we have something to send */
- uart_irq_enable(SERCOMM_UART_NR, UART_IRQ_TX_EMPTY, 1);
-#endif
-}
-
-/* how deep is the Tx queue for a given DLCI */
-unsigned int sercomm_tx_queue_depth(uint8_t dlci)
-{
- struct llist_head *le;
- unsigned int num = 0;
-
- llist_for_each(le, &sercomm.tx.dlci_queues[dlci]) {
- num++;
- }
-
- return num;
-}
-
-/* fetch one octet of to-be-transmitted serial data */
-int sercomm_drv_pull(uint8_t *ch)
-{
- /* we are always called from interrupt context in this function,
- * which means that any data structures we use need to be for
- * our exclusive access */
- if (!sercomm.tx.msg) {
- unsigned int i;
- /* dequeue a new message from the queues */
- for (i = 0; i < ARRAY_SIZE(sercomm.tx.dlci_queues); i++) {
- sercomm.tx.msg = msgb_dequeue(&sercomm.tx.dlci_queues[i]);
- if (sercomm.tx.msg)
- break;
- }
- if (sercomm.tx.msg) {
- /* start of a new message, send start flag octet */
- *ch = HDLC_FLAG;
- sercomm.tx.next_char = sercomm.tx.msg->data;
- return 1;
- } else {
- /* no more data avilable */
- return 0;
- }
- }
-
- if (sercomm.tx.state == RX_ST_ESCAPE) {
- /* we've already transmitted the ESCAPE octet,
- * we now need to transmit the escaped data */
- *ch = *sercomm.tx.next_char++;
- sercomm.tx.state = RX_ST_DATA;
- } else if (sercomm.tx.next_char >= sercomm.tx.msg->tail) {
- /* last character has already been transmitted,
- * send end-of-message octet */
- *ch = HDLC_FLAG;
- /* we've reached the end of the message buffer */
- msgb_free(sercomm.tx.msg);
- sercomm.tx.msg = NULL;
- sercomm.tx.next_char = NULL;
- /* escaping for the two control octets */
- } else if (*sercomm.tx.next_char == HDLC_FLAG ||
- *sercomm.tx.next_char == HDLC_ESCAPE ||
- *sercomm.tx.next_char == 0x00) {
- /* send an escape octet */
- *ch = HDLC_ESCAPE;
- /* invert bit 5 of the next octet to be sent */
- *sercomm.tx.next_char ^= (1 << 5);
- sercomm.tx.state = RX_ST_ESCAPE;
- } else {
- /* standard case, simply send next octet */
- *ch = *sercomm.tx.next_char++;
- }
- return 1;
-}
-
-/* register a handler for a given DLCI */
-int sercomm_register_rx_cb(uint8_t dlci, dlci_cb_t cb)
-{
- if (dlci >= ARRAY_SIZE(sercomm.rx.dlci_handler))
- return -EINVAL;
-
- if (sercomm.rx.dlci_handler[dlci])
- return -EBUSY;
-
- sercomm.rx.dlci_handler[dlci] = cb;
- return 0;
-}
-
-/* dispatch an incoming message once it is completely received */
-static void dispatch_rx_msg(uint8_t dlci, struct msgb *msg)
-{
- if (dlci >= ARRAY_SIZE(sercomm.rx.dlci_handler) ||
- !sercomm.rx.dlci_handler[dlci]) {
- msgb_free(msg);
- return;
- }
- sercomm.rx.dlci_handler[dlci](dlci, msg);
-}
-
-/* the driver has received one byte, pass it into sercomm layer */
-int sercomm_drv_rx_char(uint8_t ch)
-{
- uint8_t *ptr;
-
- /* we are always called from interrupt context in this function,
- * which means that any data structures we use need to be for
- * our exclusive access */
- if (!sercomm.rx.msg)
- sercomm.rx.msg = sercomm_alloc_msgb(SERCOMM_RX_MSG_SIZE);
-
- if (msgb_tailroom(sercomm.rx.msg) == 0) {
- //cons_puts("sercomm_drv_rx_char() overflow!\n");
- msgb_free(sercomm.rx.msg);
- sercomm.rx.msg = sercomm_alloc_msgb(SERCOMM_RX_MSG_SIZE);
- sercomm.rx.state = RX_ST_WAIT_START;
- return 0;
- }
-
- switch (sercomm.rx.state) {
- case RX_ST_WAIT_START:
- if (ch != HDLC_FLAG)
- break;
- sercomm.rx.state = RX_ST_ADDR;
- break;
- case RX_ST_ADDR:
- sercomm.rx.dlci = ch;
- sercomm.rx.state = RX_ST_CTRL;
- break;
- case RX_ST_CTRL:
- sercomm.rx.ctrl = ch;
- sercomm.rx.state = RX_ST_DATA;
- break;
- case RX_ST_DATA:
- if (ch == HDLC_ESCAPE) {
- /* drop the escape octet, but change state */
- sercomm.rx.state = RX_ST_ESCAPE;
- break;
- } else if (ch == HDLC_FLAG) {
- /* message is finished */
- dispatch_rx_msg(sercomm.rx.dlci, sercomm.rx.msg);
- /* allocate new buffer */
- sercomm.rx.msg = NULL;
- /* start all over again */
- sercomm.rx.state = RX_ST_WAIT_START;
-
- /* do not add the control char */
- break;
- }
- /* default case: store the octet */
- ptr = msgb_put(sercomm.rx.msg, 1);
- *ptr = ch;
- break;
- case RX_ST_ESCAPE:
- /* store bif-5-inverted octet in buffer */
- ch ^= (1 << 5);
- ptr = msgb_put(sercomm.rx.msg, 1);
- *ptr = ch;
- /* transition back to normal DATA state */
- sercomm.rx.state = RX_ST_DATA;
- break;
- }
-
- return 1;
-}
diff --git a/Src/osmocom-bb/src/target/firmware/comm/sercomm_cons.c b/Src/osmocom-bb/src/target/firmware/comm/sercomm_cons.c
deleted file mode 100644
index a0dca40..0000000
--- a/Src/osmocom-bb/src/target/firmware/comm/sercomm_cons.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/* Serial console layer, layered on top of sercomm HDLC */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <string.h>
-
-#include <asm/system.h>
-
-#include <uart.h>
-
-#include <console.h>
-#include <osmocom/core/msgb.h>
-#include <comm/sercomm.h>
-#include <comm/sercomm_cons.h>
-
-static struct {
- struct msgb *cur_msg;
-} scons;
-
-static void raw_puts(const char *s)
-{
- int i = strlen(s);
- while (i--)
- uart_putchar_wait(SERCOMM_UART_NR, *s++);
-}
-
-#ifdef DEBUG
-#define raw_putd(x) raw_puts(x)
-#else
-#define raw_putd(x)
-#endif
-
-int sercomm_puts(const char *s)
-{
- unsigned long flags;
- const int len = strlen(s);
- unsigned int bytes_left = len;
-
- if (!sercomm_initialized()) {
- raw_putd("sercomm not initialized: ");
- raw_puts(s);
- return len - 1;
- }
-
- /* This function is called from any context: Supervisor, IRQ, FIQ, ...
- * as such, we need to ensure re-entrant calls are either supported or
- * avoided. */
- local_irq_save(flags);
- local_fiq_disable();
-
- while (bytes_left > 0) {
- unsigned int write_num, space_left, flush;
- uint8_t *data;
-
- if (!scons.cur_msg)
- scons.cur_msg = sercomm_alloc_msgb(SERCOMM_CONS_ALLOC);
-
- if (!scons.cur_msg) {
- raw_putd("cannot allocate sercomm msgb: ");
- raw_puts(s);
- return -ENOMEM;
- }
-
- /* space left in the current msgb */
- space_left = msgb_tailroom(scons.cur_msg);
-
- if (space_left <= bytes_left) {
- write_num = space_left;
- /* flush buffer when it is full */
- flush = 1;
- } else {
- write_num = bytes_left;
- flush = 0;
- }
-
- /* obtain pointer where to copy the data */
- data = msgb_put(scons.cur_msg, write_num);
-
- /* copy data while looking for \n line termination */
- {
- unsigned int i;
- for (i = 0; i < write_num; i++) {
- /* flush buffer at end of line, but skip
- * flushing if we have a backlog in order to
- * increase efficiency of msgb filling */
- if (*s == '\n' &&
- sercomm_tx_queue_depth(SC_DLCI_CONSOLE) < 4)
- flush = 1;
- *data++ = *s++;
- }
- }
- bytes_left -= write_num;
-
- if (flush) {
- sercomm_sendmsg(SC_DLCI_CONSOLE, scons.cur_msg);
- /* reset scons.cur_msg pointer to ensure we allocate
- * a new one next round */
- scons.cur_msg = NULL;
- }
- }
-
- local_irq_restore(flags);
-
- return len - 1;
-}
-
-int sercomm_putchar(int c)
-{
- char s[2];
- int rc;
-
- s[0] = c & 0xff;
- s[1] = '\0';
-
- rc = sercomm_puts(s);
- if (rc < 0)
- return rc;
-
- return c;
-}
diff --git a/Src/osmocom-bb/src/target/firmware/comm/timer.c b/Src/osmocom-bb/src/target/firmware/comm/timer.c
deleted file mode 100644
index 6a649ae..0000000
--- a/Src/osmocom-bb/src/target/firmware/comm/timer.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <debug.h>
-#include <osmocom/core/linuxlist.h>
-
-#include <comm/timer.h>
-
-#include <calypso/timer.h>
-#include <calypso/irq.h>
-
-#include <keypad.h>
-
-static LLIST_HEAD(timer_list);
-
-unsigned long volatile jiffies;
-
-#define TIMER_HZ 100
-
-#define time_after(a,b) \
- (typecheck(unsigned long, a) && \
- typecheck(unsigned long, b) && \
- ((long)(b) - (long)(a) < 0))
-#define time_before(a,b) time_after(b,a)
-
-void add_timer(struct osmo_timer_list *timer)
-{
- struct osmo_timer_list *list_timer;
-
- /* TODO: Optimize and remember the closest item... */
- timer->active = 1;
-
- /* this might be called from within update_timers */
- llist_for_each_entry(list_timer, &timer_list, entry)
- if (timer == list_timer)
- return;
-
- timer->in_list = 1;
- llist_add(&timer->entry, &timer_list);
-}
-
-void schedule_timer(struct osmo_timer_list *timer, int milliseconds)
-{
- timer->expires = jiffies + ((milliseconds * TIMER_HZ) / 1000);
- add_timer(timer);
-}
-
-void del_timer(struct osmo_timer_list *timer)
-{
- if (timer->in_list) {
- timer->active = 0;
- timer->in_list = 0;
- llist_del(&timer->entry);
- }
-}
-
-int timer_pending(struct osmo_timer_list *timer)
-{
- return timer->active;
-}
-
-#if 0
-/*
- * if we have a nearest time return the delta between the current
- * time and the time of the nearest timer.
- * If the nearest timer timed out return NULL and then we will
- * dispatch everything after the select
- */
-struct timeval *nearest_timer()
-{
- struct timeval current_time;
-
- if (s_nearest_time.tv_sec == 0 && s_nearest_time.tv_usec == 0)
- return NULL;
-
- if (gettimeofday(&current_time, NULL) == -1)
- return NULL;
-
- unsigned long long nearestTime = s_nearest_time.tv_sec * MICRO_SECONDS + s_nearest_time.tv_usec;
- unsigned long long currentTime = current_time.tv_sec * MICRO_SECONDS + current_time.tv_usec;
-
- if (nearestTime < currentTime) {
- s_select_time.tv_sec = 0;
- s_select_time.tv_usec = 0;
- } else {
- s_select_time.tv_sec = (nearestTime - currentTime) / MICRO_SECONDS;
- s_select_time.tv_usec = (nearestTime - currentTime) % MICRO_SECONDS;
- }
-
- return &s_select_time;
-}
-
-/*
- * Find the nearest time and update s_nearest_time
- */
-void prepare_timers()
-{
- struct osmo_timer_list *timer, *nearest_timer = NULL;
- llist_for_each_entry(timer, &timer_list, entry) {
- if (!nearest_timer || time_before(timer->expires, nearest_timer->expires)) {
- nearest_timer = timer;
- }
- }
-
- if (nearest_timer) {
- s_nearest_time = nearest_timer->timeout;
- } else {
- memset(&s_nearest_time, 0, sizeof(struct timeval));
- }
-}
-#endif
-
-/*
- * fire all timers... and remove them
- */
-int update_timers(void)
-{
- struct osmo_timer_list *timer, *tmp;
- int work = 0;
-
- /*
- * The callbacks might mess with our list and in this case
- * even llist_for_each_entry_safe is not safe to use. To allow
- * del_timer, add_timer, schedule_timer to be called from within
- * the callback we jump through some loops.
- *
- * First we set the handled flag of each active timer to zero,
- * then we iterate over the list and execute the callbacks. As the
- * list might have been changed (specially the next) from within
- * the callback we have to start over again. Once every callback
- * is dispatched we will remove the non-active from the list.
- *
- * TODO: If this is a performance issue we can poison a global
- * variable in add_timer and del_timer and only then restart.
- */
- llist_for_each_entry(timer, &timer_list, entry) {
- timer->handled = 0;
- }
-
-restart:
- llist_for_each_entry(timer, &timer_list, entry) {
- if (!timer->handled && time_before(timer->expires, jiffies)) {
- timer->handled = 1;
- timer->active = 0;
- (*timer->cb)(timer->data);
- work = 1;
- goto restart;
- }
- }
-
- llist_for_each_entry_safe(timer, tmp, &timer_list, entry) {
- timer->handled = 0;
- if (!timer->active) {
- del_timer(timer);
- }
- }
-
- return work;
-}
-
-int timer_check(void)
-{
- struct osmo_timer_list *timer;
- int i = 0;
-
- llist_for_each_entry(timer, &timer_list, entry) {
- i++;
- }
- return i;
-}
-
-static void timer_irq(enum irq_nr irq)
-{
- /* we only increment jiffies here. FIXME: does this need to be atomic? */
- jiffies++;
-
- keypad_poll();
-}
-
-void timer_init(void)
-{
- /* configure TIMER2 for our purpose */
- hwtimer_enable(2, 1);
- /* The timer runs at 13MHz / 32, i.e. 406.25kHz */
-#if (TIMER_HZ == 100)
- hwtimer_load(2, 4062);
- hwtimer_config(2, 0, 1);
-#elif (TIMER_HZ == 10)
- /* prescaler 4, 1015 ticks until expiry */
- hwtimer_load(2, 1015);
- hwtimer_config(2, 4, 1);
-#endif
- hwtimer_enable(2, 1);
-
- /* register interrupt handler with default priority, EDGE triggered */
- irq_register_handler(IRQ_TIMER2, &timer_irq);
- irq_config(IRQ_TIMER2, 0, 1, -1);
- irq_enable(IRQ_TIMER2);
-}