diff options
Diffstat (limited to 'drivers/haptic')
| -rw-r--r-- | drivers/haptic/solenoid.c | 155 | ||||
| -rw-r--r-- | drivers/haptic/solenoid.h | 26 | 
2 files changed, 126 insertions, 55 deletions
| diff --git a/drivers/haptic/solenoid.c b/drivers/haptic/solenoid.c index 14d868bffe..637a77da3d 100644 --- a/drivers/haptic/solenoid.c +++ b/drivers/haptic/solenoid.c @@ -20,11 +20,22 @@  #include "haptic.h"  #include "gpio.h"  #include "usb_device_state.h" - -bool     solenoid_on      = false; -bool     solenoid_buzzing = false; -uint16_t solenoid_start   = 0; -uint8_t  solenoid_dwell   = SOLENOID_DEFAULT_DWELL; +#include <stdlib.h> + +uint8_t      solenoid_dwell  = SOLENOID_DEFAULT_DWELL; +static pin_t solenoid_pads[] = SOLENOID_PINS; +#define NUMBER_OF_SOLENOIDS (sizeof(solenoid_pads) / sizeof(pin_t)) +bool     solenoid_on[NUMBER_OF_SOLENOIDS]      = {false}; +bool     solenoid_buzzing[NUMBER_OF_SOLENOIDS] = {false}; +uint16_t solenoid_start[NUMBER_OF_SOLENOIDS]   = {0}; +#ifdef SOLENOID_PIN_ACTIVE_LOW +#    define low true +#    define high false +#else +#    define low false +#    define high true +#endif +static bool solenoid_active_state[NUMBER_OF_SOLENOIDS];  extern haptic_config_t haptic_config; @@ -36,7 +47,7 @@ void solenoid_buzz_off(void) {      haptic_set_buzz(0);  } -void solenoid_set_buzz(int buzz) { +void solenoid_set_buzz(uint8_t buzz) {      haptic_set_buzz(buzz);  } @@ -44,59 +55,121 @@ void solenoid_set_dwell(uint8_t dwell) {      solenoid_dwell = dwell;  } -void solenoid_stop(void) { -    SOLENOID_PIN_WRITE_INACTIVE(); -    solenoid_on      = false; -    solenoid_buzzing = false; +/** + * @brief Stops a specific solenoid + * + * @param index select which solenoid to check/stop + */ +void solenoid_stop(uint8_t index) { +    writePin(solenoid_pads[index], !solenoid_active_state[index]); +    solenoid_on[index]      = false; +    solenoid_buzzing[index] = false;  } -void solenoid_fire(void) { -    if (!haptic_config.buzz && solenoid_on) return; -    if (haptic_config.buzz && solenoid_buzzing) return; +/** + * @brief Fires off a specific solenoid + * + * @param index Selects which solenoid to fire + */ +void solenoid_fire(uint8_t index) { +    if (!haptic_config.buzz && solenoid_on[index]) return; +    if (haptic_config.buzz && solenoid_buzzing[index]) return; + +    solenoid_on[index]      = true; +    solenoid_buzzing[index] = true; +    solenoid_start[index]   = timer_read(); +    writePin(solenoid_pads[index], solenoid_active_state[index]); +} -    solenoid_on      = true; -    solenoid_buzzing = true; -    solenoid_start   = timer_read(); -    SOLENOID_PIN_WRITE_ACTIVE(); +/** + * @brief Handles selecting a non-active solenoid, and firing it. + * + */ +void solenoid_fire_handler(void) { +#ifndef SOLENOID_RANDOM_FIRE +    if (NUMBER_OF_SOLENOIDS > 1) { +        uint8_t i = rand() % NUMBER_OF_SOLENOIDS; +        if (!solenoid_on[i]) { +            solenoid_fire(i); +        } +    } else { +        solenoid_fire(0); +    } +#else +    for (uint8_t i = 0; i < NUMBER_OF_SOLENOIDS; i++) { +        if (!solenoid_on[i]) { +            solenoid_fire(i); +            break; +        } +    } +#endif  } +/** + * @brief Checks active solenoid to stop them, and to handle buzz mode + * + */  void solenoid_check(void) { -    uint16_t elapsed = 0; +    uint16_t elapsed[NUMBER_OF_SOLENOIDS] = {0}; -    if (!solenoid_on) return; +    for (uint8_t i = 0; i < NUMBER_OF_SOLENOIDS; i++) { +        if (!solenoid_on[i]) continue; -    elapsed = timer_elapsed(solenoid_start); +        elapsed[i] = timer_elapsed(solenoid_start[i]); -    // Check if it's time to finish this solenoid click cycle -    if (elapsed > solenoid_dwell) { -        solenoid_stop(); -        return; -    } +        // Check if it's time to finish this solenoid click cycle +        if (elapsed[i] > solenoid_dwell) { +            solenoid_stop(i); +            continue; +        } -    // Check whether to buzz the solenoid on and off -    if (haptic_config.buzz) { -        if ((elapsed % (SOLENOID_BUZZ_ACTUATED + SOLENOID_BUZZ_NONACTUATED)) < SOLENOID_BUZZ_ACTUATED) { -            if (!solenoid_buzzing) { -                solenoid_buzzing = true; -                SOLENOID_PIN_WRITE_ACTIVE(); -            } -        } else { -            if (solenoid_buzzing) { -                solenoid_buzzing = false; -                SOLENOID_PIN_WRITE_INACTIVE(); +        // Check whether to buzz the solenoid on and off +        if (haptic_config.buzz) { +            if ((elapsed[i] % (SOLENOID_BUZZ_ACTUATED + SOLENOID_BUZZ_NONACTUATED)) < SOLENOID_BUZZ_ACTUATED) { +                if (!solenoid_buzzing[i]) { +                    solenoid_buzzing[i] = true; +                    writePin(solenoid_pads[i], solenoid_active_state[i]); +                } +            } else { +                if (solenoid_buzzing[i]) { +                    solenoid_buzzing[i] = false; +                    writePin(solenoid_pads[i], !solenoid_active_state[i]); +                }              }          }      }  } +/** + * @brief Initial configuration for solenoids + * + */  void solenoid_setup(void) { -    SOLENOID_PIN_WRITE_INACTIVE(); -    setPinOutput(SOLENOID_PIN); -    if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED)) { -        solenoid_fire(); +#ifdef SOLENOID_PINS_ACTIVE_STATE +    bool    state_temp[] = SOLENOID_PINS_ACTIVE_STATE; +    uint8_t bound_check  = (sizeof(state_temp) / sizeof(bool)); +#endif + +    for (uint8_t i = 0; i < NUMBER_OF_SOLENOIDS; i++) { +#ifdef SOLENOID_PINS_ACTIVE_STATE +        solenoid_active_state[i] = (bound_check - i) ? state_temp[i] : high; +#else +        solenoid_active_state[i] = high; +#endif +        writePin(solenoid_pads[i], !solenoid_active_state[i]); +        setPinOutput(solenoid_pads[i]); +        if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED)) { +            solenoid_fire(i); +        }      }  } +/** + * @brief stops solenoids prior to device reboot, to prevent them from being locked on + * + */  void solenoid_shutdown(void) { -    SOLENOID_PIN_WRITE_INACTIVE(); +    for (uint8_t i = 0; i < NUMBER_OF_SOLENOIDS; i++) { +        writePin(solenoid_pads[i], !solenoid_active_state[i]); +    }  } diff --git a/drivers/haptic/solenoid.h b/drivers/haptic/solenoid.h index 653148154f..952f86e922 100644 --- a/drivers/haptic/solenoid.h +++ b/drivers/haptic/solenoid.h @@ -45,26 +45,24 @@  #    define SOLENOID_BUZZ_NONACTUATED SOLENOID_MIN_DWELL  #endif -#ifndef SOLENOID_PIN -#    error SOLENOID_PIN not defined +#ifndef SOLENOID_PINS +#    ifdef SOLENOID_PIN +#        define SOLENOID_PINS \ +            { SOLENOID_PIN } +#    else +#        error SOLENOID_PINS array not defined +#    endif  #endif -#ifdef SOLENOID_PIN_ACTIVE_LOW -#    define SOLENOID_PIN_WRITE_ACTIVE() writePinLow(SOLENOID_PIN) -#    define SOLENOID_PIN_WRITE_INACTIVE() writePinHigh(SOLENOID_PIN) -#else -#    define SOLENOID_PIN_WRITE_ACTIVE() writePinHigh(SOLENOID_PIN) -#    define SOLENOID_PIN_WRITE_INACTIVE() writePinLow(SOLENOID_PIN) -#endif - -void solenoid_buzz_on(void); +void solenoidbuzz_on(void);  void solenoid_buzz_off(void); -void solenoid_set_buzz(int buzz); +void solenoid_set_buzz(uint8_t buzz);  void solenoid_set_dwell(uint8_t dwell); -void solenoid_stop(void); -void solenoid_fire(void); +void solenoid_stop(uint8_t index); +void solenoid_fire(uint8_t index); +void solenoid_fire_handler(void);  void solenoid_check(void); | 
