void capture_task (void *data) { int ret; // We need to disable interrupts during capture so we do not // interfere with taking a photo extint_disable (extint1); while ( tcm8230_frame_ready_p ()) continue; while (! tcm8230_frame_ready_p ()) continue; ret = tcm8230_capture (image, sizeof(image), 200); if (ret < 0) // Capturing failed *comms_data[CD_PHOTO_READY-ARRAY_OFFSET] = 0; else { *comms_data[CD_PHOTO_READY-ARRAY_OFFSET] = 1; kernelTaskBlocked (CAPTURE_TASK); // Reblock capture task kernelTaskReady (PHOTO_READY_FLASH_TASK); // Indicate a photo is available } extint_enable (extint1); }
// Interrupt handler void Handle_EXTI_Irq(uint32_t line) { if (__HAL_GPIO_EXTI_GET_FLAG(1 << line)) { __HAL_GPIO_EXTI_CLEAR_FLAG(1 << line); if (line < EXTI_NUM_VECTORS) { mp_obj_t *cb = &MP_STATE_PORT(pyb_extint_callback)[line]; if (*cb != mp_const_none) { // When executing code within a handler we must lock the GC to prevent // any memory allocations. We must also catch any exceptions. gc_lock(); nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_call_function_1(*cb, MP_OBJ_NEW_SMALL_INT(line)); nlr_pop(); } else { // Uncaught exception; disable the callback so it doesn't run again. *cb = mp_const_none; extint_disable(line); printf("Uncaught exception in ExtInt interrupt handler line %lu\n", line); mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); } gc_unlock(); } } } }
static void handler (void) { // Disable interrupt temp extint_disable (extint1); irq_clear (AT91C_ID_IRQ1); uint8_t addr; uint8_t buffer[2]; i2c_ret_t ret; DELAY_US (4); //pio_output_toggle (LED1_PIO); ret = i2c_slave_read (i2c_slave1, buffer, sizeof (buffer), 10000); addr = buffer[0] - ARRAY_OFFSET; if (addr >= sizeof (comms_data)) addr = 0; if (ret == 1) { // Have not received photo line command. if (buffer[0] != CD_PHOTO_LINE) ret = i2c_slave_write (i2c_slave1, comms_data[addr], 130, 1000); // Return data requested. else { // check if photo ready. if (comms_data[CD_PHOTO_READY-ARRAY_OFFSET]) { ret = i2c_slave_write (i2c_slave1, comms_data[CD_PHOTO_NEXT_LINE-ARRAY_OFFSET], 130, 1000); if (ret > 0) { ret++; *comms_data[CD_FAULT - ARRAY_OFFSET] = ret; comms_data[CD_PHOTO_NEXT_LINE-ARRAY_OFFSET] += ret; if ((comms_data[CD_PHOTO_NEXT_LINE-ARRAY_OFFSET] - image) == image_size) { // We have sent the entire picture comms_data[CD_PHOTO_NEXT_LINE-ARRAY_OFFSET] = image; comms_data[CD_PHOTO_READY-ARRAY_OFFSET] = 0; } } } } } if (ret == 2) { if (buffer[0] == COMMS_COMMAND) next_command = buffer[1]; } extint_enable (extint1); }
/// \method disable() /// Disable the interrupt associated with the ExtInt object. /// This could be useful for debouncing. STATIC mp_obj_t extint_obj_disable(mp_obj_t self_in) { extint_obj_t *self = self_in; extint_disable(self->line); return mp_const_none; }
// Set override_callback_obj to true if you want to unconditionally set the // callback function. uint extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t callback_obj, bool override_callback_obj) { const pin_obj_t *pin = NULL; uint v_line; if (MP_OBJ_IS_INT(pin_obj)) { // If an integer is passed in, then use it to identify lines 16 thru 22 // We expect lines 0 thru 15 to be passed in as a pin, so that we can // get both the port number and line number. v_line = mp_obj_get_int(pin_obj); if (v_line < 16) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "ExtInt vector %d < 16, use a Pin object", v_line)); } if (v_line >= EXTI_NUM_VECTORS) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "ExtInt vector %d >= max of %d", v_line, EXTI_NUM_VECTORS)); } } else { pin = pin_find(pin_obj); v_line = pin->pin; } if (mode != GPIO_MODE_IT_RISING && mode != GPIO_MODE_IT_FALLING && mode != GPIO_MODE_IT_RISING_FALLING && mode != GPIO_MODE_EVT_RISING && mode != GPIO_MODE_EVT_FALLING && mode != GPIO_MODE_EVT_RISING_FALLING) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid ExtInt Mode: %d", mode)); } if (pull != GPIO_NOPULL && pull != GPIO_PULLUP && pull != GPIO_PULLDOWN) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid ExtInt Pull: %d", pull)); } mp_obj_t *cb = &MP_STATE_PORT(pyb_extint_callback)[v_line]; if (!override_callback_obj && *cb != mp_const_none && callback_obj != mp_const_none) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "ExtInt vector %d is already in use", v_line)); } // We need to update callback atomically, so we disable the line // before we update anything. extint_disable(v_line); *cb = callback_obj; pyb_extint_mode[v_line] = (mode & 0x00010000) ? // GPIO_MODE_IT == 0x00010000 EXTI_Mode_Interrupt : EXTI_Mode_Event; if (*cb != mp_const_none) { mp_hal_gpio_clock_enable(pin->gpio); GPIO_InitTypeDef exti; exti.Pin = pin->pin_mask; exti.Mode = mode; exti.Pull = pull; exti.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(pin->gpio, &exti); // Calling HAL_GPIO_Init does an implicit extint_enable /* Enable and set NVIC Interrupt to the lowest priority */ HAL_NVIC_SetPriority(nvic_irq_channel[v_line], IRQ_PRI_EXTINT, IRQ_SUBPRI_EXTINT); HAL_NVIC_EnableIRQ(nvic_irq_channel[v_line]); } return v_line; }
void SpiPauseSpi(void) { extint_disable(PIN_IRQ->pin); }
void SpiPauseSpi(void) { DEBUG_printf("SpiPauseSpi\n"); extint_disable(PIN_IRQ->pin); }