void startInputDriver(const char *msg, /*nullable*/digital_input_s *hw, bool isActiveHigh) { if (hw == NULL) { // we can get NULL driver if user somehow has invalid pin in his configuration warning(CUSTOM_ERR_INVALID_INPUT_ICU_PIN, "s_not input pin"); return; } hw->isActiveHigh = isActiveHigh; if (hw->isActiveHigh) { wave_icucfg.mode = ICU_INPUT_ACTIVE_HIGH; } else { wave_icucfg.mode = ICU_INPUT_ACTIVE_LOW; } ICUDriver *driver = hw->driver; if (driver != NULL) { if (hw->started) { icuDisableNotificationsI(driver); icuStopCapture(driver); icuStop(driver); } wave_icucfg.channel = getInputCaptureChannel(hw->brainPin); efiIcuStart(msg, driver, &wave_icucfg); efiAssertVoid(CUSTOM_ERR_6672, driver != NULL, "di: driver is NULL"); efiAssertVoid(CUSTOM_ERR_6673, driver->state == ICU_READY, "di: driver not ready"); icuStartCapture(driver); // this would change state from READY to WAITING icuEnableNotifications(driver); } hw->started = true; }
/** * turns pin off and returns digital_input_s back into registeredIcus pool */ void removeWaveAnalyzerDriver(const char *msg, brain_pin_e brainPin) { if (brainPin == GPIO_UNASSIGNED) { return; } brain_pin_markUnused(brainPin); ICUDriver *driver = getInputCaptureDriver(msg, brainPin); if (driver == NULL) { return; } int regSize = registeredIcus.size; for (int i = 0; i < regSize; i++) { if (registeredIcus.elements[i].driver == driver) { // removing from driver from the list of used drivers memcpy(®isteredIcus.elements[i], ®isteredIcus.elements[regSize - 1], sizeof(digital_input_s)); registeredIcus.size--; icuDisableNotificationsI(driver); icuStopCapture(driver); icuStop(driver); return; } } }
/* * Application entry point. */ int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * Initializes the PWM driver 4 and ICU driver 3. * GPIOD12 is the PWM output channel 0. * GPIOC6 is the ICU input ICU_CHANNEL_1. * The two pins have to be externally connected together. */ pwmStart(&PWMD4, &pwmcfg); pwmEnablePeriodicNotification(&PWMD4); palSetPadMode(GPIOD, 12, PAL_MODE_ALTERNATE(2)); icuStart(&ICUD3, &icucfg); palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2)); icuStartCapture(&ICUD3); icuEnableNotifications(&ICUD3); chThdSleepMilliseconds(2000); /* * Starts the PWM channel 0 using 75% duty cycle. */ pwmEnableChannel(&PWMD4, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD4, 7500)); pwmEnableChannelNotification(&PWMD4, 0); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 50% duty cycle. */ pwmEnableChannel(&PWMD4, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD4, 5000)); chThdSleepMilliseconds(5000); /* * Changes the PWM channel 0 to 25% duty cycle. */ pwmEnableChannel(&PWMD4, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD4, 2500)); chThdSleepMilliseconds(5000); /* * Changes PWM period to half second the duty cycle becomes 50% * implicitly. */ pwmChangePeriod(&PWMD4, 5000); chThdSleepMilliseconds(5000); /* * Disables channel 0 and stops the drivers. */ pwmDisableChannel(&PWMD4, 0); pwmStop(&PWMD4); icuStopCapture(&ICUD3); icuStop(&ICUD3); palClearPad(GPIOE, GPIOE_LED4_BLUE); palClearPad(GPIOE, GPIOE_LED9_BLUE); /* * Normal main() thread activity, in this demo it does nothing. */ while (true) { chThdSleepMilliseconds(500); } return 0; }