--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2004 Giovanni Bajo
+ *
+ * -->
+ *
+ * \brief Hardware support for buzzers and leds in DSP56K-based boards
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.7 2006/07/19 12:56:25 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.6 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.5 2005/04/11 19:10:27 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.4 2004/11/16 21:54:43 bernie
+ *#* Changes for SC Monoboard support.
+ *#*
+ *#* Revision 1.3 2004/08/25 14:12:08 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 18:36:05 bernie
+ *#* Import buzzerled driver.
+ *#*
+ *#*/
+
+#ifndef DRV_BUZZERLED_DSP56K_H
+#define DRV_BUZZERLED_DSP56K_H
+
+#include <cfg/compiler.h>
+#include <hw.h>
+#include "pwm.h"
+
+#if ARCH & ARCH_HECO
+
+/**
+ * \name Connection of the leds to the DSP:
+ * <pre>
+ * Led Line DSP Pin
+ * ---------------------------
+ * YELLOW T2 HOME1/TB3
+ * GREEN T3 INDX1/TB2
+ * RED T4 PHB1/TB1
+ * </pre>
+ */
+
+INLINE bool bld_is_inverted_intensity(enum BLD_DEVICE device)
+{
+ return (device == BLD_GREEN_LED
+ || device == BLD_YELLOW_LED
+ || device == BLD_RED_LED);
+}
+
+INLINE bool bld_is_pwm(enum BLD_DEVICE device)
+{
+ // Only the buzzer is connected to a PWM
+ return (device == BLD_BUZZER || device == BLD_READY_LED);
+}
+
+INLINE bool bld_is_timer(enum BLD_DEVICE device)
+{
+ // LEDs are connected to timers
+ return (device == BLD_GREEN_LED || device == BLD_YELLOW_LED || device == BLD_RED_LED);
+}
+
+INLINE uint16_t bld_get_pwm(enum BLD_DEVICE device)
+{
+ switch (device)
+ {
+ default: ASSERT(0);
+ case BLD_BUZZER: return 5; // PWMA5
+ case BLD_READY_LED: return 9; // PWMB3
+ }
+}
+
+
+INLINE struct REG_TIMER_STRUCT* bld_get_timer(enum BLD_DEVICE device)
+{
+ switch (device)
+ {
+ default: ASSERT(0);
+ case BLD_GREEN_LED: return ®_TIMER_B[2];
+ case BLD_RED_LED: return ®_TIMER_B[1];
+ case BLD_YELLOW_LED: return ®_TIMER_B[3];
+ }
+}
+
+INLINE void bld_hw_init(void)
+{
+}
+
+INLINE void bld_hw_set(enum BLD_DEVICE device, bool enable)
+{
+ if (bld_is_inverted_intensity(device))
+ enable = !enable;
+
+ // Handle a BLD connected to a PWM
+ if (bld_is_pwm(device))
+ {
+ struct PWM* pwm = pwm_get_handle(bld_get_pwm(device));
+
+ pwm_set_enable(pwm, false);
+ pwm_set_dutycycle_percent(pwm, (enable ? 50 : 0));
+ pwm_set_enable(pwm, true);
+ }
+ else if (bld_is_timer(device))
+ {
+ struct REG_TIMER_STRUCT* timer = bld_get_timer(device);
+
+ // Check that the timer is currently stopped, and the OFLAG is not
+ // controlled by another timer. Otherwise, the led is already
+ // controlled by the timer, and we cannot correctly set it
+ // on/off without reprogramming the timer.
+ ASSERT((timer->CTRL & REG_TIMER_CTRL_MODE_MASK) == REG_TIMER_CTRL_MODE_STOP);
+ ASSERT(!(timer->SCR & REG_TIMER_SCR_EEOF));
+
+ // Check also that polarity is correct
+ ASSERT(!(timer->SCR & REG_TIMER_SCR_OPS));
+
+ // Without programming the timer, we have a way to manually force a certain
+ // value on the external pin. We also need to enable the output pin.
+ timer->SCR &= ~REG_TIMER_SCR_VAL_1;
+ timer->SCR |= REG_TIMER_SCR_OEN |
+ REG_TIMER_SCR_FORCE |
+ (!enable ? REG_TIMER_SCR_VAL_0 : REG_TIMER_SCR_VAL_1);
+ }
+ else
+ ASSERT(0);
+}
+
+#elif ARCH & ARCH_SC
+
+// We do not need inline functions here, because constant propagation is not big deal here
+void bld_hw_init(void);
+void bld_hw_set(enum BLD_DEVICE device, bool enable);
+
+#endif
+
+#endif /* DRV_BUZZERLED_DSP56K_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Stefano Fedrigo <aleph@develer.com>
+ * \author Giovanni Bajo <rasky@develer.com>
+ *
+ * \brief DSP5680x CPU specific serial I/O driver
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.14 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.13 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.12 2005/04/11 19:10:27 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.11 2005/01/25 07:42:04 bernie
+ *#* Simplify.
+ *#*
+ *#* Revision 1.10 2005/01/14 00:48:33 aleph
+ *#* Rename callbacks; SerialHardwareVT.txSending: New callback.
+ *#*
+ *#* Revision 1.9 2004/12/08 09:42:55 bernie
+ *#* Add support for multiplexed serial ports.
+ *#*
+ *#* Revision 1.8 2004/10/26 09:00:49 bernie
+ *#* Don't access serial data register twice.
+ *#*
+ *#* Revision 1.7 2004/10/19 08:57:15 bernie
+ *#* Bugfixes for DSP56K serial driver from scfirm.
+ *#*
+ *#* Revision 1.5 2004/08/25 14:12:08 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.4 2004/07/30 14:27:49 rasky
+ *#* Aggiornati alcuni file DSP56k per la nuova libreria di IRQ management
+ *#*
+ *#* Revision 1.3 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.2 2004/05/23 18:21:53 bernie
+ *#* Trim CVS logs and cleanup header info.
+ *#*/
+
+#include "ser.h"
+#include "ser_p.h"
+#include <drv/irq.h>
+#include <cfg/debug.h>
+#include <hw.h>
+#include <DSP56F807.h>
+
+// GPIO E is shared with SPI (in DSP56807). Pins 0&1 are TXD0 and RXD0. To use
+// the serial, we need to disable the GPIO functions on them.
+#define REG_GPIO_SERIAL_0 REG_GPIO_E
+#define REG_GPIO_SERIAL_MASK_0 0x03
+
+#define REG_GPIO_SERIAL_1 REG_GPIO_D
+#define REG_GPIO_SERIAL_MASK_1 0xC0
+
+
+// Check flag consistency
+#if (SERRF_PARITYERROR != REG_SCI_SR_PF) || \
+ (SERRF_RXSROVERRUN != REG_SCI_SR_OR) || \
+ (SERRF_FRAMEERROR != REG_SCI_SR_FE) || \
+ (SERRF_NOISEERROR != REG_SCI_SR_NF)
+ #error error flags do not match with register bits
+#endif
+
+static unsigned char ser0_fifo_rx[CONFIG_SER0_FIFOSIZE_RX];
+static unsigned char ser0_fifo_tx[CONFIG_SER0_FIFOSIZE_TX];
+static unsigned char ser1_fifo_rx[CONFIG_SER1_FIFOSIZE_RX];
+static unsigned char ser1_fifo_tx[CONFIG_SER1_FIFOSIZE_TX];
+
+#if CONFIG_SER_MULTI
+ #include <kern/sem.h>
+
+ #define MAX_MULTI_GROUPS 1
+
+ struct Semaphore multi_sems[MAX_MULTI_GROUPS];
+#endif
+
+
+struct SCI
+{
+ struct SerialHardware hw;
+ struct Serial* serial;
+ volatile struct REG_SCI_STRUCT* regs;
+ IRQ_VECTOR irq_tx;
+ IRQ_VECTOR irq_rx;
+ int num_group;
+ int id;
+};
+
+static inline void enable_tx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
+{
+ regs->CR |= REG_SCI_CR_TEIE | REG_SCI_CR_TIIE;
+}
+
+static inline void enable_rx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
+{
+ regs->CR |= REG_SCI_CR_RIE;
+}
+
+static inline void disable_tx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
+{
+ regs->CR &= ~(REG_SCI_CR_TEIE | REG_SCI_CR_TIIE);
+}
+
+static inline void disable_rx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
+{
+ regs->CR &= ~(REG_SCI_CR_RIE | REG_SCI_CR_REIE);
+}
+
+static inline void disable_tx_irq(struct SerialHardware* _hw)
+{
+ struct SCI* hw = (struct SCI*)_hw;
+
+ disable_tx_irq_bare(hw->regs);
+}
+
+static inline void disable_rx_irq(struct SerialHardware* _hw)
+{
+ struct SCI* hw = (struct SCI*)_hw;
+
+ disable_rx_irq_bare(hw->regs);
+}
+
+static inline void enable_tx_irq(struct SerialHardware* _hw)
+{
+ struct SCI* hw = (struct SCI*)_hw;
+
+ enable_tx_irq_bare(hw->regs);
+}
+
+static inline void enable_rx_irq(struct SerialHardware* _hw)
+{
+ struct SCI* hw = (struct SCI*)_hw;
+
+ enable_rx_irq_bare(hw->regs);
+}
+
+static inline bool tx_irq_enabled(struct SerialHardware* _hw)
+{
+ struct SCI* hw = (struct SCI*)_hw;
+
+ return (hw->regs->CR & REG_SCI_CR_TEIE);
+}
+
+static void tx_isr(const struct SCI *hw)
+{
+#pragma interrupt warn
+ volatile struct REG_SCI_STRUCT* regs = hw->regs;
+
+ if (fifo_isempty(&hw->serial->txfifo))
+ disable_tx_irq_bare(regs);
+ else
+ {
+ // Clear transmitter flags before sending data
+ (void)regs->SR;
+ regs->DR = fifo_pop(&hw->serial->txfifo);
+ }
+}
+
+static void rx_isr(const struct SCI *hw)
+{
+#pragma interrupt warn
+ volatile struct REG_SCI_STRUCT* regs = hw->regs;
+
+ // Propagate errors
+ hw->serial->status |= regs->SR & (SERRF_PARITYERROR |
+ SERRF_RXSROVERRUN |
+ SERRF_FRAMEERROR |
+ SERRF_NOISEERROR);
+
+ /*
+ * Serial IRQ can happen for two reason: data ready (RDRF) or overrun (OR)
+ * If the data is ready, we need to fetch it from the data register or
+ * the interrupt will retrigger immediatly. In case of overrun, instead,
+ * the value of the data register is meaningless.
+ */
+ if (regs->SR & REG_SCI_SR_RDRF)
+ {
+ unsigned char data = regs->DR;
+
+ if (fifo_isfull(&hw->serial->rxfifo))
+ hw->serial->status |= SERRF_RXFIFOOVERRUN;
+ else
+ fifo_push(&hw->serial->rxfifo, data);
+ }
+
+ // Writing anything to the status register clear the error bits.
+ regs->SR = 0;
+}
+
+static void init(struct SerialHardware* _hw, struct Serial* ser)
+{
+ struct SCI* hw = (struct SCI*)_hw;
+ volatile struct REG_SCI_STRUCT* regs = hw->regs;
+
+ // Clear status register (IRQ/status flags)
+ (void)regs->SR;
+ regs->SR = 0;
+
+ // Clear data register
+ (void)regs->DR;
+
+ // Install the handlers and set priorities for both IRQs
+ irq_install(hw->irq_tx, (isr_t)tx_isr, hw);
+ irq_install(hw->irq_rx, (isr_t)rx_isr, hw);
+ irq_setpriority(hw->irq_tx, IRQ_PRIORITY_SCI_TX);
+ irq_setpriority(hw->irq_rx, IRQ_PRIORITY_SCI_RX);
+
+ // Activate the RX error interrupts, and RX/TX transmissions
+ regs->CR = REG_SCI_CR_TE | REG_SCI_CR_RE;
+ enable_rx_irq_bare(regs);
+
+ // Disable GPIO pins for TX and RX lines
+ // \todo this should be divided into serial 0 and 1
+ REG_GPIO_SERIAL_0->PER |= REG_GPIO_SERIAL_MASK_0;
+ REG_GPIO_SERIAL_1->PER |= REG_GPIO_SERIAL_MASK_1;
+
+ hw->serial = ser;
+}
+
+static void cleanup(struct SerialHardware* _hw)
+{
+ struct SCI* hw = (struct SCI*)_hw;
+
+ // Uninstall the ISRs
+ disable_rx_irq(_hw);
+ disable_tx_irq(_hw);
+ irq_uninstall(hw->irq_tx);
+ irq_uninstall(hw->irq_rx);
+}
+
+static void setbaudrate(struct SerialHardware* _hw, unsigned long rate)
+{
+ struct SCI* hw = (struct SCI*)_hw;
+
+ // SCI has an internal 16x divider on the input clock, which comes
+ // from the IPbus (see the scheme in user manual, 12.7.3). We apply
+ // it to calculate the period to store in the register.
+ hw->regs->BR = (IPBUS_FREQ + rate * 8ul) / (rate * 16ul);
+}
+
+static void setparity(struct SerialHardware* _hw, int parity)
+{
+ // ???
+ ASSERT(0);
+}
+
+
+#if CONFIG_SER_MULTI
+
+static void multi_init(void)
+{
+ static bool flag = false;
+ int i;
+
+ if (flag)
+ return;
+
+ for (i = 0; i < MAX_MULTI_GROUPS; ++i)
+ sem_init(&multi_sems[i]);
+ flag = true;
+}
+
+static void init_lock(struct SerialHardware* _hw, struct Serial *ser)
+{
+ struct SCI* hw = (struct SCI*)_hw;
+
+ // Initialize the multi engine (if needed)
+ multi_init();
+
+ // Acquire the lock of the semaphore for this group
+ ASSERT(hw->num_group >= 0);
+ ASSERT(hw->num_group < MAX_MULTI_GROUPS);
+ sem_obtain(&multi_sems[hw->num_group]);
+
+ // Do a hardware switch to the given serial
+ ser_hw_switch(hw->num_group, hw->id);
+
+ init(_hw, ser);
+}
+
+static void cleanup_unlock(struct SerialHardware* _hw)
+{
+ struct SCI* hw = (struct SCI*)_hw;
+
+ cleanup(_hw);
+
+ sem_release(&multi_sems[hw->num_group]);
+}
+
+#endif /* CONFIG_SER_MULTI */
+
+
+static const struct SerialHardwareVT SCI_VT =
+{
+ .init = init,
+ .cleanup = cleanup,
+ .setBaudrate = setbaudrate,
+ .setParity = setparity,
+ .txStart = enable_tx_irq,
+ .txSending = tx_irq_enabled,
+};
+
+#if CONFIG_SER_MULTI
+static const struct SerialHardwareVT SCI_MULTI_VT =
+{
+ .init = init_lock,
+ .cleanup = cleanup_unlock,
+ .setBaudrate = setbaudrate,
+ .setParity = setparity,
+ .txStart = enable_tx_irq,
+ .txSending = tx_irq_enabled,
+};
+#endif /* CONFIG_SER_MULTI */
+
+#define SCI_DESC_NORMAL(hwch) \
+ { \
+ .hw = \
+ { \
+ .table = &SCI_VT, \
+ .rxbuffer = ser ## hwch ## _fifo_rx, \
+ .txbuffer = ser ## hwch ## _fifo_tx, \
+ .rxbuffer_size = countof(ser ## hwch ## _fifo_rx), \
+ .txbuffer_size = countof(ser ## hwch ## _fifo_tx), \
+ }, \
+ .regs = ®_SCI[hwch], \
+ .irq_rx = IRQ_SCI ## hwch ## _RECEIVER_FULL, \
+ .irq_tx = IRQ_SCI ## hwch ## _TRANSMITTER_READY, \
+ .num_group = -1, \
+ .id = -1, \
+ } \
+ /**/
+
+#if CONFIG_SER_MULTI
+#define SCI_DESC_MULTI(hwch, group_, id_) \
+ { \
+ .hw = \
+ { \
+ .table = &SCI_MULTI_VT, \
+ .rxbuffer = ser ## hwch ## _fifo_rx, \
+ .txbuffer = ser ## hwch ## _fifo_tx, \
+ .rxbuffer_size = countof(ser ## hwch ## _fifo_rx), \
+ .txbuffer_size = countof(ser ## hwch ## _fifo_tx), \
+ }, \
+ .regs = ®_SCI[hwch], \
+ .irq_rx = IRQ_SCI ## hwch ## _RECEIVER_FULL, \
+ .irq_tx = IRQ_SCI ## hwch ## _TRANSMITTER_READY, \
+ .num_group = group_, \
+ .id = id_, \
+ } \
+ /**/
+#endif /* CONFIG_SER_MULTI */
+
+// \todo Move this into hw.h, with a little preprocessor magic
+static struct SCI SCIDescs[] =
+{
+ SCI_DESC_NORMAL(0),
+ SCI_DESC_MULTI(1, 0, 0),
+ SCI_DESC_MULTI(1, 0, 1),
+};
+
+struct SerialHardware* ser_hw_getdesc(int unit)
+{
+ ASSERT(unit < countof(SCIDescs));
+ return &SCIDescs[unit].hw;
+}
--- /dev/null
+#error This code must be revised for the new timer API
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2004 Giovanni Bajo
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Giovanni Bajo <rasky@develer.com>
+ *
+ * \brief Driver module for DSP56K
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.10 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.9 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
+ *#* Revision 1.8 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.7 2005/04/11 19:10:28 bernie
+ *#* Include top-level headers from cfg/ subdir.
+ *#*
+ *#* Revision 1.6 2004/11/16 22:37:14 bernie
+ *#* Replace IPTR with iptr_t.
+ *#*
+ *#* Revision 1.5 2004/08/25 14:12:08 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.4 2004/07/30 14:27:49 rasky
+ *#* Aggiornati alcuni file DSP56k per la nuova libreria di IRQ management
+ *#*
+ *#* Revision 1.3 2004/06/06 18:30:34 bernie
+ *#* Import DSP56800 changes from SC.
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 18:23:30 bernie
+ *#* Import drv/timer module.
+ *#*
+ *#*/
+
+#ifndef DRV_TIMER_DSP56K_H
+#define DRV_TIMER_DSP56K_H
+
+#include "timer.h"
+#include <DSP56F807.h>
+#include <cfg/compiler.h>
+#include <hw.h>
+#include <drv/irq.h>
+
+// Calculate register pointer and irq vector from hw.h setting
+#define REG_SYSTEM_TIMER PP_CAT(REG_TIMER_, SYSTEM_TIMER)
+#define SYSTEM_TIMER_IRQ_VECTOR PP_CAT(IRQ_TIMER_, SYSTEM_TIMER)
+
+/// Prescaler for the system timer
+#define TIMER_PRESCALER 16
+
+/// Frequency of the hardware high precision timer
+#define TIMER_HW_HPTICKS_PER_SEC (IPBUS_FREQ / TIMER_PRESCALER)
+
+/// Type of time expressed in ticks of the hardware high precision timer
+typedef uint16_t hptime_t;
+
+static void system_timer_isr(UNUSED(iptr_t, arg));
+
+static void timer_hw_init(void)
+{
+ uint16_t compare;
+
+ // Clear compare flag status and enable interrupt on compare
+ REG_SYSTEM_TIMER->SCR &= ~REG_TIMER_SCR_TCF;
+ REG_SYSTEM_TIMER->SCR |= REG_TIMER_SCR_TCFIE;
+
+ // Calculate the compare value needed to generate an interrupt exactly
+ // TICKS_PER_SEC times each second (usually, every millisecond). Check that
+ // the calculation is accurate, otherwise there is a precision error
+ // (probably the prescaler is too big or too small).
+ compare = TIMER_HW_HPTICKS_PER_SEC / TICKS_PER_SEC;
+ ASSERT((uint32_t)compare * TICKS_PER_SEC == IPBUS_FREQ / TIMER_PRESCALER);
+ REG_SYSTEM_TIMER->CMP1 = compare;
+
+ // The value for reload (at initializationa and after compare is met) is zero
+ REG_SYSTEM_TIMER->LOAD = 0;
+
+ // Set the interrupt handler and priority
+ irq_install(SYSTEM_TIMER_IRQ_VECTOR, &system_timer_isr, NULL);
+ irq_setpriority(SYSTEM_TIMER_IRQ_VECTOR, IRQ_PRIORITY_SYSTEM_TIMER);
+
+ // Small preprocessor trick to generate the REG_TIMER_CTRL_PRIMARY_IPBYNN macro
+ // needed to set the prescaler
+ #define REG_CONTROL_PRESCALER PP_CAT(REG_TIMER_CTRL_PRIMARY_IPBY, TIMER_PRESCALER)
+
+ // Setup the counter and start counting
+ REG_SYSTEM_TIMER->CTRL =
+ REG_TIMER_CTRL_MODE_RISING | // count rising edges (normal)
+ REG_CONTROL_PRESCALER | // frequency (IPbus / TIMER_PRESCALER)
+ REG_TIMER_CTRL_LENGTH; // up to CMP1, then reload
+}
+
+INLINE void timer_hw_irq(void)
+{
+ // Clear the overflow flag so that we are ready for another interrupt
+ REG_SYSTEM_TIMER->SCR &= ~REG_TIMER_SCR_TCF;
+}
+
+INLINE hptime_t timer_hw_hpread(void)
+{
+ return REG_SYSTEM_TIMER->CNTR;
+}
+
+#define DEFINE_TIMER_ISR \
+ static void system_timer_isr(UNUSED(iptr_t, arg))
+
+#endif /* DRV_TIMER_DSP56_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright (C) 2003,2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright (C) 2000 Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief CPU specific serial I/O driver
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.7 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.6 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.5 2004/12/13 11:51:08 bernie
+ *#* DISABLE_INTS/ENABLE_INTS: Convert to IRQ_DISABLE/IRQ_ENABLE.
+ *#*
+ *#* Revision 1.4 2004/08/25 14:12:08 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.3 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.2 2004/05/23 18:21:53 bernie
+ *#* Trim CVS logs and cleanup header info.
+ *#*
+ *#*/
+
+#include "hw.h"
+#include "serhw.h"
+
+#define SER_HW_ENABLE_TX \
+ ATOMIC( \
+ if (!ser_sending) \
+ { \
+ ser_sending = true; \
+ (INT_PEND1 |= INT1F_TI) \
+ } \
+ );
+
+static volatile bool ser_sending;
+
+// Serial TX intr
+INTERRUPT(0x30) void TI_interrupt(void)
+{
+ if (CANT_SEND)
+ {
+ ser_sending = false;
+ return;
+ }
+
+ /* Can we send two bytes at the same time? */
+ if (SP_STAT & SPSF_TX_EMPTY)
+ {
+ SBUF = fifo_pop(&ser_txfifo);
+
+ if (CANT_SEND)
+ {
+ ser_sending = false;
+ return;
+ }
+ }
+
+ SBUF = fifo_pop(&ser_txfifo);
+}
+
+INTERRUPT(0x32) void RI_interrupt(void)
+{
+ ser_status |= SP_STAT &
+ (SPSF_OVERRUN_ERROR | SPSF_PARITY_ERROR | SPSF_FRAMING_ERROR);
+ if (fifo_isfull(&ser_rxfifo))
+ ser_status |= SERRF_RXFIFOOVERRUN;
+ else
+ fifo_push(&ser_rxfifo, SBUF);
+}
+
+static void ser_setbaudrate(unsigned long rate)
+{
+ // Calcola il periodo per la generazione del baud rate richiesto
+ uint16_t baud = (uint16_t)(((CLOCK_FREQ / 16) / rate) - 1) | 0x8000;
+ BAUD_RATE = (uint8_t)baud;
+ BAUD_RATE = (uint8_t)(baud >> 8);
+}
+
+static void ser_hw_init(void)
+{
+ // Inizializza la porta seriale
+ SP_CON = SPCF_RECEIVE_ENABLE | SPCF_MODE1;
+ ioc1_img |= IOC1F_TXD_SEL | IOC1F_EXTINT_SRC;
+ IOC1 = ioc1_img;
+
+ // Svuota il buffer di ricezione
+ {
+ uint8_t dummy = SBUF;
+ }
+
+ // Abilita gli interrupt
+ INT_MASK1 |= INT1F_TI | INT1F_RI;
+}
+
--- /dev/null
+#error This code must be revised for the new timer API
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000 Bernardo Innocenti
+ *
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief Low-level timer module for AVR
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.7 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.6 2006/02/21 21:28:02 bernie
+ *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
+ *#*
+ *#* Revision 1.5 2005/11/04 16:20:02 bernie
+ *#* Fix reference to README.devlib in header.
+ *#*
+ *#* Revision 1.4 2004/12/13 11:51:08 bernie
+ *#* DISABLE_INTS/ENABLE_INTS: Convert to IRQ_DISABLE/IRQ_ENABLE.
+ *#*
+ *#* Revision 1.3 2004/08/25 14:12:08 rasky
+ *#* Aggiornato il comment block dei log RCS
+ *#*
+ *#* Revision 1.2 2004/06/03 11:27:09 bernie
+ *#* Add dual-license information.
+ *#*
+ *#* Revision 1.1 2004/05/23 18:23:30 bernie
+ *#* Import drv/timer module.
+ *#*
+ *#*/
+
+#ifndef TIMER_I196_H
+#define TIMER_I196_H
+
+/**
+ * Retrigger TIMER2, adjusting the time to account for
+ * the interrupt prologue latency.
+ */
+#define TIMER_RETRIGGER (TIMER2 -= TICKS_RATE)
+
+#define TIMER_INIT \
+ TIMER2 = (65535 - TICKS_RATE); \
+ INT_MASK1 |= INT1F_T2OVF; \
+ ATOMIC( \
+ WSR = 1; \
+ IOC3 |= IOC3F_T2_ENA; \
+ WSR = 0; \
+ )
+
+#define DEFINE_TIMER_ISR \
+ INTERRUPT(0x38) void TM2_OVFL_interrupt(void); \
+ INTERRUPT(0x38) void TM2_OVFL_interrupt(void)
+
+#endif /* DRV_TIMER_I196_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2004 Giovanni Bajo
- *
- * -->
- *
- * \brief Hardware support for buzzers and leds in DSP56K-based boards
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.7 2006/07/19 12:56:25 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.6 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.5 2005/04/11 19:10:27 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.4 2004/11/16 21:54:43 bernie
- *#* Changes for SC Monoboard support.
- *#*
- *#* Revision 1.3 2004/08/25 14:12:08 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 18:36:05 bernie
- *#* Import buzzerled driver.
- *#*
- *#*/
-
-#ifndef DRV_BUZZERLED_DSP56K_H
-#define DRV_BUZZERLED_DSP56K_H
-
-#include <cfg/compiler.h>
-#include <hw.h>
-#include "pwm.h"
-
-#if ARCH & ARCH_HECO
-
-/**
- * \name Connection of the leds to the DSP:
- * <pre>
- * Led Line DSP Pin
- * ---------------------------
- * YELLOW T2 HOME1/TB3
- * GREEN T3 INDX1/TB2
- * RED T4 PHB1/TB1
- * </pre>
- */
-
-INLINE bool bld_is_inverted_intensity(enum BLD_DEVICE device)
-{
- return (device == BLD_GREEN_LED
- || device == BLD_YELLOW_LED
- || device == BLD_RED_LED);
-}
-
-INLINE bool bld_is_pwm(enum BLD_DEVICE device)
-{
- // Only the buzzer is connected to a PWM
- return (device == BLD_BUZZER || device == BLD_READY_LED);
-}
-
-INLINE bool bld_is_timer(enum BLD_DEVICE device)
-{
- // LEDs are connected to timers
- return (device == BLD_GREEN_LED || device == BLD_YELLOW_LED || device == BLD_RED_LED);
-}
-
-INLINE uint16_t bld_get_pwm(enum BLD_DEVICE device)
-{
- switch (device)
- {
- default: ASSERT(0);
- case BLD_BUZZER: return 5; // PWMA5
- case BLD_READY_LED: return 9; // PWMB3
- }
-}
-
-
-INLINE struct REG_TIMER_STRUCT* bld_get_timer(enum BLD_DEVICE device)
-{
- switch (device)
- {
- default: ASSERT(0);
- case BLD_GREEN_LED: return ®_TIMER_B[2];
- case BLD_RED_LED: return ®_TIMER_B[1];
- case BLD_YELLOW_LED: return ®_TIMER_B[3];
- }
-}
-
-INLINE void bld_hw_init(void)
-{
-}
-
-INLINE void bld_hw_set(enum BLD_DEVICE device, bool enable)
-{
- if (bld_is_inverted_intensity(device))
- enable = !enable;
-
- // Handle a BLD connected to a PWM
- if (bld_is_pwm(device))
- {
- struct PWM* pwm = pwm_get_handle(bld_get_pwm(device));
-
- pwm_set_enable(pwm, false);
- pwm_set_dutycycle_percent(pwm, (enable ? 50 : 0));
- pwm_set_enable(pwm, true);
- }
- else if (bld_is_timer(device))
- {
- struct REG_TIMER_STRUCT* timer = bld_get_timer(device);
-
- // Check that the timer is currently stopped, and the OFLAG is not
- // controlled by another timer. Otherwise, the led is already
- // controlled by the timer, and we cannot correctly set it
- // on/off without reprogramming the timer.
- ASSERT((timer->CTRL & REG_TIMER_CTRL_MODE_MASK) == REG_TIMER_CTRL_MODE_STOP);
- ASSERT(!(timer->SCR & REG_TIMER_SCR_EEOF));
-
- // Check also that polarity is correct
- ASSERT(!(timer->SCR & REG_TIMER_SCR_OPS));
-
- // Without programming the timer, we have a way to manually force a certain
- // value on the external pin. We also need to enable the output pin.
- timer->SCR &= ~REG_TIMER_SCR_VAL_1;
- timer->SCR |= REG_TIMER_SCR_OEN |
- REG_TIMER_SCR_FORCE |
- (!enable ? REG_TIMER_SCR_VAL_0 : REG_TIMER_SCR_VAL_1);
- }
- else
- ASSERT(0);
-}
-
-#elif ARCH & ARCH_SC
-
-// We do not need inline functions here, because constant propagation is not big deal here
-void bld_hw_init(void);
-void bld_hw_set(enum BLD_DEVICE device, bool enable);
-
-#endif
-
-#endif /* DRV_BUZZERLED_DSP56K_H */
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
- *
- * -->
- *
- * \version $Id$
- *
- * \author Stefano Fedrigo <aleph@develer.com>
- * \author Giovanni Bajo <rasky@develer.com>
- *
- * \brief DSP5680x CPU specific serial I/O driver
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.14 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.13 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.12 2005/04/11 19:10:27 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.11 2005/01/25 07:42:04 bernie
- *#* Simplify.
- *#*
- *#* Revision 1.10 2005/01/14 00:48:33 aleph
- *#* Rename callbacks; SerialHardwareVT.txSending: New callback.
- *#*
- *#* Revision 1.9 2004/12/08 09:42:55 bernie
- *#* Add support for multiplexed serial ports.
- *#*
- *#* Revision 1.8 2004/10/26 09:00:49 bernie
- *#* Don't access serial data register twice.
- *#*
- *#* Revision 1.7 2004/10/19 08:57:15 bernie
- *#* Bugfixes for DSP56K serial driver from scfirm.
- *#*
- *#* Revision 1.5 2004/08/25 14:12:08 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.4 2004/07/30 14:27:49 rasky
- *#* Aggiornati alcuni file DSP56k per la nuova libreria di IRQ management
- *#*
- *#* Revision 1.3 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.2 2004/05/23 18:21:53 bernie
- *#* Trim CVS logs and cleanup header info.
- *#*/
-
-#include "ser.h"
-#include "ser_p.h"
-#include <drv/irq.h>
-#include <cfg/debug.h>
-#include <hw.h>
-#include <DSP56F807.h>
-
-// GPIO E is shared with SPI (in DSP56807). Pins 0&1 are TXD0 and RXD0. To use
-// the serial, we need to disable the GPIO functions on them.
-#define REG_GPIO_SERIAL_0 REG_GPIO_E
-#define REG_GPIO_SERIAL_MASK_0 0x03
-
-#define REG_GPIO_SERIAL_1 REG_GPIO_D
-#define REG_GPIO_SERIAL_MASK_1 0xC0
-
-
-// Check flag consistency
-#if (SERRF_PARITYERROR != REG_SCI_SR_PF) || \
- (SERRF_RXSROVERRUN != REG_SCI_SR_OR) || \
- (SERRF_FRAMEERROR != REG_SCI_SR_FE) || \
- (SERRF_NOISEERROR != REG_SCI_SR_NF)
- #error error flags do not match with register bits
-#endif
-
-static unsigned char ser0_fifo_rx[CONFIG_SER0_FIFOSIZE_RX];
-static unsigned char ser0_fifo_tx[CONFIG_SER0_FIFOSIZE_TX];
-static unsigned char ser1_fifo_rx[CONFIG_SER1_FIFOSIZE_RX];
-static unsigned char ser1_fifo_tx[CONFIG_SER1_FIFOSIZE_TX];
-
-#if CONFIG_SER_MULTI
- #include <kern/sem.h>
-
- #define MAX_MULTI_GROUPS 1
-
- struct Semaphore multi_sems[MAX_MULTI_GROUPS];
-#endif
-
-
-struct SCI
-{
- struct SerialHardware hw;
- struct Serial* serial;
- volatile struct REG_SCI_STRUCT* regs;
- IRQ_VECTOR irq_tx;
- IRQ_VECTOR irq_rx;
- int num_group;
- int id;
-};
-
-static inline void enable_tx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
-{
- regs->CR |= REG_SCI_CR_TEIE | REG_SCI_CR_TIIE;
-}
-
-static inline void enable_rx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
-{
- regs->CR |= REG_SCI_CR_RIE;
-}
-
-static inline void disable_tx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
-{
- regs->CR &= ~(REG_SCI_CR_TEIE | REG_SCI_CR_TIIE);
-}
-
-static inline void disable_rx_irq_bare(volatile struct REG_SCI_STRUCT* regs)
-{
- regs->CR &= ~(REG_SCI_CR_RIE | REG_SCI_CR_REIE);
-}
-
-static inline void disable_tx_irq(struct SerialHardware* _hw)
-{
- struct SCI* hw = (struct SCI*)_hw;
-
- disable_tx_irq_bare(hw->regs);
-}
-
-static inline void disable_rx_irq(struct SerialHardware* _hw)
-{
- struct SCI* hw = (struct SCI*)_hw;
-
- disable_rx_irq_bare(hw->regs);
-}
-
-static inline void enable_tx_irq(struct SerialHardware* _hw)
-{
- struct SCI* hw = (struct SCI*)_hw;
-
- enable_tx_irq_bare(hw->regs);
-}
-
-static inline void enable_rx_irq(struct SerialHardware* _hw)
-{
- struct SCI* hw = (struct SCI*)_hw;
-
- enable_rx_irq_bare(hw->regs);
-}
-
-static inline bool tx_irq_enabled(struct SerialHardware* _hw)
-{
- struct SCI* hw = (struct SCI*)_hw;
-
- return (hw->regs->CR & REG_SCI_CR_TEIE);
-}
-
-static void tx_isr(const struct SCI *hw)
-{
-#pragma interrupt warn
- volatile struct REG_SCI_STRUCT* regs = hw->regs;
-
- if (fifo_isempty(&hw->serial->txfifo))
- disable_tx_irq_bare(regs);
- else
- {
- // Clear transmitter flags before sending data
- (void)regs->SR;
- regs->DR = fifo_pop(&hw->serial->txfifo);
- }
-}
-
-static void rx_isr(const struct SCI *hw)
-{
-#pragma interrupt warn
- volatile struct REG_SCI_STRUCT* regs = hw->regs;
-
- // Propagate errors
- hw->serial->status |= regs->SR & (SERRF_PARITYERROR |
- SERRF_RXSROVERRUN |
- SERRF_FRAMEERROR |
- SERRF_NOISEERROR);
-
- /*
- * Serial IRQ can happen for two reason: data ready (RDRF) or overrun (OR)
- * If the data is ready, we need to fetch it from the data register or
- * the interrupt will retrigger immediatly. In case of overrun, instead,
- * the value of the data register is meaningless.
- */
- if (regs->SR & REG_SCI_SR_RDRF)
- {
- unsigned char data = regs->DR;
-
- if (fifo_isfull(&hw->serial->rxfifo))
- hw->serial->status |= SERRF_RXFIFOOVERRUN;
- else
- fifo_push(&hw->serial->rxfifo, data);
- }
-
- // Writing anything to the status register clear the error bits.
- regs->SR = 0;
-}
-
-static void init(struct SerialHardware* _hw, struct Serial* ser)
-{
- struct SCI* hw = (struct SCI*)_hw;
- volatile struct REG_SCI_STRUCT* regs = hw->regs;
-
- // Clear status register (IRQ/status flags)
- (void)regs->SR;
- regs->SR = 0;
-
- // Clear data register
- (void)regs->DR;
-
- // Install the handlers and set priorities for both IRQs
- irq_install(hw->irq_tx, (isr_t)tx_isr, hw);
- irq_install(hw->irq_rx, (isr_t)rx_isr, hw);
- irq_setpriority(hw->irq_tx, IRQ_PRIORITY_SCI_TX);
- irq_setpriority(hw->irq_rx, IRQ_PRIORITY_SCI_RX);
-
- // Activate the RX error interrupts, and RX/TX transmissions
- regs->CR = REG_SCI_CR_TE | REG_SCI_CR_RE;
- enable_rx_irq_bare(regs);
-
- // Disable GPIO pins for TX and RX lines
- // \todo this should be divided into serial 0 and 1
- REG_GPIO_SERIAL_0->PER |= REG_GPIO_SERIAL_MASK_0;
- REG_GPIO_SERIAL_1->PER |= REG_GPIO_SERIAL_MASK_1;
-
- hw->serial = ser;
-}
-
-static void cleanup(struct SerialHardware* _hw)
-{
- struct SCI* hw = (struct SCI*)_hw;
-
- // Uninstall the ISRs
- disable_rx_irq(_hw);
- disable_tx_irq(_hw);
- irq_uninstall(hw->irq_tx);
- irq_uninstall(hw->irq_rx);
-}
-
-static void setbaudrate(struct SerialHardware* _hw, unsigned long rate)
-{
- struct SCI* hw = (struct SCI*)_hw;
-
- // SCI has an internal 16x divider on the input clock, which comes
- // from the IPbus (see the scheme in user manual, 12.7.3). We apply
- // it to calculate the period to store in the register.
- hw->regs->BR = (IPBUS_FREQ + rate * 8ul) / (rate * 16ul);
-}
-
-static void setparity(struct SerialHardware* _hw, int parity)
-{
- // ???
- ASSERT(0);
-}
-
-
-#if CONFIG_SER_MULTI
-
-static void multi_init(void)
-{
- static bool flag = false;
- int i;
-
- if (flag)
- return;
-
- for (i = 0; i < MAX_MULTI_GROUPS; ++i)
- sem_init(&multi_sems[i]);
- flag = true;
-}
-
-static void init_lock(struct SerialHardware* _hw, struct Serial *ser)
-{
- struct SCI* hw = (struct SCI*)_hw;
-
- // Initialize the multi engine (if needed)
- multi_init();
-
- // Acquire the lock of the semaphore for this group
- ASSERT(hw->num_group >= 0);
- ASSERT(hw->num_group < MAX_MULTI_GROUPS);
- sem_obtain(&multi_sems[hw->num_group]);
-
- // Do a hardware switch to the given serial
- ser_hw_switch(hw->num_group, hw->id);
-
- init(_hw, ser);
-}
-
-static void cleanup_unlock(struct SerialHardware* _hw)
-{
- struct SCI* hw = (struct SCI*)_hw;
-
- cleanup(_hw);
-
- sem_release(&multi_sems[hw->num_group]);
-}
-
-#endif /* CONFIG_SER_MULTI */
-
-
-static const struct SerialHardwareVT SCI_VT =
-{
- .init = init,
- .cleanup = cleanup,
- .setBaudrate = setbaudrate,
- .setParity = setparity,
- .txStart = enable_tx_irq,
- .txSending = tx_irq_enabled,
-};
-
-#if CONFIG_SER_MULTI
-static const struct SerialHardwareVT SCI_MULTI_VT =
-{
- .init = init_lock,
- .cleanup = cleanup_unlock,
- .setBaudrate = setbaudrate,
- .setParity = setparity,
- .txStart = enable_tx_irq,
- .txSending = tx_irq_enabled,
-};
-#endif /* CONFIG_SER_MULTI */
-
-#define SCI_DESC_NORMAL(hwch) \
- { \
- .hw = \
- { \
- .table = &SCI_VT, \
- .rxbuffer = ser ## hwch ## _fifo_rx, \
- .txbuffer = ser ## hwch ## _fifo_tx, \
- .rxbuffer_size = countof(ser ## hwch ## _fifo_rx), \
- .txbuffer_size = countof(ser ## hwch ## _fifo_tx), \
- }, \
- .regs = ®_SCI[hwch], \
- .irq_rx = IRQ_SCI ## hwch ## _RECEIVER_FULL, \
- .irq_tx = IRQ_SCI ## hwch ## _TRANSMITTER_READY, \
- .num_group = -1, \
- .id = -1, \
- } \
- /**/
-
-#if CONFIG_SER_MULTI
-#define SCI_DESC_MULTI(hwch, group_, id_) \
- { \
- .hw = \
- { \
- .table = &SCI_MULTI_VT, \
- .rxbuffer = ser ## hwch ## _fifo_rx, \
- .txbuffer = ser ## hwch ## _fifo_tx, \
- .rxbuffer_size = countof(ser ## hwch ## _fifo_rx), \
- .txbuffer_size = countof(ser ## hwch ## _fifo_tx), \
- }, \
- .regs = ®_SCI[hwch], \
- .irq_rx = IRQ_SCI ## hwch ## _RECEIVER_FULL, \
- .irq_tx = IRQ_SCI ## hwch ## _TRANSMITTER_READY, \
- .num_group = group_, \
- .id = id_, \
- } \
- /**/
-#endif /* CONFIG_SER_MULTI */
-
-// \todo Move this into hw.h, with a little preprocessor magic
-static struct SCI SCIDescs[] =
-{
- SCI_DESC_NORMAL(0),
- SCI_DESC_MULTI(1, 0, 0),
- SCI_DESC_MULTI(1, 0, 1),
-};
-
-struct SerialHardware* ser_hw_getdesc(int unit)
-{
- ASSERT(unit < countof(SCIDescs));
- return &SCIDescs[unit].hw;
-}
+++ /dev/null
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright (C) 2003,2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright (C) 2000 Bernardo Innocenti <bernie@codewiz.org>
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief CPU specific serial I/O driver
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.7 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.6 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.5 2004/12/13 11:51:08 bernie
- *#* DISABLE_INTS/ENABLE_INTS: Convert to IRQ_DISABLE/IRQ_ENABLE.
- *#*
- *#* Revision 1.4 2004/08/25 14:12:08 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.3 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.2 2004/05/23 18:21:53 bernie
- *#* Trim CVS logs and cleanup header info.
- *#*
- *#*/
-
-#include "hw.h"
-#include "serhw.h"
-
-#define SER_HW_ENABLE_TX \
- ATOMIC( \
- if (!ser_sending) \
- { \
- ser_sending = true; \
- (INT_PEND1 |= INT1F_TI) \
- } \
- );
-
-static volatile bool ser_sending;
-
-// Serial TX intr
-INTERRUPT(0x30) void TI_interrupt(void)
-{
- if (CANT_SEND)
- {
- ser_sending = false;
- return;
- }
-
- /* Can we send two bytes at the same time? */
- if (SP_STAT & SPSF_TX_EMPTY)
- {
- SBUF = fifo_pop(&ser_txfifo);
-
- if (CANT_SEND)
- {
- ser_sending = false;
- return;
- }
- }
-
- SBUF = fifo_pop(&ser_txfifo);
-}
-
-INTERRUPT(0x32) void RI_interrupt(void)
-{
- ser_status |= SP_STAT &
- (SPSF_OVERRUN_ERROR | SPSF_PARITY_ERROR | SPSF_FRAMING_ERROR);
- if (fifo_isfull(&ser_rxfifo))
- ser_status |= SERRF_RXFIFOOVERRUN;
- else
- fifo_push(&ser_rxfifo, SBUF);
-}
-
-static void ser_setbaudrate(unsigned long rate)
-{
- // Calcola il periodo per la generazione del baud rate richiesto
- uint16_t baud = (uint16_t)(((CLOCK_FREQ / 16) / rate) - 1) | 0x8000;
- BAUD_RATE = (uint8_t)baud;
- BAUD_RATE = (uint8_t)(baud >> 8);
-}
-
-static void ser_hw_init(void)
-{
- // Inizializza la porta seriale
- SP_CON = SPCF_RECEIVE_ENABLE | SPCF_MODE1;
- ioc1_img |= IOC1F_TXD_SEL | IOC1F_EXTINT_SRC;
- IOC1 = ioc1_img;
-
- // Svuota il buffer di ricezione
- {
- uint8_t dummy = SBUF;
- }
-
- // Abilita gli interrupt
- INT_MASK1 |= INT1F_TI | INT1F_RI;
-}
-
+++ /dev/null
-#error This code must be revised for the new timer API
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2004 Giovanni Bajo
- *
- * -->
- *
- * \version $Id$
- *
- * \author Giovanni Bajo <rasky@develer.com>
- *
- * \brief Driver module for DSP56K
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.10 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.9 2006/02/21 21:28:02 bernie
- *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
- *#*
- *#* Revision 1.8 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.7 2005/04/11 19:10:28 bernie
- *#* Include top-level headers from cfg/ subdir.
- *#*
- *#* Revision 1.6 2004/11/16 22:37:14 bernie
- *#* Replace IPTR with iptr_t.
- *#*
- *#* Revision 1.5 2004/08/25 14:12:08 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.4 2004/07/30 14:27:49 rasky
- *#* Aggiornati alcuni file DSP56k per la nuova libreria di IRQ management
- *#*
- *#* Revision 1.3 2004/06/06 18:30:34 bernie
- *#* Import DSP56800 changes from SC.
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 18:23:30 bernie
- *#* Import drv/timer module.
- *#*
- *#*/
-
-#ifndef DRV_TIMER_DSP56K_H
-#define DRV_TIMER_DSP56K_H
-
-#include "timer.h"
-#include <DSP56F807.h>
-#include <cfg/compiler.h>
-#include <hw.h>
-#include <drv/irq.h>
-
-// Calculate register pointer and irq vector from hw.h setting
-#define REG_SYSTEM_TIMER PP_CAT(REG_TIMER_, SYSTEM_TIMER)
-#define SYSTEM_TIMER_IRQ_VECTOR PP_CAT(IRQ_TIMER_, SYSTEM_TIMER)
-
-/// Prescaler for the system timer
-#define TIMER_PRESCALER 16
-
-/// Frequency of the hardware high precision timer
-#define TIMER_HW_HPTICKS_PER_SEC (IPBUS_FREQ / TIMER_PRESCALER)
-
-/// Type of time expressed in ticks of the hardware high precision timer
-typedef uint16_t hptime_t;
-
-static void system_timer_isr(UNUSED(iptr_t, arg));
-
-static void timer_hw_init(void)
-{
- uint16_t compare;
-
- // Clear compare flag status and enable interrupt on compare
- REG_SYSTEM_TIMER->SCR &= ~REG_TIMER_SCR_TCF;
- REG_SYSTEM_TIMER->SCR |= REG_TIMER_SCR_TCFIE;
-
- // Calculate the compare value needed to generate an interrupt exactly
- // TICKS_PER_SEC times each second (usually, every millisecond). Check that
- // the calculation is accurate, otherwise there is a precision error
- // (probably the prescaler is too big or too small).
- compare = TIMER_HW_HPTICKS_PER_SEC / TICKS_PER_SEC;
- ASSERT((uint32_t)compare * TICKS_PER_SEC == IPBUS_FREQ / TIMER_PRESCALER);
- REG_SYSTEM_TIMER->CMP1 = compare;
-
- // The value for reload (at initializationa and after compare is met) is zero
- REG_SYSTEM_TIMER->LOAD = 0;
-
- // Set the interrupt handler and priority
- irq_install(SYSTEM_TIMER_IRQ_VECTOR, &system_timer_isr, NULL);
- irq_setpriority(SYSTEM_TIMER_IRQ_VECTOR, IRQ_PRIORITY_SYSTEM_TIMER);
-
- // Small preprocessor trick to generate the REG_TIMER_CTRL_PRIMARY_IPBYNN macro
- // needed to set the prescaler
- #define REG_CONTROL_PRESCALER PP_CAT(REG_TIMER_CTRL_PRIMARY_IPBY, TIMER_PRESCALER)
-
- // Setup the counter and start counting
- REG_SYSTEM_TIMER->CTRL =
- REG_TIMER_CTRL_MODE_RISING | // count rising edges (normal)
- REG_CONTROL_PRESCALER | // frequency (IPbus / TIMER_PRESCALER)
- REG_TIMER_CTRL_LENGTH; // up to CMP1, then reload
-}
-
-INLINE void timer_hw_irq(void)
-{
- // Clear the overflow flag so that we are ready for another interrupt
- REG_SYSTEM_TIMER->SCR &= ~REG_TIMER_SCR_TCF;
-}
-
-INLINE hptime_t timer_hw_hpread(void)
-{
- return REG_SYSTEM_TIMER->CNTR;
-}
-
-#define DEFINE_TIMER_ISR \
- static void system_timer_isr(UNUSED(iptr_t, arg))
-
-#endif /* DRV_TIMER_DSP56_H */
+++ /dev/null
-#error This code must be revised for the new timer API
-/**
- * \file
- * <!--
- * This file is part of BeRTOS.
- *
- * Bertos 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- *
- * Copyright 2003,2004 Develer S.r.l. (http://www.develer.com/)
- * Copyright 2000 Bernardo Innocenti
- *
- * -->
- *
- * \version $Id$
- *
- * \author Bernardo Innocenti <bernie@develer.com>
- *
- * \brief Low-level timer module for AVR
- */
-
-/*#*
- *#* $Log$
- *#* Revision 1.7 2006/07/19 12:56:26 bernie
- *#* Convert to new Doxygen style.
- *#*
- *#* Revision 1.6 2006/02/21 21:28:02 bernie
- *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
- *#*
- *#* Revision 1.5 2005/11/04 16:20:02 bernie
- *#* Fix reference to README.devlib in header.
- *#*
- *#* Revision 1.4 2004/12/13 11:51:08 bernie
- *#* DISABLE_INTS/ENABLE_INTS: Convert to IRQ_DISABLE/IRQ_ENABLE.
- *#*
- *#* Revision 1.3 2004/08/25 14:12:08 rasky
- *#* Aggiornato il comment block dei log RCS
- *#*
- *#* Revision 1.2 2004/06/03 11:27:09 bernie
- *#* Add dual-license information.
- *#*
- *#* Revision 1.1 2004/05/23 18:23:30 bernie
- *#* Import drv/timer module.
- *#*
- *#*/
-
-#ifndef TIMER_I196_H
-#define TIMER_I196_H
-
-/**
- * Retrigger TIMER2, adjusting the time to account for
- * the interrupt prologue latency.
- */
-#define TIMER_RETRIGGER (TIMER2 -= TICKS_RATE)
-
-#define TIMER_INIT \
- TIMER2 = (65535 - TICKS_RATE); \
- INT_MASK1 |= INT1F_T2OVF; \
- ATOMIC( \
- WSR = 1; \
- IOC3 |= IOC3F_T2_ENA; \
- WSR = 0; \
- )
-
-#define DEFINE_TIMER_ISR \
- INTERRUPT(0x38) void TM2_OVFL_interrupt(void); \
- INTERRUPT(0x38) void TM2_OVFL_interrupt(void)
-
-#endif /* DRV_TIMER_I196_H */