Fix for hack that worked around iOS app
Haptics.cpp@2:4f76784f8968, 2016-02-25 (annotated)
- Committer:
- roysandberg
- Date:
- Thu Feb 25 00:19:46 2016 +0000
- Revision:
- 2:4f76784f8968
- Parent:
- 0:8c0ecbdd3449
- Child:
- 3:b64f3abb3c0b
On/Off/Twilight Mode
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
roysandberg | 0:8c0ecbdd3449 | 1 | /****************************************************************************** |
roysandberg | 0:8c0ecbdd3449 | 2 | * Haptics.c |
roysandberg | 0:8c0ecbdd3449 | 3 | * |
roysandberg | 0:8c0ecbdd3449 | 4 | * Created on: Dec 16, 2011 |
roysandberg | 0:8c0ecbdd3449 | 5 | * Board: DRV2603EVM-CT RevD |
roysandberg | 0:8c0ecbdd3449 | 6 | * Author: a0866685 |
roysandberg | 0:8c0ecbdd3449 | 7 | * |
roysandberg | 0:8c0ecbdd3449 | 8 | * Description: This file contains the functions for sending haptics waveforms. |
roysandberg | 0:8c0ecbdd3449 | 9 | * Edit this file when changing actuators. |
roysandberg | 0:8c0ecbdd3449 | 10 | * |
roysandberg | 0:8c0ecbdd3449 | 11 | * @TODO - Update this file when changing between actuators types |
roysandberg | 0:8c0ecbdd3449 | 12 | * (ERM, LRA, Piezo) |
roysandberg | 0:8c0ecbdd3449 | 13 | * |
roysandberg | 0:8c0ecbdd3449 | 14 | ******************************************************************************/ |
roysandberg | 2:4f76784f8968 | 15 | |
roysandberg | 0:8c0ecbdd3449 | 16 | #include "Actuator_Waveforms.h" |
roysandberg | 0:8c0ecbdd3449 | 17 | |
roysandberg | 0:8c0ecbdd3449 | 18 | // private variables |
roysandberg | 0:8c0ecbdd3449 | 19 | //static uint8_t j,k; |
roysandberg | 0:8c0ecbdd3449 | 20 | |
roysandberg | 2:4f76784f8968 | 21 | extern float lraEffectMultiplier; // defined in main.cpp |
roysandberg | 2:4f76784f8968 | 22 | |
roysandberg | 0:8c0ecbdd3449 | 23 | // public variables |
roysandberg | 0:8c0ecbdd3449 | 24 | uint16_t Haptics_dumbModeTick = DUMBTICK; // Sets the LRA Auto-resonance off frequency (use DUMBTICK above to set frequency) |
roysandberg | 0:8c0ecbdd3449 | 25 | uint16_t Haptics_resonantModeTick; |
roysandberg | 0:8c0ecbdd3449 | 26 | |
roysandberg | 0:8c0ecbdd3449 | 27 | DigitalOut LRA_EN(P0_12); |
roysandberg | 0:8c0ecbdd3449 | 28 | PwmOut LRA(P0_11); |
roysandberg | 0:8c0ecbdd3449 | 29 | |
roysandberg | 0:8c0ecbdd3449 | 30 | extern DigitalOut led1; |
roysandberg | 0:8c0ecbdd3449 | 31 | |
roysandberg | 2:4f76784f8968 | 32 | |
roysandberg | 2:4f76784f8968 | 33 | // Used for off-mode haptics and LED signature |
roysandberg | 2:4f76784f8968 | 34 | Timeout firstLEDOff; |
roysandberg | 2:4f76784f8968 | 35 | Timeout secondBuzz; |
roysandberg | 2:4f76784f8968 | 36 | Timeout secondLEDOff; |
roysandberg | 2:4f76784f8968 | 37 | |
roysandberg | 0:8c0ecbdd3449 | 38 | Ticker hapticsTicker; |
roysandberg | 0:8c0ecbdd3449 | 39 | volatile uint16_t lraPlaybackMode = 0; |
roysandberg | 0:8c0ecbdd3449 | 40 | volatile int lraCurrent = 0; |
roysandberg | 0:8c0ecbdd3449 | 41 | volatile int lraTarget = 0; |
roysandberg | 0:8c0ecbdd3449 | 42 | volatile uint16_t lraDelay = 0; |
roysandberg | 0:8c0ecbdd3449 | 43 | volatile uint16_t placeInWaveform = 0; |
roysandberg | 0:8c0ecbdd3449 | 44 | volatile uint16_t waveformDelayCounter = 0; |
roysandberg | 0:8c0ecbdd3449 | 45 | const Waveform* volatile waveform; |
roysandberg | 2:4f76784f8968 | 46 | //const Waveform* volatile heartbeatWaveform = &lra_tick; |
roysandberg | 2:4f76784f8968 | 47 | const Waveform* volatile heartbeatWaveform = &lra_rampdown; |
roysandberg | 2:4f76784f8968 | 48 | |
roysandberg | 2:4f76784f8968 | 49 | |
roysandberg | 0:8c0ecbdd3449 | 50 | |
roysandberg | 0:8c0ecbdd3449 | 51 | |
roysandberg | 0:8c0ecbdd3449 | 52 | // TODO: Support haptics modalities here: off, waveform, delayed waveform, ramp to target |
roysandberg | 0:8c0ecbdd3449 | 53 | |
roysandberg | 0:8c0ecbdd3449 | 54 | // Called every 5ms to update LRA amplitude based on desired haptics response |
roysandberg | 0:8c0ecbdd3449 | 55 | void hapticsCallback() { |
roysandberg | 0:8c0ecbdd3449 | 56 | switch (lraPlaybackMode) { |
roysandberg | 0:8c0ecbdd3449 | 57 | case LRA_MODE_WAVEFORM: |
roysandberg | 0:8c0ecbdd3449 | 58 | // play the current amplitude |
roysandberg | 0:8c0ecbdd3449 | 59 | //led1 = 1; |
roysandberg | 0:8c0ecbdd3449 | 60 | |
roysandberg | 0:8c0ecbdd3449 | 61 | if(waveform->data[placeInWaveform] == 0x80) { |
roysandberg | 0:8c0ecbdd3449 | 62 | LRA.pulsewidth_us(0); |
roysandberg | 0:8c0ecbdd3449 | 63 | LRA_EN = 0; |
roysandberg | 0:8c0ecbdd3449 | 64 | } else { |
roysandberg | 0:8c0ecbdd3449 | 65 | LRA_EN = 1; |
roysandberg | 2:4f76784f8968 | 66 | float scaledWaveform = ((float)waveform->data[placeInWaveform]) * 0.375 * lraEffectMultiplier; // 0.375 is 96/256 |
roysandberg | 2:4f76784f8968 | 67 | LRA.pulsewidth_us((uint16_t)scaledWaveform); |
roysandberg | 2:4f76784f8968 | 68 | //LRA.pulsewidth_us(((((uint16_t)waveform->data[placeInWaveform])*3) >> 3)); // mult by 3 shift right by 3 to get in range of 0..96 |
roysandberg | 2:4f76784f8968 | 69 | //LRA.pulsewidth_us(90); // used for fixed intensity output (for testing) |
roysandberg | 0:8c0ecbdd3449 | 70 | } |
roysandberg | 0:8c0ecbdd3449 | 71 | |
roysandberg | 0:8c0ecbdd3449 | 72 | // run down the timer on this amplitude |
roysandberg | 0:8c0ecbdd3449 | 73 | waveformDelayCounter++; |
roysandberg | 0:8c0ecbdd3449 | 74 | if (waveformDelayCounter >= waveform->data[placeInWaveform+1]) { |
roysandberg | 0:8c0ecbdd3449 | 75 | // move to the next waveform entry and reset the timer when necessary |
roysandberg | 0:8c0ecbdd3449 | 76 | waveformDelayCounter=0; |
roysandberg | 0:8c0ecbdd3449 | 77 | placeInWaveform += 2; |
roysandberg | 0:8c0ecbdd3449 | 78 | if (placeInWaveform >= waveform->length) { |
roysandberg | 0:8c0ecbdd3449 | 79 | //led1 = 0; |
roysandberg | 0:8c0ecbdd3449 | 80 | LRA.pulsewidth_us(0); |
roysandberg | 0:8c0ecbdd3449 | 81 | LRA_EN = 0; |
roysandberg | 0:8c0ecbdd3449 | 82 | placeInWaveform = 0; |
roysandberg | 0:8c0ecbdd3449 | 83 | waveformDelayCounter = 0; |
roysandberg | 0:8c0ecbdd3449 | 84 | lraPlaybackMode = LRA_MODE_OFF; |
roysandberg | 0:8c0ecbdd3449 | 85 | } |
roysandberg | 0:8c0ecbdd3449 | 86 | } |
roysandberg | 0:8c0ecbdd3449 | 87 | break; |
roysandberg | 0:8c0ecbdd3449 | 88 | case LRA_MODE_DELAYED_WAVEFORM: |
roysandberg | 0:8c0ecbdd3449 | 89 | waveformDelayCounter+=5; // every tick is 5ms |
roysandberg | 0:8c0ecbdd3449 | 90 | if (waveformDelayCounter >= lraDelay) { |
roysandberg | 0:8c0ecbdd3449 | 91 | waveformDelayCounter = 0; |
roysandberg | 0:8c0ecbdd3449 | 92 | lraPlaybackMode = LRA_MODE_WAVEFORM; |
roysandberg | 0:8c0ecbdd3449 | 93 | } |
roysandberg | 0:8c0ecbdd3449 | 94 | break; |
roysandberg | 0:8c0ecbdd3449 | 95 | case LRA_MODE_RAMP_TO_TARGET: |
roysandberg | 0:8c0ecbdd3449 | 96 | // full ramp from 384 to 768 (threshold to full) takes 384*5 = 1920ms with step size = 1 |
roysandberg | 0:8c0ecbdd3449 | 97 | if (lraTarget > lraCurrent) { |
roysandberg | 0:8c0ecbdd3449 | 98 | lraCurrent += 2; |
roysandberg | 0:8c0ecbdd3449 | 99 | } else { |
roysandberg | 0:8c0ecbdd3449 | 100 | lraCurrent -= 2; |
roysandberg | 0:8c0ecbdd3449 | 101 | } |
roysandberg | 0:8c0ecbdd3449 | 102 | LRA_EN = 1; |
roysandberg | 0:8c0ecbdd3449 | 103 | //led1 = 1; |
roysandberg | 0:8c0ecbdd3449 | 104 | LRA.pulsewidth_us((lraCurrent) >> 3); //divide by 8 to get in range of 0..95 |
roysandberg | 0:8c0ecbdd3449 | 105 | break; |
roysandberg | 0:8c0ecbdd3449 | 106 | case LRA_MODE_OFF: |
roysandberg | 0:8c0ecbdd3449 | 107 | default: |
roysandberg | 0:8c0ecbdd3449 | 108 | // Do nothing |
roysandberg | 0:8c0ecbdd3449 | 109 | break; |
roysandberg | 0:8c0ecbdd3449 | 110 | } |
roysandberg | 0:8c0ecbdd3449 | 111 | } |
roysandberg | 0:8c0ecbdd3449 | 112 | |
roysandberg | 0:8c0ecbdd3449 | 113 | /** |
roysandberg | 0:8c0ecbdd3449 | 114 | * Haptics_Init - initialize haptics variables and settings |
roysandberg | 0:8c0ecbdd3449 | 115 | */ |
roysandberg | 0:8c0ecbdd3449 | 116 | void Haptics_Init(void) |
roysandberg | 0:8c0ecbdd3449 | 117 | { |
roysandberg | 0:8c0ecbdd3449 | 118 | // mbed uses 4uS timer precision, so keep this as large as possible for better granularity |
roysandberg | 0:8c0ecbdd3449 | 119 | // 96 uS period means 96 is the maximum pulse width. So we need to scale from 256 to 96, or mult by 3, and shift right by 3. |
roysandberg | 0:8c0ecbdd3449 | 120 | LRA.period_us(96); // 96 uS -> 10.4 Khz (needs to be between 10Khz and 250Khz) |
roysandberg | 0:8c0ecbdd3449 | 121 | |
roysandberg | 0:8c0ecbdd3449 | 122 | hapticsTicker.attach(&hapticsCallback, 0.005); // update haptics every 5 ms |
roysandberg | 0:8c0ecbdd3449 | 123 | |
roysandberg | 0:8c0ecbdd3449 | 124 | Haptics_resonantModeTick = (unsigned int) Haptics_dumbModeTick * 2; |
roysandberg | 0:8c0ecbdd3449 | 125 | } |
roysandberg | 0:8c0ecbdd3449 | 126 | |
roysandberg | 0:8c0ecbdd3449 | 127 | |
roysandberg | 0:8c0ecbdd3449 | 128 | /* |
roysandberg | 0:8c0ecbdd3449 | 129 | * Haptics_OutputWaveform - control the PWM output pattern |
roysandberg | 0:8c0ecbdd3449 | 130 | * @param struct Waveform - the waveform output type, length in bytes, and data |
roysandberg | 0:8c0ecbdd3449 | 131 | */ |
roysandberg | 0:8c0ecbdd3449 | 132 | void Haptics_OutputWaveform(const Waveform* newWaveform) |
roysandberg | 0:8c0ecbdd3449 | 133 | { |
roysandberg | 0:8c0ecbdd3449 | 134 | |
roysandberg | 0:8c0ecbdd3449 | 135 | if (lraPlaybackMode == LRA_MODE_OFF || lraPlaybackMode == LRA_MODE_RAMP_TO_TARGET) { |
roysandberg | 0:8c0ecbdd3449 | 136 | waveform = newWaveform; |
roysandberg | 0:8c0ecbdd3449 | 137 | lraPlaybackMode = LRA_MODE_WAVEFORM; |
roysandberg | 0:8c0ecbdd3449 | 138 | } else { |
roysandberg | 0:8c0ecbdd3449 | 139 | //printf("OutputWaveform: mode=%d, delay=%d, place=%d\n\r", lraPlaybackMode, waveformDelayCounter, placeInWaveform); |
roysandberg | 0:8c0ecbdd3449 | 140 | } |
roysandberg | 0:8c0ecbdd3449 | 141 | } |
roysandberg | 0:8c0ecbdd3449 | 142 | |
roysandberg | 0:8c0ecbdd3449 | 143 | // Override any currently active haptic effect |
roysandberg | 0:8c0ecbdd3449 | 144 | void Haptics_OverrideOutputWaveform(const Waveform* newWaveform) |
roysandberg | 0:8c0ecbdd3449 | 145 | { |
roysandberg | 0:8c0ecbdd3449 | 146 | //led1 = !led1; |
roysandberg | 0:8c0ecbdd3449 | 147 | placeInWaveform = 0; |
roysandberg | 0:8c0ecbdd3449 | 148 | waveform = newWaveform; |
roysandberg | 0:8c0ecbdd3449 | 149 | LRA_EN = 1; |
roysandberg | 0:8c0ecbdd3449 | 150 | LRA.pulsewidth_us((((int)waveform->data[placeInWaveform])*3) >> 3); // mult by 3 shift right by 2 to get in range of 0..95 |
roysandberg | 0:8c0ecbdd3449 | 151 | lraPlaybackMode = LRA_MODE_WAVEFORM; |
roysandberg | 0:8c0ecbdd3449 | 152 | } |
roysandberg | 0:8c0ecbdd3449 | 153 | |
roysandberg | 0:8c0ecbdd3449 | 154 | void Haptics_OutputDelayedHeartbeat(uint16_t delay) { |
roysandberg | 0:8c0ecbdd3449 | 155 | Haptics_OutputDelayedWaveform(heartbeatWaveform, delay); |
roysandberg | 0:8c0ecbdd3449 | 156 | } |
roysandberg | 0:8c0ecbdd3449 | 157 | |
roysandberg | 0:8c0ecbdd3449 | 158 | void Haptics_SetHeartbeatWaveform (int waveformNum) { |
roysandberg | 0:8c0ecbdd3449 | 159 | printf("SetHeartbeatWaveform to %d.\n\r", waveformNum); |
roysandberg | 0:8c0ecbdd3449 | 160 | |
roysandberg | 0:8c0ecbdd3449 | 161 | switch (waveformNum) { |
roysandberg | 0:8c0ecbdd3449 | 162 | case 1: |
roysandberg | 0:8c0ecbdd3449 | 163 | heartbeatWaveform = &lra_click_nobrake; |
roysandberg | 0:8c0ecbdd3449 | 164 | break; |
roysandberg | 0:8c0ecbdd3449 | 165 | case 2: |
roysandberg | 0:8c0ecbdd3449 | 166 | heartbeatWaveform = &lra_alert; |
roysandberg | 0:8c0ecbdd3449 | 167 | break; |
roysandberg | 0:8c0ecbdd3449 | 168 | case 3: |
roysandberg | 0:8c0ecbdd3449 | 169 | heartbeatWaveform = &lra_rampup; |
roysandberg | 0:8c0ecbdd3449 | 170 | break; |
roysandberg | 0:8c0ecbdd3449 | 171 | case 4: |
roysandberg | 0:8c0ecbdd3449 | 172 | heartbeatWaveform = &lra_rampdown; |
roysandberg | 0:8c0ecbdd3449 | 173 | break; |
roysandberg | 0:8c0ecbdd3449 | 174 | case 5: |
roysandberg | 0:8c0ecbdd3449 | 175 | heartbeatWaveform = &lra_softclick; |
roysandberg | 0:8c0ecbdd3449 | 176 | break; |
roysandberg | 0:8c0ecbdd3449 | 177 | case 6: |
roysandberg | 0:8c0ecbdd3449 | 178 | heartbeatWaveform = &lra_softbump; |
roysandberg | 0:8c0ecbdd3449 | 179 | break; |
roysandberg | 0:8c0ecbdd3449 | 180 | case 7: |
roysandberg | 0:8c0ecbdd3449 | 181 | heartbeatWaveform = &lra_softalert; |
roysandberg | 0:8c0ecbdd3449 | 182 | break; |
roysandberg | 0:8c0ecbdd3449 | 183 | case 8: |
roysandberg | 0:8c0ecbdd3449 | 184 | heartbeatWaveform = &lra_rampupdoubleclick; |
roysandberg | 0:8c0ecbdd3449 | 185 | break; |
roysandberg | 0:8c0ecbdd3449 | 186 | case 0: |
roysandberg | 0:8c0ecbdd3449 | 187 | default: |
roysandberg | 0:8c0ecbdd3449 | 188 | heartbeatWaveform = &lra_tick; |
roysandberg | 0:8c0ecbdd3449 | 189 | } |
roysandberg | 0:8c0ecbdd3449 | 190 | } |
roysandberg | 0:8c0ecbdd3449 | 191 | |
roysandberg | 0:8c0ecbdd3449 | 192 | void Haptics_OutputDelayedWaveform(const Waveform* newWaveform, uint16_t delay) { |
roysandberg | 0:8c0ecbdd3449 | 193 | |
roysandberg | 0:8c0ecbdd3449 | 194 | if (lraPlaybackMode == LRA_MODE_OFF || lraPlaybackMode == LRA_MODE_RAMP_TO_TARGET) { |
roysandberg | 0:8c0ecbdd3449 | 195 | placeInWaveform = 0; |
roysandberg | 0:8c0ecbdd3449 | 196 | waveformDelayCounter = 0; |
roysandberg | 0:8c0ecbdd3449 | 197 | lraDelay = delay; |
roysandberg | 0:8c0ecbdd3449 | 198 | waveform = newWaveform; |
roysandberg | 0:8c0ecbdd3449 | 199 | lraPlaybackMode = LRA_MODE_DELAYED_WAVEFORM; |
roysandberg | 0:8c0ecbdd3449 | 200 | } else { |
roysandberg | 0:8c0ecbdd3449 | 201 | //printf("Haptics: mode=%d, delay=%d, until=%d, place=%d\n\r", lraPlaybackMode, waveformDelayCounter, lraDelay, placeInWaveform); |
roysandberg | 0:8c0ecbdd3449 | 202 | } |
roysandberg | 0:8c0ecbdd3449 | 203 | } |
roysandberg | 2:4f76784f8968 | 204 | |
roysandberg | 2:4f76784f8968 | 205 | |
roysandberg | 2:4f76784f8968 | 206 | void LEDOffCallback() { |
roysandberg | 2:4f76784f8968 | 207 | led1=0; |
roysandberg | 2:4f76784f8968 | 208 | } |
roysandberg | 2:4f76784f8968 | 209 | |
roysandberg | 2:4f76784f8968 | 210 | void BuzzCallback() { |
roysandberg | 2:4f76784f8968 | 211 | Haptics_OutputWaveform(&lra_alert); |
roysandberg | 2:4f76784f8968 | 212 | led1 = 1; |
roysandberg | 2:4f76784f8968 | 213 | } |
roysandberg | 2:4f76784f8968 | 214 | |
roysandberg | 2:4f76784f8968 | 215 | // generate off mode haptic response |
roysandberg | 2:4f76784f8968 | 216 | // This is 2 buzzes separated by 300 ms, and 2 led blinks with the same timing. |
roysandberg | 2:4f76784f8968 | 217 | void LeavingOffModeHapticResponse(int ledFinalState) { |
roysandberg | 0:8c0ecbdd3449 | 218 | |
roysandberg | 2:4f76784f8968 | 219 | // Turn on LED and generate first buzz |
roysandberg | 2:4f76784f8968 | 220 | BuzzCallback(); |
roysandberg | 2:4f76784f8968 | 221 | |
roysandberg | 2:4f76784f8968 | 222 | // Setup callback to turn off LED after 50ms |
roysandberg | 2:4f76784f8968 | 223 | firstLEDOff.attach(&LEDOffCallback,0.05); |
roysandberg | 2:4f76784f8968 | 224 | |
roysandberg | 2:4f76784f8968 | 225 | // Setup callback to generate second buzz after 300ms, and turn on LED second time |
roysandberg | 2:4f76784f8968 | 226 | secondBuzz.attach(&BuzzCallback,0.3); |
roysandberg | 2:4f76784f8968 | 227 | |
roysandberg | 2:4f76784f8968 | 228 | // Setup callback to turn off LED after 350mS |
roysandberg | 2:4f76784f8968 | 229 | if (ledFinalState == 0) { |
roysandberg | 2:4f76784f8968 | 230 | secondLEDOff.attach(&LEDOffCallback,0.35); |
roysandberg | 2:4f76784f8968 | 231 | } |
roysandberg | 2:4f76784f8968 | 232 | } |
roysandberg | 2:4f76784f8968 | 233 | |
roysandberg | 2:4f76784f8968 | 234 | void EnteringOffModeHapticResponse() { |
roysandberg | 2:4f76784f8968 | 235 | Haptics_OutputWaveform(&lra_rampdown); |
roysandberg | 2:4f76784f8968 | 236 | led1 = 0; |
roysandberg | 2:4f76784f8968 | 237 | } |
roysandberg | 2:4f76784f8968 | 238 | |
roysandberg | 0:8c0ecbdd3449 | 239 | // Ignored while waveform is playing or queued. Overridden by waveforms. |
roysandberg | 0:8c0ecbdd3449 | 240 | void Haptics_SetRampTarget(float amplitude) |
roysandberg | 0:8c0ecbdd3449 | 241 | { |
roysandberg | 0:8c0ecbdd3449 | 242 | if (lraPlaybackMode == LRA_MODE_OFF || lraPlaybackMode == LRA_MODE_RAMP_TO_TARGET) { |
roysandberg | 0:8c0ecbdd3449 | 243 | if (lraPlaybackMode == LRA_MODE_OFF) { |
roysandberg | 0:8c0ecbdd3449 | 244 | lraCurrent = 384; // reset to threshold off if this is the first ramp target |
roysandberg | 0:8c0ecbdd3449 | 245 | } |
roysandberg | 0:8c0ecbdd3449 | 246 | if (amplitude > 1.0) amplitude = 1.0; |
roysandberg | 0:8c0ecbdd3449 | 247 | if (amplitude < 0.0) amplitude = 0.0; |
roysandberg | 0:8c0ecbdd3449 | 248 | lraTarget = (int) (amplitude*768); // (96 * 8) |
roysandberg | 0:8c0ecbdd3449 | 249 | lraPlaybackMode = LRA_MODE_RAMP_TO_TARGET; |
roysandberg | 0:8c0ecbdd3449 | 250 | //printf("Ramp current=%d, target=%d\n\r", lraCurrent>>3, lraTarget>>3); |
roysandberg | 0:8c0ecbdd3449 | 251 | } |
roysandberg | 0:8c0ecbdd3449 | 252 | } |
roysandberg | 0:8c0ecbdd3449 | 253 | |
roysandberg | 0:8c0ecbdd3449 | 254 | // Buzz this many times |
roysandberg | 0:8c0ecbdd3449 | 255 | void Haptics_OutputCount (uint16_t count) { |
roysandberg | 0:8c0ecbdd3449 | 256 | switch (count) { |
roysandberg | 0:8c0ecbdd3449 | 257 | case 1: |
roysandberg | 0:8c0ecbdd3449 | 258 | Haptics_OutputWaveform(&lra_click_nobrake); |
roysandberg | 0:8c0ecbdd3449 | 259 | break; |
roysandberg | 0:8c0ecbdd3449 | 260 | case 2: |
roysandberg | 0:8c0ecbdd3449 | 261 | Haptics_OutputWaveform(&lra_doubleclick_nobrake); |
roysandberg | 0:8c0ecbdd3449 | 262 | break; |
roysandberg | 0:8c0ecbdd3449 | 263 | case 3: |
roysandberg | 0:8c0ecbdd3449 | 264 | Haptics_OutputWaveform(&lra_tripleclick_nobrake); |
roysandberg | 0:8c0ecbdd3449 | 265 | break; |
roysandberg | 0:8c0ecbdd3449 | 266 | } |
roysandberg | 0:8c0ecbdd3449 | 267 | } |
roysandberg | 0:8c0ecbdd3449 | 268 | |
roysandberg | 0:8c0ecbdd3449 | 269 | // Stop haptics regardless of mode |
roysandberg | 0:8c0ecbdd3449 | 270 | void Haptics_Off() |
roysandberg | 0:8c0ecbdd3449 | 271 | { |
roysandberg | 0:8c0ecbdd3449 | 272 | lraPlaybackMode = LRA_MODE_OFF; |
roysandberg | 0:8c0ecbdd3449 | 273 | } |
roysandberg | 0:8c0ecbdd3449 | 274 | |
roysandberg | 0:8c0ecbdd3449 | 275 | bool isHapticsOff() |
roysandberg | 0:8c0ecbdd3449 | 276 | { |
roysandberg | 0:8c0ecbdd3449 | 277 | return (lraPlaybackMode == LRA_MODE_OFF); |
roysandberg | 0:8c0ecbdd3449 | 278 | } |