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

Gedare Bloom gedare at rtems.org
Thu Aug 14 13:52:53 UTC 2014


Since Joel commented on style issues, I'll try to stick to technical questions.

On Wed, Aug 13, 2014 at 3:48 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
> ---
>  c/src/lib/libbsp/arm/tms570/Makefile.am            |  148 ++++++
>  c/src/lib/libbsp/arm/tms570/README                 |   64 +++
>  c/src/lib/libbsp/arm/tms570/bsp_specs              |   13 +
>  c/src/lib/libbsp/arm/tms570/clock/tms570-rti.c     |  205 ++++++++
>  c/src/lib/libbsp/arm/tms570/configure.ac           |   45 ++
>  .../lib/libbsp/arm/tms570/console/printk-support.c |   68 +++
>  c/src/lib/libbsp/arm/tms570/console/tms570-sci.c   |  546 ++++++++++++++++++++
>  c/src/lib/libbsp/arm/tms570/include/bsp.h          |  101 ++++
>  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  |   39 ++
>  c/src/lib/libbsp/arm/tms570/include/tms570-sci.h   |   75 +++
>  c/src/lib/libbsp/arm/tms570/include/tms570-vim.h   |   74 +++
>  c/src/lib/libbsp/arm/tms570/include/tms570.h       |   29 ++
>  c/src/lib/libbsp/arm/tms570/irq/irq.c              |  182 +++++++
>  .../make/custom/tms570ls3137_hdk-testsuite.tcfg    |   19 +
>  .../arm/tms570/make/custom/tms570ls3137_hdk.cfg    |   19 +
>  .../tms570/make/custom/tms570ls3137_hdk_intram.cfg |   20 +
>  .../tms570/make/custom/tms570ls3137_hdk_sdram.cfg  |   19 +
>  c/src/lib/libbsp/arm/tms570/pom/tms570-pom.c       |  100 ++++
>  c/src/lib/libbsp/arm/tms570/startup/bspreset.c     |   37 ++
>  c/src/lib/libbsp/arm/tms570/startup/bspstart.c     |   46 ++
>  .../lib/libbsp/arm/tms570/startup/bspstarthooks.c  |   42 ++
>  .../arm/tms570/startup/linkcmds.tms570ls3137_hdk   |   27 +
>  .../startup/linkcmds.tms570ls3137_hdk_intram       |   28 +
>  .../tms570/startup/linkcmds.tms570ls3137_hdk_sdram |   27 +
>  27 files changed, 2303 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/tms570-rti.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/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/tms570-rti.c b/c/src/lib/libbsp/arm/tms570/clock/tms570-rti.c
> new file mode 100644
> index 0000000..3f8278c
> --- /dev/null
> +++ b/c/src/lib/libbsp/arm/tms570/clock/tms570-rti.c
Usually this file is called clock.c

> @@ -0,0 +1,205 @@
> +/**
> + * @file tms570-rti.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>
> +
> +void Clock_exit( void );
> +rtems_isr Clock_isr( rtems_vector_number vector );
> +void Install_clock( rtems_isr_entry );
> +
> +/*
> + *  Clock_driver_ticks is a monotonically increasing counter of the
> + *  number of clock ticks since the driver was initialized.
> + */
> +
> +volatile uint32_t         Clock_driver_ticks;
> +
> +/*
> + *  Clock_isrs is the number of clock ISRs until the next invocation of
> + *  the RTEMS clock tick routine.  The clock tick device driver
> + *  gets an interrupt once a millisecond and counts down until the
> + *  length of time between the user configured microseconds per tick
> + *  has passed.
> + */
> +
> +uint32_t         Clock_isrs;              /* ISRs until next tick */
> +
> +/*
> + * These are set by clock driver during its init
> + */
> +
> +rtems_device_major_number rtems_clock_major = ~0;
> +rtems_device_minor_number rtems_clock_minor;
> +
> +/*
> + *  The previous ISR on this clock tick interrupt vector.
> + */
> +
> +rtems_isr_entry  Old_ticker;
> +
> +/**
> + * @brief Clock isr handler
> + *
> + * bump the number of clock driver ticks since initialization
> + *
> + * determine if it is time to announce the passing of tick as configured
> + * to RTEMS through the rtems_clock_tick directive
> + *
> + * @param[in] vector interrupt vector
> + *
> + * @retval Void
> + */
> +rtems_isr Clock_isr(
> +  rtems_vector_number vector
> +)
> +{
> +   TMS570_RTI.RTIINTFLAG = 0x00000001;
> +   ++Clock_driver_ticks;
> +   /* TMS570_RTI.RTICOMP0 += 1000; */
Delete commented code that is not intended to be used in the future.

And as Joel said, use the clockdrv_shell.h file.

> 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..4815263
> --- /dev/null
> +++ b/c/src/lib/libbsp/arm/tms570/console/tms570-sci.c
> @@ -0,0 +1,546 @@
> +/**
> + * @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 <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 10
This define is only used to size the buffer in the interrupt handler.
If the size is determined by something in the hw, the define should
come in the header file with a note about the requirement. If the size
is chosen by you for the interrupt handler, you should just put the
value in the handler and make a comment/note about it. I don't think
the define here is that useful.

> +#define TMS570_CONTEXT_TABLE_SIZE 2
This define could be derived using RTEMS_ARRAY_SIZE(tms570_sci_context
driver_context_table)?

> +#define TMS570_USE_INTERRUPTS
This define should probably come from a BSPOPTS setting.
> +
> +/**
> + * @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;
> +#ifdef TMS570_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)return 0;
Always make control flow paths explicit by using braces and line breaks.

> +  if(ctx->regs->SCIRD != 0){
> +     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
> + *
If it is not tested, what is it intended for, or should it just be deleted?

> + * @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;
> +
> +  rtems_termios_interrupt_lock_acquire(tty, &lock_context);
> +
> +  switch (t->c_cflag & (PARENB|PARODD)) {
> +    case (PARENB|PARODD):
> +      /* Odd parity */
> +      ctx->regs->SCIGCR1 &= !(1<<3);
I would guess you want ~ not !.

> +      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);
Ditto.

> +  }
> +
> +  /* Baud rate */
> +  ctx->regs->BRS |= 0xFF00001A;
> +
> +  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 inicialization of the driver
Replace inicialization with initialization in multiple places.

> + *
> + * inicialization 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 inicialization
> + * @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
> +)
> +{
Should this function be doing anything? Now it just returns true.

> +  bool ok;
> +  /* TODO: test peripheral startup code below
> +    tms570_sci_context *ctx = rtems_termios_get_device_context(tty);
> +    ctx->regs->SCIGCR1 |= (1<<25) | (1<<24) | (1<<4);
> +    ctx->regs->SCIFORMAT |= 0x7;
> +    ctx->regs->SCIPIO0 |= (1<<1) | (1<<2);
> +    ctx->regs->SCISETINTLVL = 0;
> +    ok = tms570_sci_set_attributes(tty, rtems_termios_get_termios(tty));
> +  */
> +  ok = true;
> +  if (!ok) {
> +    return false;
> +  }
> +  return true;
> +}
> +
> +/**
> + * @brief inicialization 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 inicialization
> + * @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);
> +  if (sc != RTEMS_SUCCESSFUL)
> +    return false;
> +  tms570_sci_enable_interrupts(rtems_termios_get_device_context(tty));
> +  return true;
> +}
> +
> +/**
> + * @brief deinicializes sci peripheral
Replace deinicializes with closes.

> + *
> + * @param[in] tty context of the driver
> + * @param[in] args
> + * @retval false Error occured during inicialization
> + * @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 deinicializes 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 inicialization
> + * @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 */
> +  }
I think you do this checking of SCIFLR in multiple places. It probably
makes sense to write an inline function for it.

> 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..450ca68
> --- /dev/null
> +++ b/c/src/lib/libbsp/arm/tms570/include/bsp.h
> @@ -0,0 +1,101 @@
> +/**
> + * @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
> + */
> +void*bsp_idle_thread( uintptr_t ignored );
Add whitespace after *.

> +
> +#define BSP_CONSOLE_UART_BASE 0x4000C000U
> +
> +/**
> + * @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..810c5c8
> --- /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
> +
> +#define TMS570_POM_REGADDRMASK    ((1<<23)-1)
> +
> +typedef struct tms570_pom_region_t {
> +  uint32_t PROGSTART;
> +  uint32_t OVLSTART;
> +  uint32_t REGSIZE;
> +  uint32_t res0;
> +} tms570_pom_region_t;
> +
> +typedef struct tms570_pom_t {
> +  uint32_t GLBCTRL;     /* 000h Global Control Register */
> +  uint32_t REV;         /* 004h Revision ID */
> +  uint32_t CLKCTRL;     /* 008h Clock Gate Control Register */
> +  uint32_t FLG;         /* 00Ch Status Register */
> +  uint32_t res0[0x1f0/4];
The actual count might be nicer to see here. Also, use "reserved" like
you do elsewhere, and either always start with 0 or with 1.

> 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..5f72356
> --- /dev/null
> +++ b/c/src/lib/libbsp/arm/tms570/irq/irq.c
> @@ -0,0 +1,182 @@
> +/**
> + * @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 set
> + * priority of the interrupt on TMS570 in the 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 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);
Some macro here could improve readability.

-gedare


More information about the devel mailing list