void lpc24xx_micro_seconds_delay(unsigned us)
{
  unsigned start = lpc24xx_timer();
  unsigned end = start + us * (lpc24xx_cclk() / 1000000);
  unsigned now = 0;

  do {
    now = lpc24xx_timer();
  } while (now < end);
}
Пример #2
0
static rtems_status_code lpc24xx_ssp_init(rtems_libi2c_bus_t *bus)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;
  rtems_interrupt_level level;
  lpc24xx_ssp_bus_entry *e = (lpc24xx_ssp_bus_entry *) bus;
  volatile lpc24xx_ssp *regs = e->regs;
  unsigned pclk = lpc24xx_cclk();
  unsigned pre =
    ((pclk + LPC24XX_SSP_BAUD_RATE - 1) / LPC24XX_SSP_BAUD_RATE + 1) & ~1U;
  lpc24xx_module module = LPC24XX_MODULE_SSP_0;
  rtems_vector_number vector = UINT32_MAX;

  if (lpc24xx_ssp_dma_data.status == LPC24XX_SSP_DMA_NOT_INITIALIZED) {
    lpc24xx_ssp_dma_status status = LPC24XX_SSP_DMA_INVALID;

    /* Test and set DMA support status */
    rtems_interrupt_disable(level);
    status = lpc24xx_ssp_dma_data.status;
    if (status == LPC24XX_SSP_DMA_NOT_INITIALIZED) {
      lpc24xx_ssp_dma_data.status = LPC24XX_SSP_DMA_INITIALIZATION;
    }
    rtems_interrupt_enable(level);

    if (status == LPC24XX_SSP_DMA_NOT_INITIALIZED) {
      /* Install DMA interrupt handler */
      sc = rtems_interrupt_handler_install(
        LPC24XX_IRQ_DMA,
        "SSP DMA",
        RTEMS_INTERRUPT_SHARED,
        lpc24xx_ssp_dma_handler,
        &lpc24xx_ssp_dma_data
      );
      RTEMS_CHECK_SC(sc, "install DMA interrupt handler");

      /* Set DMA support status */
      lpc24xx_ssp_dma_data.status = LPC24XX_SSP_DMA_AVAILABLE;
    }
  }

  /* Disable module */
  regs->cr1 = 0;

  switch ((uintptr_t) regs) {
    case SSP0_BASE_ADDR:
      module = LPC24XX_MODULE_SSP_0;
      vector = LPC24XX_IRQ_SPI_SSP_0;
      break;
    case SSP1_BASE_ADDR:
      module = LPC24XX_MODULE_SSP_1;
      vector = LPC24XX_IRQ_SSP_1;
      break;
    default:
      return RTEMS_IO_ERROR;
  }

  /* Set clock select */
  sc = lpc24xx_module_enable(module, LPC24XX_MODULE_PCLK_DEFAULT);
  RTEMS_CHECK_SC(sc, "enable module clock");

  /* Set serial clock rate to save value */
  regs->cr0 = SET_SSP_CR0_SCR(0, 255);

  /* Set clock prescaler */
  if (pre > 254) {
    pre = 254;
  } else if (pre < 2) {
    pre = 2;
  }
  regs->cpsr = pre;

  /* Save clock value */
  e->clock = pclk / pre;

  /* Enable module and loop back mode */
  regs->cr1 = SSP_CR1_LBM | SSP_CR1_SSE;

  /* Install interrupt handler */
  sc = rtems_interrupt_handler_install(
    vector,
    "SSP",
    RTEMS_INTERRUPT_UNIQUE,
    lpc24xx_ssp_handler,
    e
  );
  RTEMS_CHECK_SC(sc, "install interrupt handler");

  /* Enable receiver overrun interrupts */
  e->regs->imsc = SSP_IMSC_RORIM;

  return RTEMS_SUCCESSFUL;
}