Пример #1
0
rtems_status_code mpc55xx_edma_obtain_channel(
  edma_channel_context *ctx,
  unsigned irq_priority
)
{
  rtems_status_code sc = mpc55xx_edma_obtain_channel_by_tcd(ctx->edma_tcd);
  if (sc == RTEMS_SUCCESSFUL) {
    unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);

    sc = mpc55xx_interrupt_handler_install(
      MPC55XX_IRQ_EDMA(channel_index),
      "eDMA Channel",
      RTEMS_INTERRUPT_SHARED,
      irq_priority,
      edma_interrupt_handler,
      ctx
    );
    if (sc == RTEMS_SUCCESSFUL) {
      rtems_chain_prepend(&edma_channel_chain, &ctx->node);
      mpc55xx_edma_enable_error_interrupts(ctx->edma_tcd);
    } else {
      mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
      sc = RTEMS_IO_ERROR;
    }
  }

  return sc;
}
Пример #2
0
void mpc55xx_edma_init(void)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;
  unsigned channel_remaining = EDMA_CHANNEL_COUNT;
  unsigned module = 0;
  unsigned group = 0;

  for (module = 0; module < EDMA_MODULE_COUNT; ++module) {
    volatile struct EDMA_tag *edma = edma_get_regs_by_module(module);
    unsigned channel_count = channel_remaining < EDMA_CHANNELS_PER_MODULE ?
      channel_remaining : EDMA_CHANNELS_PER_MODULE;
    unsigned channel = 0;

    channel_remaining -= channel_count;

    /* Disable requests */
    edma->CERQR.B.CERQ = 0x40;

    /* Arbitration mode: group round robin, channel fixed */
    edma->CR.B.ERGA = 1;
    edma->CR.B.ERCA = 0;
    for (channel = 0; channel < channel_count; ++channel) {
      volatile struct tcd_t *tcd = &edma->TCD [channel];
      edma->CPR [channel].R = 0x80U | (channel & 0xfU);

      /* Initialize TCD, stop channel first */
      tcd->BMF.R = 0;
      tcd->SADDR = 0;
      tcd->SDF.R = 0;
      tcd->NBYTES = 0;
      tcd->SLAST = 0;
      tcd->DADDR = 0;
      tcd->CDF.R = 0;
      tcd->DLAST_SGA = 0;
    }

    /* Clear interrupt requests */
    edma->CIRQR.B.CINT = 0x40;
    edma->CER.B.CERR = 0x40;
  }

  for (group = 0; group < EDMA_GROUP_COUNT; ++group) {
    sc = mpc55xx_interrupt_handler_install(
      MPC55XX_IRQ_EDMA_ERROR(group),
      "eDMA Error",
      RTEMS_INTERRUPT_UNIQUE,
      MPC55XX_INTC_DEFAULT_PRIORITY,
      edma_interrupt_error_handler,
      NULL
    );
    if (sc != RTEMS_SUCCESSFUL) {
      bsp_fatal(MPC55XX_FATAL_EDMA_IRQ_INSTALL);
    }
  }
}
Пример #3
0
static void mpc55xx_clock_handler_install( rtems_isr_entry isr, 
					   rtems_isr_entry *old_isr)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;

  sc = mpc55xx_interrupt_handler_install(
    MPC55XX_IRQ_EMIOS_GET_REQUEST( MPC55XX_CLOCK_EMIOS_CHANNEL),
    "clock",
    RTEMS_INTERRUPT_UNIQUE,
    MPC55XX_INTC_MIN_PRIORITY,
    (rtems_interrupt_handler) isr,
    NULL
  );
 *old_isr = NULL;
  RTEMS_CHECK_SC_VOID( sc, "install clock interrupt handler");
}
Пример #4
0
static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;

  sc = mpc55xx_interrupt_handler_install(
    MPC55XX_IRQ_EMIOS(MPC55XX_CLOCK_EMIOS_CHANNEL),
    "clock",
    RTEMS_INTERRUPT_UNIQUE,
    MPC55XX_INTC_MIN_PRIORITY,
    (rtems_interrupt_handler) isr,
    NULL
  );
  if (sc != RTEMS_SUCCESSFUL) {
    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_IRQ_INSTALL);
  }
}
Пример #5
0
static int mpc55xx_esci_set_attributes(int minor, const struct termios *t)
{
  mpc55xx_esci_context *self = console_generic_get_context(minor);
  volatile struct ESCI_tag *regs = self->regs;
  union ESCI_CR1_tag cr1 = { .R = regs->CR1.R };
  union ESCI_CR2_tag cr2 = MPC55XX_ZERO_FLAGS;
  rtems_termios_baud_t br = rtems_termios_baud_to_number(t->c_cflag);

  /* Enable module */
  cr2.B.MDIS = 0;

  /* Interrupts */
  cr1.B.TCIE = 0;
  cr1.B.ILIE = 0;
  cr2.B.IEBERR = 0;
  cr2.B.ORIE = 0;
  cr2.B.NFIE = 0;
  cr2.B.FEIE = 0;
  cr2.B.PFIE = 0;

  /* Disable receiver wake-up standby */
  cr1.B.RWU = 0;

  /* Disable DMA channels */
  cr2.B.RXDMA = 0;
  cr2.B.TXDMA = 0;

  /* Idle line type */
  cr1.B.ILT = 0;

  /* Disable loops */
  cr1.B.LOOPS = 0;

  /* Enable or disable receiver */
  cr1.B.RE = (t->c_cflag & CREAD) ? 1 : 0;

  /* Enable transmitter */
  cr1.B.TE = 1;

  /* Baud rate */
  if (br > 0) {
    br = bsp_clock_speed / (16 * br);
    br = (br > 8191) ? 8191 : br;
  } else {
    br = 0;
  }
  cr1.B.SBR = br;

  /* Number of data bits */
  if ((t->c_cflag & CSIZE) != CS8) {
    return -1;
  }
  cr1.B.M = 0;

  /* Parity */
  cr1.B.PE = (t->c_cflag & PARENB) ? 1 : 0;
  cr1.B.PT = (t->c_cflag & PARODD) ? 1 : 0;

  /* Stop bits */
  if (t->c_cflag & CSTOPB ) {
    /* Two stop bits */
    return -1;
  }

  /* Disable LIN */
  regs->LCR.R = 0;

  /* Set control registers */
  regs->CR2.R = cr2.R;
  regs->CR1.R = cr1.R;

  return 0;
}

static int mpc55xx_esci_first_open(int major, int minor, void *arg)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;
  int rv = 0;
  mpc55xx_esci_context *self = console_generic_get_context(minor);
  struct rtems_termios_tty *tty = console_generic_get_tty_at_open(arg);

  self->tty = tty;

  rv = rtems_termios_set_initial_baud(tty, 115200);
  if (rv != 0) {
    rtems_fatal_error_occurred(0xdeadbeef);
  }

  rv = mpc55xx_esci_set_attributes(minor, &tty->termios);
  if (rv != 0) {
    rtems_fatal_error_occurred(0xdeadbeef);
  }

  sc = mpc55xx_interrupt_handler_install(
    self->irq,
    "eSCI",
    RTEMS_INTERRUPT_UNIQUE,
    MPC55XX_INTC_DEFAULT_PRIORITY,
    mpc55xx_esci_interrupt_handler,
    self
  );
  if (sc != RTEMS_SUCCESSFUL) {
    rtems_fatal_error_occurred(0xdeadbeef);
  }

  mpc55xx_esci_interrupts_clear_and_enable(self);
  self->transmit_in_progress = false;

  return 0;
}