[PATCH v2] BSP for TMS570LS31x Hercules Development Kit from TI (TMS570LS3137)

Gedare Bloom gedare at rtems.org
Mon Aug 18 13:36:18 UTC 2014


On Fri, Aug 15, 2014 at 12:32 PM, Premysl Houdek <kom541000 at 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 <kom541000 at 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 <kom541000 at 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 <kom541000 at 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 <pisa at 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 <kom541000 at 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 <pisa at 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


More information about the devel mailing list