Esempio n. 1
0
File: i2c.c Progetto: chch1028/rtems
rtems_status_code stm32f4_i2c_init(stm32f4_i2c_bus_entry *e)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;
  volatile stm32f4_i2c *regs = e->regs;
  stm32f4_rcc_index rcc_index = i2c_get_rcc_index(e);
  uint32_t pclk = i2c_get_pclk(e);
  uint32_t cr1 = 0;
  uint32_t cr2 = 0;

  assert(pclk >= 2000000);

  /* Create mutex */
  sc = rtems_semaphore_create (
    rtems_build_name ('I', '2', 'C', '1' + e->index),
    0,
    RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
    0,
    &e->mutex
  );
  RTEMS_CHECK_SC(sc, "create mutex");

  /* Install interrupt handler and disable this vector */
  sc = rtems_interrupt_handler_install(
    e->vector,
    "I2C",
    RTEMS_INTERRUPT_UNIQUE,
    stm32f4_i2c_handler,
    e
  );
  RTEMS_CHECK_SC(sc, "install interrupt handler");
  bsp_interrupt_vector_disable(e->vector);

  /* Enable module clock */
  stm32f4_rcc_set_clock(rcc_index, true);

  /* Setup initial bit rate */
  sc = stm32f4_i2c_set_bitrate(e, STM32F4_I2C_INITIAL_BITRATE);
  RTEMS_CHECK_SC(sc, "set bitrate");

  /* Set config registers */
  cr2 = regs->cr2;
  cr2 = STM32F4_I2C_CR2_FREQ_SET(cr2, pclk / 1000000);
  cr2 |= STM32F4_I2C_CR2_ITEVTEN;
  cr2 |= STM32F4_I2C_CR2_ITBUFEN;
  regs->cr2 = cr2;

  cr1 = regs->cr1;
  cr1 |= STM32F4_I2C_CR1_PE;
  regs->cr1 = cr1;

  return RTEMS_SUCCESSFUL;
}
Esempio n. 2
0
static void bsp_interrupt_server_trigger(void *arg)
{
  bsp_interrupt_server_entry *e = arg;

  bsp_interrupt_vector_disable(e->vector);

  if (e->node.next == NULL) {
    rtems_chain_append(&bsp_interrupt_server_chain, &e->node);
  } else {
    ++bsp_interrupt_server_errors;
  }

  rtems_event_send(bsp_interrupt_server_id, BSP_INTERRUPT_EVENT);
}
Esempio n. 3
0
static rtems_status_code submit_record(struct snd_buffer *buf)
{
  bsp_interrupt_vector_disable(MM_IRQ_AC97DMAW);
  if (record_level == RECORD_Q_SIZE) {
    bsp_interrupt_vector_enable(MM_IRQ_AC97DMAW);
    return RTEMS_UNSATISFIED;
  }
  record_q[record_produce] = buf;
  record_produce = (record_produce + 1) & RECORD_Q_MASK;
  record_level++;

  if (record_level == 1)
    record_start(buf);

  bsp_interrupt_vector_enable(MM_IRQ_AC97DMAW);
  return RTEMS_SUCCESSFUL;
}
Esempio n. 4
0
static rtems_status_code submit_play(struct snd_buffer *buf)
{
  bsp_interrupt_vector_disable(MM_IRQ_AC97DMAR);
  if (play_level == PLAY_Q_SIZE) {
    bsp_interrupt_vector_enable(MM_IRQ_AC97DMAR);
    return RTEMS_UNSATISFIED;
  }
  play_q[play_produce] = buf;
  play_produce = (play_produce + 1) & PLAY_Q_MASK;
  play_level++;

  if (play_level == 1)
    play_start(buf);

  bsp_interrupt_vector_enable(MM_IRQ_AC97DMAR);
  return RTEMS_SUCCESSFUL;
}
Esempio n. 5
0
static void bsp_interrupt_server_trigger(void *arg)
{
  rtems_interrupt_lock_context lock_context;
  bsp_interrupt_server_entry *e = arg;

  bsp_interrupt_vector_disable(e->vector);

  rtems_interrupt_lock_acquire(&bsp_interrupt_server_lock, &lock_context);

  if (rtems_chain_is_node_off_chain(&e->node)) {
    rtems_chain_append_unprotected(&bsp_interrupt_server_chain, &e->node);
  } else {
    ++bsp_interrupt_server_errors;
  }

  rtems_interrupt_lock_release(&bsp_interrupt_server_lock, &lock_context);

  rtems_event_system_send(bsp_interrupt_server_id, RTEMS_EVENT_SYSTEM_SERVER);
}
Esempio n. 6
0
static void BSP_uart_off(const rtems_raw_irq_connect_data* used)
{
  bsp_interrupt_vector_disable(used->idtIndex - BSP_IRQ_VECTOR_BASE);
}
Esempio n. 7
0
File: video.c Progetto: RTEMS/rtems
rtems_device_driver video_control(
  rtems_device_major_number major,
  rtems_device_minor_number minor,
  void *arg
)
{
  rtems_libio_ioctl_args_t *args = arg;
  unsigned int *a = (unsigned int *)args->buffer;
  rtems_status_code sc;

  switch (args->command) {
    case VIDEO_BUFFER_LOCK:
      if (last_buffer == -1) {
        *a = 0;
      } else {
        bsp_interrupt_vector_disable(MM_IRQ_VIDEOIN);
        if(*a) invalidate_caches();
        *a = (unsigned int)buffers[last_buffer];
        buffers_locked[last_buffer] = true;
        bsp_interrupt_vector_enable(MM_IRQ_VIDEOIN);
      }
      sc = RTEMS_SUCCESSFUL;
      break;
    case VIDEO_BUFFER_UNLOCK: {
      int i;
      for(i=0;i<N_BUFFERS;i++) {
        if ((unsigned int)buffers[i] == (unsigned int)a) {
          buffers_locked[i] = false;
          break;
        }
      }
      sc = RTEMS_SUCCESSFUL;
      break;
    }
    
    case VIDEO_SET_BRIGHTNESS:
      write_reg(0x0a, (unsigned int)a);
      sc = RTEMS_SUCCESSFUL;
      break;
    case VIDEO_GET_BRIGHTNESS:
      *a = read_reg(0x0a);
      sc = RTEMS_SUCCESSFUL;
      break;
    case VIDEO_SET_CONTRAST:
      write_reg(0x08, (unsigned int)a);
      sc = RTEMS_SUCCESSFUL;
      break;
    case VIDEO_GET_CONTRAST:
      *a = read_reg(0x08);
      sc = RTEMS_SUCCESSFUL;
      break;
    case VIDEO_SET_HUE:
      write_reg(0x0b, (unsigned int)a);
      sc = RTEMS_SUCCESSFUL;
      break;
    case VIDEO_GET_HUE:
      *a = read_reg(0x0b);
      sc = RTEMS_SUCCESSFUL;
      break;
    
    case VIDEO_GET_SIGNAL:
      *a = read_reg(0x10);
      sc = RTEMS_SUCCESSFUL;
      break;
    
    case VIDEO_SET_REGISTER:
      write_reg(((unsigned int)a & 0xffff0000) >> 16,
        (unsigned int)a & 0x0000ffff);
      sc = RTEMS_SUCCESSFUL;
      break;
    case VIDEO_GET_REGISTER:
      *a = read_reg(*a);
      sc = RTEMS_SUCCESSFUL;
      break;
    
    case VIDEO_SET_FORMAT:
      set_format((int)a);
      sc = RTEMS_SUCCESSFUL;
      break;
    
    default:
      sc = RTEMS_UNSATISFIED;
      break;
  }

  if (sc == RTEMS_SUCCESSFUL)
    args->ioctl_return = 0;
  else
    args->ioctl_return = -1;

  return sc;
}
Esempio n. 8
0
/**
 * @brief Removes an interrupt handler.
 *
 * @ingroup bsp_interrupt
 *
 * @return In addition to the standard status codes this function returns
 * RTEMS_INTERNAL_ERROR if the BSP interrupt support is not initialized.
 *
 * @see rtems_interrupt_handler_remove().
 */
static rtems_status_code bsp_interrupt_handler_remove(
  rtems_vector_number vector,
  rtems_interrupt_handler handler,
  void *arg
)
{
  rtems_status_code sc = RTEMS_SUCCESSFUL;
  rtems_interrupt_level level;
  rtems_vector_number index = 0;
  bsp_interrupt_handler_entry *head = NULL;
  bsp_interrupt_handler_entry *current = NULL;
  bsp_interrupt_handler_entry *previous = NULL;
  bsp_interrupt_handler_entry *match = NULL;

  /* Check parameters and system state */
  if (!bsp_interrupt_is_initialized()) {
    return RTEMS_INTERNAL_ERROR;
  } else if (!bsp_interrupt_is_valid_vector(vector)) {
    return RTEMS_INVALID_ID;
  } else if (handler == NULL) {
    return RTEMS_INVALID_ADDRESS;
  } else if (rtems_interrupt_is_in_progress()) {
    return RTEMS_CALLED_FROM_ISR;
  }

  /* Lock */
  sc = bsp_interrupt_lock();
  if (sc != RTEMS_SUCCESSFUL) {
    return sc;
  }

  /* Get handler table index */
  index = bsp_interrupt_handler_index(vector);

  /* Get head entry of the handler list for current vector */
  head = &bsp_interrupt_handler_table [index];

  /* Search for a matching entry */
  current = head;
  do {
    if (current->handler == handler && current->arg == arg) {
      match = current;
      break;
    }
    previous = current;
    current = current->next;
  } while (current != NULL);

  /* Remove the matching entry */
  if (match != NULL) {
    if (match->next != NULL) {
      /*
       * The match has a successor.  A successor is always
       * allocated.  So replace the match with its successor
       * and free the successor entry.
       */
      current = match->next;

      rtems_interrupt_disable(level);
      *match = *current;
      rtems_interrupt_enable(level);

      bsp_interrupt_free_handler_entry(current);
    } else if (match == head) {
      /*
       * The match is the list head and has no successor.
       * The list head is stored in a static table so clear
       * this entry.  Since now the list is empty disable the
       * vector.
       */

      /* Disable the vector */
      sc = bsp_interrupt_vector_disable(vector);

      /* Clear entry */
      rtems_interrupt_disable(level);
      bsp_interrupt_clear_handler_entry(head);
      #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
        bsp_interrupt_handler_index_table [vector] = 0;
      #endif
      rtems_interrupt_enable(level);

      /* Allow shared handlers */
      bsp_interrupt_set_handler_unique(index, false);

      /* Check status code */
      if (sc != RTEMS_SUCCESSFUL) {
        bsp_interrupt_unlock();
        return sc;
      }
    } else {
      /*
       * The match is the list tail and has a predecessor.
       * So terminate the predecessor and free the match.
       */
      rtems_interrupt_disable(level);
      previous->next = NULL;
      rtems_interrupt_enable(level);

      bsp_interrupt_free_handler_entry(match);
    }
  } else {
    /* No matching entry found */
    bsp_interrupt_unlock();
    return RTEMS_UNSATISFIED;
  }

  /* Unlock */
  sc = bsp_interrupt_unlock();
  if (sc != RTEMS_SUCCESSFUL) {
    return sc;
  }

  return RTEMS_SUCCESSFUL;
}
Esempio n. 9
0
File: ckinit.c Progetto: Fyleo/rtems
void Clock_driver_support_shutdown_hardware(void)
{
  bsp_interrupt_vector_disable(MM_IRQ_TIMER0);
  MM_WRITE(MM_TIMER0_CONTROL, 0);
}
Esempio n. 10
0
File: i2c.c Progetto: chch1028/rtems
static void stm32f4_i2c_handler(void *arg)
{
  /* This handler implements the suggested read method from stm32f103xx
   * reference manual if the handler is not the one with the highest priority */
  stm32f4_i2c_bus_entry *e = arg;
  volatile stm32f4_i2c *regs = e->regs;
  uint32_t sr1 = regs->sr1;
  uint8_t *data = e->data;
  uint8_t *last = e->last;
  bool read = e->read;
  bool wake_task = false;
  uint32_t cr1;

  if(sr1 & STM32F4_I2C_SR1_SB) {
    /* Start condition sent. */
    regs->dr = e->addr_with_rw;
  }

  if(read) {
    size_t len = e->len;

    if(len == 1) {
      /* special case for one single byte */
      if(sr1 & STM32F4_I2C_SR1_ADDR) {
        cr1 = regs->cr1;
        cr1 &= ~STM32F4_I2C_CR1_ACK;
        regs->cr1 = cr1;

        /* Read sr2 to clear flag */
        regs->sr2;

        cr1 = regs->cr1;
        cr1 |= STM32F4_I2C_CR1_STOP;
        regs->cr1 = cr1;
      } else if(sr1 & STM32F4_I2C_SR1_RxNE) {
        *data = regs->dr;
        wake_task = true;
      }
    } else if (len == 2) {
      /* special case for two bytes */
      if(sr1 & STM32F4_I2C_SR1_ADDR) {
        /* Read sr2 to clear flag */
        regs->sr2;

        cr1 = regs->cr1;
        cr1 &= ~STM32F4_I2C_CR1_ACK;
        regs->cr1 = cr1;
      } else if(sr1 & STM32F4_I2C_SR1_BTF) {
        cr1 = regs->cr1;
        cr1 |= STM32F4_I2C_CR1_STOP;
        regs->cr1 = cr1;

        *data = regs->dr;
        ++data;
        *data = regs->dr;
        wake_task = true;
      }
    } else {
      /* more than two bytes */
      if(sr1 & STM32F4_I2C_SR1_ADDR) {
        /* Read sr2 to clear flag */
        regs->sr2;
      } else if(sr1 & STM32F4_I2C_SR1_BTF && data == last - 2) {
        cr1 = regs->cr1;
        cr1 &= ~STM32F4_I2C_CR1_ACK;
        regs->cr1 = cr1;

        *data = regs->dr;
        ++data;

        cr1 = regs->cr1;
        cr1 |= STM32F4_I2C_CR1_STOP;
        regs->cr1 = cr1;

        *data = regs->dr;
        ++data;
      } else if((sr1 & STM32F4_I2C_SR1_RxNE) && (data != last - 2)) {
        *data = regs->dr;

        if(data == last) {
          wake_task = true;
        } else {
          ++data;
        }
      }
    }
  } else /* write */ {
    if(sr1 & STM32F4_I2C_SR1_ADDR) {
      /* Address sent */
      regs->sr2;
    }

    if((sr1 & (STM32F4_I2C_SR1_ADDR | STM32F4_I2C_SR1_TxE)) && (data <= last)) {
      regs->dr = *data;
      ++data;
    } else if(sr1 & STM32F4_I2C_SR1_BTF) {
      uint32_t cr1 = regs->cr1;
      cr1 |= STM32F4_I2C_CR1_STOP;
      regs->cr1 = cr1;
      wake_task = true;
    }
  }

  e->data = data;

  if(wake_task) {
    bsp_interrupt_vector_disable(e->vector);
    rtems_event_transient_send(e->task_id);
  }
}