/** * @file ds1809_device.c * @brief DS1809 pulse-based control helper. */ #include "ds1809_device.h" #include "main.h" #define DS1809_POSITION_COUNT 64u #define DS1809_CPU_PULSE_WIDTH_MS 2u #define DS1809_CPU_INTER_PULSE_HIGH_MS 2u #define DS1809_CONTROL_PORT_READY_DELAY_MS 10u static void ds1809_drive_idle_high(void) { HAL_GPIO_WritePin(DS1809_UC_GPIO_Port, DS1809_UC_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(DS1809_DC_GPIO_Port, DS1809_DC_Pin, GPIO_PIN_SET); } static void ds1809_pulse_direction(uint8_t increment, uint8_t decrement, uint16_t count, uint16_t low_time_ms, uint16_t high_time_ms) { uint16_t pulse_index; if ((count == 0u) || ((increment == 0u) && (decrement == 0u))) { ds1809_drive_idle_high(); return; } ds1809_drive_idle_high(); for (pulse_index = 0u; pulse_index < count; ++pulse_index) { if (increment != 0u) { HAL_GPIO_WritePin(DS1809_UC_GPIO_Port, DS1809_UC_Pin, GPIO_PIN_RESET); } if (decrement != 0u) { HAL_GPIO_WritePin(DS1809_DC_GPIO_Port, DS1809_DC_Pin, GPIO_PIN_RESET); } HAL_Delay(low_time_ms); ds1809_drive_idle_high(); HAL_Delay(high_time_ms); } } void ds1809_pulse(uint8_t increment, uint8_t decrement, uint16_t count, uint16_t pulse_ms) { if (pulse_ms < DS1809_CPU_PULSE_WIDTH_MS) { pulse_ms = DS1809_CPU_PULSE_WIDTH_MS; } ds1809_pulse_direction(increment, decrement, count, pulse_ms, pulse_ms); } void ds1809_apply_position_from_min(uint8_t position_from_min) { /* * DS1809 CPU-driven timing requirements from the local datasheet: * - a pulse must stay low for longer than 1 ms to count as a step; * - repetitive pulses need at least 1 ms of high time between steps; * - the control inputs are locked out for at least 10 ms after power-up. * * Use 2 ms low/high timing for margin, always drive to the RL end first, * then walk back up to the requested absolute position. */ if (position_from_min >= DS1809_POSITION_COUNT) { position_from_min = (uint8_t)(DS1809_POSITION_COUNT - 1u); } HAL_Delay(DS1809_CONTROL_PORT_READY_DELAY_MS); ds1809_pulse_direction(0u, 1u, DS1809_POSITION_COUNT, DS1809_CPU_PULSE_WIDTH_MS, DS1809_CPU_INTER_PULSE_HIGH_MS); ds1809_pulse_direction(1u, 0u, position_from_min, DS1809_CPU_PULSE_WIDTH_MS, DS1809_CPU_INTER_PULSE_HIGH_MS); }