On Fri, Aug 15, 2014 at 12:32 PM, Premysl Houdek <kom541...@gmail.com> wrote: > Included variants: > tms570ls3137_hdk_intram - place code and data into internal SRAM > tms570ls3137_hdk_sdram - place code into external SDRAM and data to SRAM > tms570ls3137_hdk - variant prepared for stand-alone RTEMS aplication > stored and running directly from flash. Not working yet. > > Chip initialization code not included in BSP. > External startup generated by TI's HalCoGen was used for > testing and debugging. > > More information about TMS570 BSP can be found at > http://www.rtems.org/wiki/index.php/Tms570 > > Patch version 2 > - most of the formatting suggestion applied. > - BSP converted to use clock shell > - console driver "set attributes" tested. Baudrate change working > Todo: > refractor header files (name register fields) > --- > c/src/lib/libbsp/arm/tms570/Makefile.am | 144 +++++ > c/src/lib/libbsp/arm/tms570/README | 67 +++ > c/src/lib/libbsp/arm/tms570/bsp_specs | 13 + > c/src/lib/libbsp/arm/tms570/clock/clock.c | 157 ++++++ > c/src/lib/libbsp/arm/tms570/configure.ac | 52 ++ > .../lib/libbsp/arm/tms570/console/printk-support.c | 85 +++ > c/src/lib/libbsp/arm/tms570/console/tms570-sci.c | 560 > ++++++++++++++++++++ > c/src/lib/libbsp/arm/tms570/include/bsp.h | 102 ++++ > c/src/lib/libbsp/arm/tms570/include/irq.h | 134 +++++ > c/src/lib/libbsp/arm/tms570/include/tms570-pom.h | 101 ++++ > c/src/lib/libbsp/arm/tms570/include/tms570-rti.h | 95 ++++ > .../libbsp/arm/tms570/include/tms570-sci-driver.h | 40 ++ > c/src/lib/libbsp/arm/tms570/include/tms570-sci.h | 76 +++ > c/src/lib/libbsp/arm/tms570/include/tms570-vim.h | 75 +++ > c/src/lib/libbsp/arm/tms570/include/tms570.h | 28 + > c/src/lib/libbsp/arm/tms570/irq/irq.c | 192 +++++++ > .../make/custom/tms570ls3137_hdk-testsuite.tcfg | 19 + > .../arm/tms570/make/custom/tms570ls3137_hdk.cfg | 20 + > .../tms570/make/custom/tms570ls3137_hdk_intram.cfg | 21 + > .../tms570/make/custom/tms570ls3137_hdk_sdram.cfg | 20 + > c/src/lib/libbsp/arm/tms570/pom/tms570-pom.c | 100 ++++ > c/src/lib/libbsp/arm/tms570/preinstall.am | 123 +++++ > c/src/lib/libbsp/arm/tms570/startup/bspreset.c | 37 ++ > c/src/lib/libbsp/arm/tms570/startup/bspstart.c | 42 ++ > .../lib/libbsp/arm/tms570/startup/bspstarthooks.c | 41 ++ > .../arm/tms570/startup/linkcmds.tms570ls3137_hdk | 27 + > .../startup/linkcmds.tms570ls3137_hdk_intram | 28 + > .../tms570/startup/linkcmds.tms570ls3137_hdk_sdram | 27 + > 28 files changed, 2426 insertions(+) > create mode 100644 c/src/lib/libbsp/arm/tms570/Makefile.am > create mode 100644 c/src/lib/libbsp/arm/tms570/README > create mode 100644 c/src/lib/libbsp/arm/tms570/bsp_specs > create mode 100644 c/src/lib/libbsp/arm/tms570/clock/clock.c > create mode 100644 c/src/lib/libbsp/arm/tms570/configure.ac > create mode 100644 c/src/lib/libbsp/arm/tms570/console/printk-support.c > create mode 100644 c/src/lib/libbsp/arm/tms570/console/tms570-sci.c > create mode 100644 c/src/lib/libbsp/arm/tms570/include/bsp.h > create mode 100644 c/src/lib/libbsp/arm/tms570/include/irq.h > create mode 100644 c/src/lib/libbsp/arm/tms570/include/tms570-pom.h > create mode 100644 c/src/lib/libbsp/arm/tms570/include/tms570-rti.h > create mode 100644 c/src/lib/libbsp/arm/tms570/include/tms570-sci-driver.h > create mode 100644 c/src/lib/libbsp/arm/tms570/include/tms570-sci.h > create mode 100644 c/src/lib/libbsp/arm/tms570/include/tms570-vim.h > create mode 100644 c/src/lib/libbsp/arm/tms570/include/tms570.h > create mode 100644 c/src/lib/libbsp/arm/tms570/irq/irq.c > create mode 100644 > c/src/lib/libbsp/arm/tms570/make/custom/tms570ls3137_hdk-testsuite.tcfg > create mode 100644 > c/src/lib/libbsp/arm/tms570/make/custom/tms570ls3137_hdk.cfg > create mode 100644 > c/src/lib/libbsp/arm/tms570/make/custom/tms570ls3137_hdk_intram.cfg > create mode 100644 > c/src/lib/libbsp/arm/tms570/make/custom/tms570ls3137_hdk_sdram.cfg > create mode 100644 c/src/lib/libbsp/arm/tms570/network/tms570-ethernet.c > create mode 100644 c/src/lib/libbsp/arm/tms570/network/tms570-ethernet.h > create mode 100644 c/src/lib/libbsp/arm/tms570/pom/tms570-pom.c > create mode 100644 c/src/lib/libbsp/arm/tms570/preinstall.am > create mode 100644 c/src/lib/libbsp/arm/tms570/startup/bspreset.c > create mode 100644 c/src/lib/libbsp/arm/tms570/startup/bspstart.c > create mode 100644 c/src/lib/libbsp/arm/tms570/startup/bspstarthooks.c > create mode 100644 > c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk > create mode 100644 > c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk_intram > create mode 100644 > c/src/lib/libbsp/arm/tms570/startup/linkcmds.tms570ls3137_hdk_sdram [...] > diff --git a/c/src/lib/libbsp/arm/tms570/clock/clock.c > b/c/src/lib/libbsp/arm/tms570/clock/clock.c > new file mode 100644 > index 0000000..3e14cb3 > --- /dev/null > +++ b/c/src/lib/libbsp/arm/tms570/clock/clock.c > @@ -0,0 +1,157 @@ > +/** > + * @file clock.c > + * > + * @ingroup tms570 > + * > + * @brief clock functions definitions. > + */ > + > +/* > + * Copyright (c) 2014 Premysl Houdek <kom541...@gmail.com> > + * > + * Google Summer of Code 2014 at > + * Czech Technical University in Prague > + * Zikova 1903/4 > + * 166 36 Praha 6 > + * Czech Republic > + * > + * Based on LPC24xx and LPC1768 BSP > + * by embedded brains GmbH and others > + * > + * The license and distribution terms for this file may be > + * found in the file LICENSE in this distribution or at > + * http://www.rtems.org/license/LICENSE. > + */ > + > +#include <stdlib.h> > + > +#include <rtems.h> > +#include <bsp.h> > +#include <bsp/irq.h> > +#include <bsp/tms570-rti.h> > + > +/** > + * > + */ > +uint32_t tms570_rti_last_tick_fcr0; > + Make this variable static if it is only used in this file.
> +/** > + * @brief Initialize the HW peripheral for clock driver > + * > + * Clock driver is implemented by RTI module > + * > + * @retval Void > + */ > +static void tms570_clock_driver_support_initialize_hardware( void ) > +{ > + > + uint32_t microsec_per_tick = > rtems_configuration_get_microseconds_per_tick(); > + > + /* Hardware specific initialize */ > + TMS570_RTI.RTIGCTRL = 0; > + TMS570_RTI.RTICPUC0 = BSP_PLL_OUT_CLOCK /1000000 / 2; /* prescaler */ > + TMS570_RTI.RTITBCTRL = 2; > + TMS570_RTI.RTICAPCTRL = 0; > + TMS570_RTI.RTICOMPCTRL = 0; > + /* set counter to zero */ > + TMS570_RTI.RTIUC0 = 0; > + TMS570_RTI.RTIFRC0 = 0; > + /* clear interrupts*/ > + TMS570_RTI.RTICLEARINTENA = 0x00070f0f; > + TMS570_RTI.RTIINTFLAG = 0x0007000f; > + /* set timer */ > + TMS570_RTI.RTICOMP0 = TMS570_RTI.RTIFRC0 + microsec_per_tick; > + TMS570_RTI.RTICOMP0CLR = TMS570_RTI.RTICOMP0 + microsec_per_tick / 2; > + TMS570_RTI.RTIUDCP0 = microsec_per_tick; > + /* enable interupt */ > + TMS570_RTI.RTISETINTENA = 0x1; > + /* enable timer */ > + TMS570_RTI.RTIGCTRL = 1; > +} > + > +/** > + * @brief Clears interrupt source > + * > + * @retval Void > + */ > +static void tms570_clock_driver_support_at_tick( void ) > +{ > + TMS570_RTI.RTIINTFLAG = 0x00000001; > + tms570_rti_last_tick_fcr0 = TMS570_RTI.RTICOMP0 - TMS570_RTI.RTIUDCP0; > + /* TMS570_RTI.RTICOMP0 += 1000; */ Remove commented-out code that is not going to be uncommented in the future. Otherwise add a note about the purpose of the commented-out code. > +} > + > +/** > + * @brief registers RTI interrupt handler > + * > + * @param[in] Clock_isr new ISR handler > + * @param[in] Old_ticker old ISR handler (unused and type broken) > + * > + * @retval Void > + */ > +static void tms570_clock_driver_support_install_isr( > + rtems_isr_entry Clock_isr > +) > +{ > + rtems_status_code sc = RTEMS_SUCCESSFUL; > + > + sc = rtems_interrupt_handler_install( > + TMS570_IRQ_TIMER_0, > + "Clock", > + RTEMS_INTERRUPT_UNIQUE, > + (rtems_interrupt_handler) Clock_isr, > + NULL > + ); > + if (sc != RTEMS_SUCCESSFUL) { > + rtems_fatal_error_occurred(0xdeadbeef); > + } > +} > + > +/** > + * @brief disables RTI interrupt > + * > + * Called when closing clock driver > + * > + * @retval Void > + */ > +static void tms570_clock_driver_support_shutdown_hardware( void ) > +{ > + /* turn off the timer interrupts */ > + TMS570_RTI.RTICLEARINTENA = 0x20000; > +} > + > +/** > + * @brief returns the nanoseconds since last tick > + * > + * Return the nanoseconds since last tick > + * > + * @retval x nanoseconds > + * > + */ > +static uint32_t tms570_clock_driver_nanoseconds_since_last_tick( void ) > +{ > + uint32_t actual_fcr0 = TMS570_RTI.RTIFRC0; > + uint32_t nsec_since_tick; I guess this is actually usec (microseconds) since tick, since you multiply by 1000 for the return value? > + > + nsec_since_tick = actual_fcr0 - tms570_rti_last_tick_fcr0; > + > + return nsec_since_tick * 1000; > +} > + > +#define Clock_driver_support_initialize_hardware \ > + tms570_clock_driver_support_initialize_hardware > +#define Clock_driver_support_at_tick \ > + tms570_clock_driver_support_at_tick > +#define Clock_driver_support_initialize_hardware \ > + tms570_clock_driver_support_initialize_hardware > +#define Clock_driver_support_shutdown_hardware \ > + tms570_clock_driver_support_shutdown_hardware > +#define Clock_driver_nanoseconds_since_last_tick \ > + tms570_clock_driver_nanoseconds_since_last_tick > + > +#define Clock_driver_support_install_isr(Clock_isr, Old_ticker ) \ > + tms570_clock_driver_support_install_isr( Clock_isr ) > + > +void Clock_isr(void *arg); /* to supress warning */ > + > +#include "../../../shared/clockdrv_shell.h" [...] > diff --git a/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c > b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c > new file mode 100644 > index 0000000..89e3100 > --- /dev/null > +++ b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c > @@ -0,0 +1,560 @@ > +/** > + * @file tms570-sci.c > + * > + * @ingroup tms570 > + * > + * @brief Serial communication interface (SCI) functions definitions. > + */ > + > +/* > + * Copyright (c) 2014 Premysl Houdek <kom541...@gmail.com> > + * > + * Google Summer of Code 2014 at > + * Czech Technical University in Prague > + * Zikova 1903/4 > + * 166 36 Praha 6 > + * Czech Republic > + * > + * Based on LPC24xx and LPC1768 BSP > + * by embedded brains GmbH and others > + * > + * The license and distribution terms for this file may be > + * found in the file LICENSE in this distribution or at > + * http://www.rtems.org/license/LICENSE. > + */ > + > +#include <bspopts.h> > +#include <termios.h> > +#include <rtems/termiostypes.h> > +#include <libchip/sersupp.h> > +#include <bsp/tms570-sci.h> > +#include <bsp/tms570-sci-driver.h> > +#include <rtems/console.h> > +#include <bsp.h> > +#include <bsp/fatal.h> > +#include <bsp/irq.h> > + > +#define TMS570_SCI_BUFFER_SIZE 1 > + > +/** > + * @brief Table including all serial drivers > + * > + * Definitions of all serial drivers > + */ > +const tms570_sci_context driver_context_table[] = { > + { > + .device_name = "/dev/console", > + .regs = &TMS570_SCI, > + .irq = TMS570_IRQ_SCI_LEVEL_0, > + }, > + { > + .device_name = "/dev/ttyS1", > + .regs = &TMS570_SCI2, > + .irq = TMS570_IRQ_SCI2_LEVEL_0, > + } > +}; > + > +/** > + * @brief Serial drivers init function > + * > + * Initialize all serial drivers specified in driver_context_table > + * > + * @param[in] major > + * @param[in] minor > + * @param[in] arg > + * @retval RTEMS_SUCCESSFUL Initialization completed > + */ > +rtems_device_driver console_initialize( > + rtems_device_major_number major, > + rtems_device_minor_number minor, > + void *arg > +) > +{ > + rtems_status_code sc; > +#if CONSOLE_USE_INTERRUPTS > + const rtems_termios_device_handler *handler = > &tms570_sci_handler_interrupt; > +#else > + const rtems_termios_device_handler *handler = &tms570_sci_handler_polled; > +#endif > + > + /* > + * Initialize the Termios infrastructure. If Termios has already > + * been initialized by another device driver, then this call will > + * have no effect. > + */ > + rtems_termios_initialize(); > + > + /* Initialize each device */ > + for ( > + minor = 0; > + minor < RTEMS_ARRAY_SIZE(driver_context_table); > + ++minor > + ) { > + tms570_sci_context *ctx = (tms570_sci_context *) > &driver_context_table[minor]; > + > + /* > + * Install this device in the file system and Termios. In order > + * to use the console (i.e. being able to do printf, scanf etc. > + * on stdin, stdout and stderr), one device must be registered as > + * "/dev/console" (CONSOLE_DEVICE_NAME). > + */ > + sc = rtems_termios_device_install( > + ctx->device_name, > + major, > + minor, > + handler, > + ctx > + ); > + if (sc != RTEMS_SUCCESSFUL) { > + bsp_fatal(BSP_FATAL_CONSOLE_NO_DEV); > + } > + } > + return RTEMS_SUCCESSFUL; > +} > + > +/** > + * @brief Reads chars from HW > + * > + * Reads chars from HW peripheral specified in driver context. > + * TMS570 does not have HW buffer for serial line so this function can > + * return only 0 or 1 char > + * > + * @param[in] ctx context of the driver > + * @param[out] buf read data buffer > + * @param[in] N size of buffer > + * @retval x Number of read chars from peripherals > + */ > +static int tms570_sci_read_received_chars( > + tms570_sci_context * ctx, > + char * buf, > + int N) > +{ > + if (N<1){ Fix white space, there should be a space before and after each parenthesis and operator here, that is: if ( N < 1 ) { > + return 0; > + } > + if (ctx->regs->SCIRD != 0){ ditto. > + buf[0] = ctx->regs->SCIRD; > + return 1; > + } > + return 0; > +} > + > +/** > + * @brief Enables RX interrupt > + * > + * Enables RX interrupt source of SCI peripheral > + * specified in the driver context. > + * > + * @param[in] ctx context of the driver > + * @retval Void > + */ > +static void tms570_sci_enable_interrupts(tms570_sci_context * ctx){ > + ctx->regs->SCISETINT = (1<<9); > +} > + > +/** > + * @brief Disables RX interrupt > + * > + * Disables RX interrupt source of SCI peripheral specified in the driver > context. > + * > + * @param[in] ctx context of the driver > + * @retval Void > + */ > +static void tms570_sci_disable_interrupts(tms570_sci_context * ctx){ > + ctx->regs->SCICLEARINT = (1<<9); > +} > + > +/** > + * @brief Check whether driver has put char in HW > + * > + * Check whether driver has put char in HW. > + * This information is read from the driver context not from a peripheral. > + * TMS570 does not have write data buffer asociated with SCI > + * so the return can be only 0 or 1. > + * > + * @param[in] ctx context of the driver > + * @retval x > + */ > +static int tms570_sci_transmitted_chars(tms570_sci_context * ctx) > +{ > + int ret; > + > + ret = ctx->tx_chars_in_hw; > + if ( ret == 1 ){ > + ctx->tx_chars_in_hw = 0; > + return 1; > + } > + return ret; > +} > + > +/** > + * @brief Set attributes of the HW peripheral > + * > + * Sets attributes of the HW peripheral (parity, baud rate, etc.) > + * TODO: untested function > + * > + * @param[in] tty rtems_termios_tty > + * @param[in] t termios driver > + * @retval true peripheral setting is changed > + */ > +static bool tms570_sci_set_attributes( > + rtems_termios_tty *tty, > + const struct termios *t > +) > +{ > + > + tms570_sci_context *ctx = rtems_termios_get_device_context(tty); > + rtems_interrupt_lock_context lock_context; > + int32_t bauddiv; > + int32_t baudrate; > + > + rtems_termios_interrupt_lock_acquire(tty, &lock_context); > + > + ctx->regs->SCIGCR1 &= ~( (1<<7) | (1<<25) | (1<<24) ); > + > + ctx->regs->SCIGCR1 &= ~(1<<4); /*one stop bit*/ > + ctx->regs->SCIFORMAT = 0x7; > + > + switch (t->c_cflag & (PARENB|PARODD)) { > + case (PARENB|PARODD): > + /* Odd parity */ > + ctx->regs->SCIGCR1 &= ~(1<<3); > + ctx->regs->SCIGCR1 |= (1<<2); > + break; > + > + case PARENB: > + /* Even parity */ > + ctx->regs->SCIGCR1 |= (1<<3); > + ctx->regs->SCIGCR1 |= (1<<2); > + break; > + > + default: > + case 0: > + case PARODD: > + /* No Parity */ > + ctx->regs->SCIGCR1 &= ~(1<<2); > + } > + > + /* Baud rate */ > + baudrate = rtems_termios_baud_to_number(cfgetospeed(t)); > + baudrate *= 2 * 16; > + bauddiv = (BSP_PLL_OUT_CLOCK + baudrate / 2) / baudrate; > + ctx->regs->BRS = bauddiv; > + > + ctx->regs->SCIGCR1 |= (1<<7) | (1<<25) | (1<<24); > + > + rtems_termios_interrupt_lock_release(tty, &lock_context); > + > + return true; > +} > + > +/** > + * @brief sci interrupt handler > + * > + * Handler checks which interrupt occured and provides nessesary maintenance > + * dequeue characters in termios driver whether character is send succesfully > + * enqueue characters in termios driver whether character is recieved > + * > + * @param[in] arg rtems_termios_tty > + * @retval Void > + */ > +static void tms570_sci_interrupt_handler(void * arg){ > + rtems_termios_tty *tty = arg; > + tms570_sci_context *ctx = rtems_termios_get_device_context(tty); > + char buf[TMS570_SCI_BUFFER_SIZE]; > + size_t n; > + > + /* > + * Check if we have received something. > + */ > + if ( (ctx->regs->SCIFLR & (1<<9) ) == (1<<9) ){ > + n = tms570_sci_read_received_chars(ctx, buf, TMS570_SCI_BUFFER_SIZE); > + if (n > 0) { > + /* Hand the data over to the Termios infrastructure */ > + rtems_termios_enqueue_raw_characters(tty, buf, n); > + } > + } > + /* > + * Check if we have something transmitted. > + */ > + if ( (ctx->regs->SCIFLR & (1<<8) ) == (1<<8) ){ > + n = tms570_sci_transmitted_chars(ctx); > + if (n > 0) { > + /* > + * Notify Termios that we have transmitted some characters. It > + * will call now the interrupt write function if more characters > + * are ready for transmission. > + */ > + rtems_termios_dequeue_characters(tty, n); > + } > + } > +} > + > +/** > + * @brief sci write function called from interrupt > + * > + * Nonblocking write function. Writes characters to HW peripheral > + * TMS570 does not have write data buffer asociated with SCI > + * so only one character can be written. > + * > + * @param[in] tty rtems_termios_tty > + * @param[in] buf buffer of characters pending to send > + * @param[in] len size of the buffer > + * @retval Void > + */ > +static void tms570_sci_interrupt_write( > + rtems_termios_tty *tty, > + const char *buf, > + size_t len > +) > +{ > + tms570_sci_context *ctx = rtems_termios_get_device_context(tty); > + > + if (len > 0) { > + /* start UART TX, this will result in an interrupt when done */ > + ctx->regs->SCITD = *buf; > + /* character written - raise count*/ > + ctx->tx_chars_in_hw = 1; > + /* Enable TX interrupt (interrupt is edge-triggered) */ > + ctx->regs->SCISETINT = (1<<8); > + > + } else { > + /* No more to send, disable TX interrupts */ > + ctx->regs->SCICLEARINT = (1<<8); > + /* Tell close that we sent everything */ > + } > +} > + > +/** > + * @brief sci write function > + * > + * Blocking write function. Waits until HW peripheral is ready and then > writes > + * character to HW peripheral. Writes all characters in the buffer. > + * > + * @param[in] tty rtems_termios_tty > + * @param[in] buf buffer of characters pending to send > + * @param[in] len size of the buffer > + * @retval Void > + */ > +static void tms570_sci_poll_write( > + rtems_termios_tty *tty, > + const char *buf, > + size_t n > +) > +{ > + tms570_sci_context *ctx = rtems_termios_get_device_context(tty); > + size_t i; > + > + /* Write */ > + > + for (i = 0; i < n; ++i) { > + while ( (ctx->regs->SCIFLR & (1<<11) ) == 0) { > + ; > + } > + ctx->regs->SCITD = buf[i]; > + } > +} > + > +/** > + * @brief See if there is recieved charakter to read > + * > + * read the RX flag from peripheral specified in context > + * > + * @param[in] ctx context of the driver > + * @retval 0 No character to read > + * @retval x Character ready to read > + */ > +static int TMS570_sci_can_read_char( > + tms570_sci_context * ctx > +) > +{ > + return ctx->regs->SCIFLR & (1<<9); > +} > + > +/** > + * @brief reads character from peripheral > + * > + * reads the recieved character from peripheral specified in context > + * > + * @param[in] ctx context of the driver > + * @retval x Character > + */ > +static char TMS570_sci_read_char( > + tms570_sci_context * ctx > +) > +{ > + return ctx->regs->SCIRD; > +} > + > +/** > + * @brief sci read function > + * > + * check if there is recieved character to be read and reads it. > + * > + * @param[in] tty rtems_termios_tty (context of the driver) > + * @retval -1 No character to be read > + * @retval x Read character > + */ > +static int tms570_sci_poll_read(rtems_termios_tty *tty) > +{ > + tms570_sci_context *ctx = rtems_termios_get_device_context(tty); > + > + /* Check if a character is available */ > + if (TMS570_sci_can_read_char(ctx)) { > + return TMS570_sci_read_char(ctx); > + } else { > + return -1; > + } > +} > + > +/** > + * @brief initialization of the driver > + * > + * initialization of the HW peripheral specified in contex of the driver. > + * This function is called only once when opening the driver. > + * > + * @param[in] tty context of the driver > + * @param[in] args > + * @retval false Error occured during initialization > + * @retval true Driver is open and ready > + */ > +static bool tms570_sci_poll_first_open( > + rtems_termios_tty *tty, > + rtems_libio_open_close_args_t *args > +) > +{ > + bool ok; > + tms570_sci_context *ctx = rtems_termios_get_device_context(tty); > + /* TODO: test peripheral startup code below > + ctx->regs->SCISETINTLVL = 0; > + */ > + rtems_termios_set_best_baud(tty, TMS570_SCI_BAUD_RATE); > + ok = tms570_sci_set_attributes(tty, rtems_termios_get_termios(tty)); > + if ( !ok ) { > + return false; > + } > + return true; > +} > + > +/** > + * @brief initialization of the interrupt driven driver > + * > + * calls tms570_sci_poll_first_open function. > + * install and enables interrupts. > + * > + * @param[in] tty context of the driver > + * @param[in] args > + * @retval false Error occured during initialization > + * @retval true Driver is open and ready > + */ > +static bool tms570_sci_interrupt_first_open( > + rtems_termios_tty *tty, > + rtems_libio_open_close_args_t *args > +) > +{ > + tms570_sci_context *ctx = rtems_termios_get_device_context(tty); > + rtems_status_code sc; > + bool ret; > + > + ret = tms570_sci_poll_first_open(tty,args); > + if ( ret == false ){ > + return false; > + } > + /* Register Interrupt handler */ > + sc = rtems_interrupt_handler_install(ctx->irq, > + ctx->device_name, > + RTEMS_INTERRUPT_SHARED, > + tms570_sci_interrupt_handler, > + tty); Continuation lines get just an extra double-indent (4 spaces). Also, put the closing ); on its own line without extra indentation. > + if ( sc != RTEMS_SUCCESSFUL ) > + return false; > + tms570_sci_enable_interrupts(rtems_termios_get_device_context(tty)); > + return true; > +} > + > +/** > + * @brief closes sci peripheral > + * > + * @param[in] tty context of the driver > + * @param[in] args > + * @retval false Error occured during initialization > + * @retval true Driver is open and ready > + */ > +static void tms570_sci_poll_last_close( > + rtems_termios_tty *tty, > + rtems_libio_open_close_args_t *args > +) > +{ > + /*tms570_sci_context *ctx = rtems_termios_get_device_context(tty);*/ > + > + /* TODO: Here shall be peripheral HW reset, someday */ > + > +} > + > +/** > + * @brief closes sci peripheral of interrupt driven driver > + * > + * calls tms570_sci_poll_last_close and disables interrupts > + * > + * @param[in] tty context of the driver > + * @param[in] args > + * @retval false Error occured during initialization > + * @retval true Driver is open and ready > + */ > +static void tms570_sci_interrupt_last_close( > + rtems_termios_tty *tty, > + rtems_libio_open_close_args_t *args > +) > +{ > + tms570_sci_context *ctx = rtems_termios_get_device_context(tty); > + rtems_interrupt_lock_context lock_context; > + > + /* Turn off RX interrupts */ > + rtems_termios_interrupt_lock_acquire(tty, &lock_context); > + tms570_sci_disable_interrupts(ctx); > + rtems_termios_interrupt_lock_release(tty, &lock_context); > + > + /* Flush device */ > + while ((ctx->regs->SCIFLR & (1<<11)) > 0) { > + ;/* Wait until all data has been sent */ > + } > + > + /* uninstall ISR */ > + rtems_interrupt_handler_remove(ctx->irq, tms570_sci_interrupt_handler, > tty); > + > + tms570_sci_poll_last_close(tty,args); > +} > + > +/** > + * @brief Struct containing definitions of polled driver functions. > + * > + * Encapsulates polled driver functions. > + * Use of this table is determited by not defining TMS570_USE_INTERRUPTS > + */ > +const rtems_termios_device_handler tms570_sci_handler_polled = { > + .first_open = tms570_sci_poll_first_open, > + .last_close = tms570_sci_poll_last_close, > + .poll_read = tms570_sci_poll_read, > + .write = tms570_sci_poll_write, > + .set_attributes = tms570_sci_set_attributes, > + .stop_remote_tx = NULL, > + .start_remote_tx = NULL, > + .mode = TERMIOS_POLLED > +}; > + > +/** > + * @brief Struct containing definitions of interrupt driven driver functions. > + * > + * Encapsulates interrupt driven driver functions. > + * Use of this table is determited by defining TMS570_USE_INTERRUPTS > + */ > +const rtems_termios_device_handler tms570_sci_handler_interrupt = { > + .first_open = tms570_sci_interrupt_first_open, > + .last_close = tms570_sci_interrupt_last_close, > + .poll_read = NULL, > + .write = tms570_sci_interrupt_write, > + .set_attributes = tms570_sci_set_attributes, > + .stop_remote_tx = NULL, > + .start_remote_tx = NULL, > + .mode = TERMIOS_IRQ_DRIVEN > +}; > diff --git a/c/src/lib/libbsp/arm/tms570/include/bsp.h > b/c/src/lib/libbsp/arm/tms570/include/bsp.h > new file mode 100644 > index 0000000..fccfca5 > --- /dev/null > +++ b/c/src/lib/libbsp/arm/tms570/include/bsp.h > @@ -0,0 +1,102 @@ > +/** > + * @file bsp.h > + * > + * @ingroup tms570 > + * > + * @brief Global BSP definitions. > + */ > + > +/* > + * Copyright (c) 2014 Premysl Houdek <kom541...@gmail.com> > + * > + * Google Summer of Code 2014 at > + * Czech Technical University in Prague > + * Zikova 1903/4 > + * 166 36 Praha 6 > + * Czech Republic > + * > + * Based on LPC24xx and LPC1768 BSP > + * > + * The license and distribution terms for this file may be > + * found in the file LICENSE in this distribution or at > + * http://www.rtems.org/license/LICENSE. > + */ > + > +#ifndef LIBBSP_ARM_TMS570_BSP_H > +#define LIBBSP_ARM_TMS570_BSP_H > + > +#include <bspopts.h> > + > +#define TMS570_PCLK ( TMS570_CCLK / TMS570_PCLKDIV ) > +#define TMS570_MPU_REGION_COUNT 8u > + > +#define BSP_FEATURE_IRQ_EXTENSION > + > +#ifndef ASM > + > +#include <rtems.h> > +#include <rtems/console.h> > +#include <rtems/clockdrv.h> > +#include <bsp/default-initial-extension.h> > + > +#define BSP_OSCILATOR_CLOCK 8000000 > +#define BSP_PLL_OUT_CLOCK 160000000 > + > +/** Define operation count for Tests */ > +#define OPERATION_COUNT 4 > + > +#ifdef __cplusplus > +extern "C" { > +#endif /* __cplusplus */ > + > +struct rtems_bsdnet_ifconfig; > + > +/** > + * @defgroup tms570 TMS570 Support > + * > + * @ingroup bsp_arm > + * > + * @brief TMS570 support package. > + * > + * @{ > + */ > + > +/** > + * @brief Optimized idle task. > + * > + * This idle task sets the power mode to idle. This causes the processor > + * clock to be stopped, while on-chip peripherals remain active. > + * Any enabled interrupt from a peripheral or an external interrupt source > + * will cause the processor to resume execution. > + * > + * To enable the idle task use the following in the system configuration: > + * > + * @code > + * #include <bsp.h> > + * > + * #define CONFIGURE_INIT > + * > + * #define CONFIGURE_IDLE_TASK_BODY bsp_idle_thread > + * > + * #include <confdefs.h> > + * @endcode > + */ Do we need all this documentation copied here? > +void* bsp_idle_thread( uintptr_t ignored ); > + > + > + Remove extra blank lines. > +/** > + * @brief Restarts the bsp with "addr" address > + * @param addr Address used to restart the bsp > + */ > +void bsp_restart( const void *addr ); > + > +/** @} */ > + > +#ifdef __cplusplus > +} > +#endif /* __cplusplus */ > + > +#endif /* ASM */ > + > +#endif /* LIBBSP_ARM_TMS570_BSP_H */ > diff --git a/c/src/lib/libbsp/arm/tms570/include/tms570-pom.h > b/c/src/lib/libbsp/arm/tms570/include/tms570-pom.h > new file mode 100644 > index 0000000..e1bbbcb > --- /dev/null > +++ b/c/src/lib/libbsp/arm/tms570/include/tms570-pom.h > @@ -0,0 +1,101 @@ > +/** > + * @file tms570-pom.h > + * @ingroup tms570 > + * @brief Parameter Overlay Module (POM) header file > + */ > + > +/* > + * Copyright (c) 2014 Pavel Pisa <p...@cmp.felk.cvut.cz> > + * > + * Czech Technical University in Prague > + * Zikova 1903/4 > + * 166 36 Praha 6 > + * Czech Republic > + * > + * The license and distribution terms for this file may be > + * found in the file LICENSE in this distribution or at > + * http://www.rtems.org/license/LICENSE. > + */ > + > + > +#ifndef LIBBSP_ARM_TMS570_POM_H > +#define LIBBSP_ARM_TMS570_POM_H > + > +#include <stdint.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif /* __cplusplus */ > + > +#define TMS570_POM_REGIONS 32 > +#define TMS570_POM_GLBCTRL_ENABLE 0x000000a0a > + > +#define TMS570_POM_REGSIZE_DISABLED 0 > +#define TMS570_POM_REGSIZE_64B 1 > +#define TMS570_POM_REGSIZE_128B 2 > +#define TMS570_POM_REGSIZE_256B 3 > +#define TMS570_POM_REGSIZE_5120B 4 > +#define TMS570_POM_REGSIZE_1KB 5 > +#define TMS570_POM_REGSIZE_2KB 6 > +#define TMS570_POM_REGSIZE_4KB 7 > +#define TMS570_POM_REGSIZE_8KB 8 > +#define TMS570_POM_REGSIZE_16KB 9 > +#define TMS570_POM_REGSIZE_32KB 0xa > +#define TMS570_POM_REGSIZE_64KB 0xb > +#define TMS570_POM_REGSIZE_128KB 0xc > +#define TMS570_POM_REGSIZE_256KB 0xd > + These defines would look nicer if you used either decimal or hex. > diff --git a/c/src/lib/libbsp/arm/tms570/irq/irq.c > b/c/src/lib/libbsp/arm/tms570/irq/irq.c > new file mode 100644 > index 0000000..87771b8 > --- /dev/null > +++ b/c/src/lib/libbsp/arm/tms570/irq/irq.c > @@ -0,0 +1,192 @@ > +/** > + * @file irq.c > + * > + * @ingroup tms570 > + * > + * @brief TMS570 interrupt support functions definitions. > + */ > + > +/* > + * Copyright (c) 2014 Premysl Houdek <kom541...@gmail.com> > + * > + * Google Summer of Code 2014 at > + * Czech Technical University in Prague > + * Zikova 1903/4 > + * 166 36 Praha 6 > + * Czech Republic > + * > + * Based on LPC24xx and LPC1768 BSP > + * > + * The license and distribution terms for this file may be > + * found in the file LICENSE in this distribution or at > + * http://www.rtems.org/license/LICENSE. > + */ > + > +#include <rtems/score/armv4.h> > + > +#include <bsp.h> > +#include <bsp/irq-generic.h> > +#include <bsp/tms570-vim.h> > +#include <bsp/irq.h> > +#include <rtems/score/armv4.h> > + > +/** > + * @brief Check if isr vector is valid > + * > + * Check if isr vector is valid by using BSP_INTERRUPT_VECTOR_MAX and > + * BSP_INTERRUPT_VECTOR_MIN defined in irq.h > + * > + * @param[in] vector interrupt vector to be checked. > + * @retval TRUE vector is valid. > + * @retval FALSE vector is invalid > + */ > +static inline bool tms570_irq_is_valid( > + rtems_vector_number vector > +) > +{ > + return (vector <= BSP_INTERRUPT_VECTOR_MAX) && > + (vector > BSP_INTERRUPT_VECTOR_MIN); > +} > + > +unsigned int priorityTable[BSP_INTERRUPT_VECTOR_MAX+1]; > + > +/** > + * @brief Set priority of the interrupt vector. > + * > + * This function is here because of compability. It should set > + * priority of the interrupt vector. > + * @warning It does not set any priority at HW layer. It is nearly imposible > to > + * @warning set priority of the interrupt on TMS570 in a nice way. > + * @param[in] vector vector of isr > + * @param[in] priority new priority assigned to the vector > + * @return Void > + */ > +void tms570_irq_set_priority( > + rtems_vector_number vector, > + unsigned priority > +) > +{ > + if (tms570_irq_is_valid(vector)) { > + priorityTable[vector] = priority; > + } > +} > + > +/** > + * @brief Gets priority of the interrupt vector. > + * > + * This function is here because of compability. It returns priority > + * of the isr vector last set by tms570_irq_set_priority function. > + * > + * @warning It does not return any real priority of the HW layer. > + * @param[in] vector vector of isr > + * @retval 0 vector is invalid. > + * @retval priority priority of the interrupt > + */ > +unsigned tms570_irq_get_priority( > + rtems_vector_number vector > +) > +{ > + if (tms570_irq_is_valid(vector)) { > + return priorityTable[vector]; > + } > + return 0; > +} > + > +/** > + * @brief Interrupt dispatch > + * > + * Called by OS to determine which interrupt occured. > + * Function passes control to interrupt handler. > + * > + * @return Void > + */ > +void bsp_interrupt_dispatch(void) > +{ > + rtems_vector_number vector = TMS570_VIM.IRQINDEX-1; > + > + bsp_interrupt_handler_dispatch(vector); > +} > + > +/** > + * @brief enables interrupt vector in the HW > + * > + * Enables HW interrupt for specified vector > + * > + * @param[in] vector vector of the isr which needs to be enabled. > + * @retval RTEMS_INVALID_ID vector is invalid. > + * @retval RTEMS_SUCCESSFUL interrupt source enabled. > + */ > +rtems_status_code bsp_interrupt_vector_enable( > + rtems_vector_number vector > +) > +{ > + if(!tms570_irq_is_valid(vector)) > + return RTEMS_INVALID_ID; > + > + TMS570_VIM.REQENASET[vector >> 5] = 1 << (vector & 0x1f); > + > + return RTEMS_SUCCESSFUL; > +} > + > +/** > + * @brief disables interrupt vector in the HW > + * > + * Disables HW interrupt for specified vector > + * > + * @param[in] vector vector of the isr which needs to be disabled. > + * @retval RTEMS_INVALID_ID vector is invalid. > + * @retval RTEMS_SUCCESSFUL interrupt source disabled. > + */ > +rtems_status_code bsp_interrupt_vector_disable( > + rtems_vector_number vector > +) > +{ > + if(!tms570_irq_is_valid(vector)) > + return RTEMS_INVALID_ID; > + > + TMS570_VIM.REQENACLR[vector >> 5] = 1 << (vector & 0x1f); > + > + return RTEMS_SUCCESSFUL; > +} > + > +/** > + * @brief Init function of interrupt module > + * > + * Resets vectored interrupt interface to default state. > + * Disables all interrupts. > + * Set all sources as IRQ (not FIR). > + * > + * @retval RTEMS_SUCCESSFUL All is set > + */ > +rtems_status_code bsp_interrupt_facility_initialize(void) > +{ > + void (**vim_vec)(void) = (void (**)(void)) 0xFFF82000; > + unsigned int value = 0x00010203; > + unsigned int i = 0; > + uint32_t sctlr; > + > + /* Disable interrupts */ > + for(i = 0; i < 3; i++) > + TMS570_VIM.REQENACLR[i] = 0xffffffff; > + /* Map default events on interrupt vectors */ > + for(i=0;i<24;i+=1,value += 0x04040404) Add more white space around the parens and operators. Also, I believe RTEMS prefers to always use { } even if there is only one line following the conditional/loop statement. Perhaps this is not explicitly stated though. > + TMS570_VIM.CHANCTRL[i] = value; > + /* Set all vectors as IRQ (not FIR) */ > + TMS570_VIM.FIRQPR[0] = 3; > + TMS570_VIM.FIRQPR[1] = 0; > + TMS570_VIM.FIRQPR[2] = 0; > + > + /*_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ARMV4_Exception_interrupt, > NULL);*/ > + for(i = 0; i <= 94; i++) > + vim_vec[i] = _ARMV4_Exception_interrupt; > + > + /* Clear bit VE in SCTLR register to not use VIM IRQ exception bypass*/ > + asm volatile ("mrc p15, 0, %0, c1, c0, 0\n": "=r" (sctlr)); > + sctlr &= ~(1 << 24); > + asm volatile ("mcr p15, 0, %0, c1, c0, 0\n": : "r" (sctlr)); > + > + return RTEMS_SUCCESSFUL; > +} > + > + > + Remove extra blank lines. > diff --git a/c/src/lib/libbsp/arm/tms570/network/tms570-ethernet.c > b/c/src/lib/libbsp/arm/tms570/network/tms570-ethernet.c > new file mode 100644 > index 0000000..e69de29 > diff --git a/c/src/lib/libbsp/arm/tms570/network/tms570-ethernet.h > b/c/src/lib/libbsp/arm/tms570/network/tms570-ethernet.h > new file mode 100644 > index 0000000..e69de29 Empty files? > diff --git a/c/src/lib/libbsp/arm/tms570/pom/tms570-pom.c > b/c/src/lib/libbsp/arm/tms570/pom/tms570-pom.c > new file mode 100644 > index 0000000..be2d904 > --- /dev/null > +++ b/c/src/lib/libbsp/arm/tms570/pom/tms570-pom.c > @@ -0,0 +1,100 @@ > +/** > + * @file tms570-pom.c > + * > + * @ingroup tms570 > + * > + * @brief TMS570 Parameter Overlay Module functions definitions. > + */ > + > + /* > + * Copyright (c) 2014 Pavel Pisa <p...@cmp.felk.cvut.cz> > + * > + * Czech Technical University in Prague > + * Zikova 1903/4 > + * 166 36 Praha 6 > + * Czech Republic > + * > + * The license and distribution terms for this file may be > + * found in the file LICENSE in this distribution or at > + * http://www.rtems.org/license/LICENSE. > + */ > + > +#include <stdint.h> > +#include <bsp/tms570-pom.h> > +#include <bsp/linker-symbols.h> > +#include <bsp.h> > + > +/** > + * @brief Prints part of the memory > + * > + * debug function > + * > + * @retval 0 > + */ > +int mem_dump(void *buf, unsigned long start, unsigned long len, int blen) > +{ > + unsigned long addr=start; > + volatile unsigned char *p=buf; > + int i; > + > + while ( len ){ > + printk("%08lX:",addr); > + i=len>16?16:len; > + addr+=i; > + len-=i; > + while(i>0){ Add whitespace. > + i -= blen; > + switch(blen){ > + case 4: > + printk("%08lX%c",(unsigned long)*(volatile uint32_t*)p,i>0?' > ':'\n'); > + break; > + case 2: > + printk("%04X%c",*(volatile uint16_t*)p,i>0?' ':'\n'); > + break; > + default: > + printk("%02X%c",*(volatile uint8_t*)(p),i>0?' ':'\n'); > + break; > + } > + p += blen; > + } > + } > + return 0; > +} > + > +/** > + * @brief remaps vector table > + * > + * transfer the rtems start vector table to address 0x0 > + * > + * @retval Void > + */ > +void tms570_pom_remap(void) > +{ > + Delete blank line here. Shouldn't be one at start of function. > + int i; > + uint32_t vec_overlay_start = 0x08000000; > + > + memcpy((void*)vec_overlay_start, bsp_start_vector_table_begin, 64); > + > + TMS570_POM.GLBCTRL = 0; > + > + for (i = 0; i < TMS570_POM_REGIONS; i++) > + TMS570_POM.REG[i].REGSIZE = TMS570_POM_REGSIZE_DISABLED; > + > + TMS570_POM.REG[0].PROGSTART = 0x0 & TMS570_POM_REGADDRMASK; > + TMS570_POM.REG[0].OVLSTART = vec_overlay_start & TMS570_POM_REGADDRMASK; > + TMS570_POM.REG[0].REGSIZE = TMS570_POM_REGSIZE_64B; > + > + TMS570_POM.GLBCTRL = TMS570_POM_GLBCTRL_ENABLE | > + (vec_overlay_start & ~TMS570_POM_REGADDRMASK); > + > +#ifdef POM_REMAP_TEST > + p32[1] = 0xe12fff1e; > + > + mem_dump((uint8_t *)0x00000000, 0x00000000, 256, 1); > + > + printk("Probing call to address 0x00000004\n"); > + ((void(*)(void))4)(); > + printk("POM call really returned\n"); > +#endif /*POM_REMAP_TEST*/ > +} -Gedare _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel