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; }
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); }
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; }
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; }
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); }
static void BSP_uart_off(const rtems_raw_irq_connect_data* used) { bsp_interrupt_vector_disable(used->idtIndex - BSP_IRQ_VECTOR_BASE); }
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; }
/** * @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; }
void Clock_driver_support_shutdown_hardware(void) { bsp_interrupt_vector_disable(MM_IRQ_TIMER0); MM_WRITE(MM_TIMER0_CONTROL, 0); }
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); } }