libyggdrasil  v1.0.0
joystick.hpp
Go to the documentation of this file.
1  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * _____.___. .___ .__.__ *
3  * \__ | | ____ ____ __| _/___________ _____|__| | *
4  * / | |/ ___\ / ___\ / __ |\_ __ \__ \ / ___/ | | *
5  * \____ / /_/ > /_/ > /_/ | | | \// __ \_\___ \| | |__ *
6  * / ______\___ /\___ /\____ | |__| (____ /____ >__|____/ *
7  * \/ /_____//_____/ \/ \/ \/ *
8  * - Yggdrasil - *
9  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
10  * This software can be used by students and other personal of the *
11  * Bern University of Applied Sciences under the terms of the MIT *
12  * license. *
13  * For other persons this software is under the terms of the GNU *
14  * General Public License version 2. *
15  * *
16  * Copyright © 2021, Bern University of Applied Sciences. *
17  * All rights reserved. *
18  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26 #pragma once
27 
29 #include <cpp/common/types.hpp>
30 #include <cpp/common/utils.hpp>
31 
32 
33 namespace bsp::ygg::prph {
34 
38  class Joystick {
39  public:
40  Joystick() = delete;
41 
45  struct Position {
46  i16 x;
47  i16 y;
48  };
49 
53  struct JoystickData {
55  u16 mag;
56  bool pressed;
57  };
58 
59 
65  static bool init() {
66  return true;
67  }
68 
75  static JoystickData getLeft() {
76  JoystickData data = { 0 };
77 
78  data.pos.x = transformInputData(getADCValue(MUX::SingleEnded_AIN0)); // Get ADC Value
79  data.pos.y = transformInputData(getADCValue(MUX::SingleEnded_AIN1)); // Get ADC Value
80  data.mag = sqrt(data.pos.x * data.pos.x + data.pos.y * data.pos.y);
81  data.pressed = LeftJoyStickButton; // Read the button state
82 
83  if(data.mag < Joystick::s_deadzone) {
84  data.pos = { 0, 0 };
85  }
86 
87  return data;
88  }
89 
97  JoystickData data = { 0 };
98 
99  data.pos.x = -transformInputData(getADCValue(MUX::SingleEnded_AIN2)); // Get ADC Value
100  data.pos.y = -transformInputData(getADCValue(MUX::SingleEnded_AIN3)); // Get ADC Value
101  data.mag = sqrt(data.pos.x * data.pos.x + data.pos.y * data.pos.y);
102  data.pressed = RightJoyStickButton; // Read the button state
103 
104  if(data.mag < Joystick::s_deadzone) {
105  data.pos = { 0, 0 };
106  }
107 
108  return data;
109  }
110 
116  static void setDeadzone(u8 deadzone) {
117  if (deadzone < PositionMax)
118  Joystick::s_deadzone = deadzone;
119  }
120 
126  static u8 getDeadzone() {
127  return Joystick::s_deadzone;
128  }
129 
130  private:
131 
135  enum class RegisterID : u8 {
136  ConversionRegister = 0x00,
137  ConfigurationRegister = 0x01,
138  };
139 
143  enum class MUX : u8 {
144  Differential_AIN0_AIN1 = 0x00,
145  Differential_AIN0_AIN3 = 0x01,
146  Differential_AIN1_AIN3 = 0x02,
147  Differential_AIN2_AIN3 = 0x03,
148  SingleEnded_AIN0 = 0x04,
149  SingleEnded_AIN1 = 0x05,
150  SingleEnded_AIN2 = 0x06,
151  SingleEnded_AIN3 = 0x07,
152  };
153 
157  enum class PGA : u8 {
158  FSR_6p144 = 0x00,
159  FSR_4p096 = 0x01,
160  FSR_2p048 = 0x02,
161  FSR_1p024 = 0x03,
162  FSR_0p512 = 0x04,
163  FSR_0p256 = 0x05,
164  };
165 
169  enum class MODE : u8 {
170  Continious = 0x00,
171  SingleShot = 0x01,
172  };
173 
177  enum class DR : u8 {
178  SPS128 = 0x00,
179  SPS250 = 0x01,
180  SPS490 = 0x02,
181  SPS920 = 0x03,
182  SPS1600 = 0x04,
183  SPS2400 = 0x05,
184  SPS3300 = 0x06,
185  };
186 
190  struct ConfigurationRegister {
191  u16 Reserved : 5;
192  u16 DR : 3;
193  u16 MODE : 1;
194  u16 PGA : 3;
195  u16 MUX : 3;
196  u16 OS : 1;
197  };
198 
199  static_assert(sizeof(ConfigurationRegister) == sizeof(u16), "Configuration register definition wrong");
200 
201 
202  constexpr static inline u8 DeviceAddress = 0x90;
203  constexpr static inline u8 ReservedBits = 0x03;
204  constexpr static inline u16 ConversionDone = 0x8000;
205 
206  constexpr static inline u16 CenterPosition = 0x34A;
207  constexpr static inline u16 MaxADCValue = 0x56A;
208  constexpr static inline u16 MinADCValue = 0x100;
209  constexpr static inline i8 PositionRange = 200;
210  constexpr static inline i8 PositionMin = -100;
211  constexpr static inline i8 PositionMax = 100;
212 
213  static inline i8 s_deadzone = 5;
214 
215 
223  static u16 getADCValue(MUX channel) {
224  ConfigurationRegister configRegister = {0};
225  configRegister.OS = 1;
226  configRegister.MUX = enumValue(channel);
227  configRegister.PGA = enumValue(PGA::FSR_4p096);
228  configRegister.MODE = enumValue(MODE::SingleShot);
229  configRegister.DR = enumValue(DR::SPS1600);
230  configRegister.Reserved = ReservedBits;
231 
232  bsp::I2CA::write<ByteSwapped<u16>>(DeviceAddress, enumValue(RegisterID::ConfigurationRegister), bit_cast<u16>(configRegister)); // Start Conversion
233 
234  while((bsp::I2CA::read<ByteSwapped<u16>>(DeviceAddress, enumValue(RegisterID::ConfigurationRegister)) & ConversionDone) == ConversionDone) { // Poll results
235  core::delay(1); // Avoid spamming the I2C
236  }
237 
238  auto adcData = bsp::I2CA::read<ByteSwapped<u16>>(DeviceAddress, enumValue(RegisterID::ConversionRegister)); // Read results
239 
240  return adcData;
241  }
242 
249  static inline i16 transformInputData(u16 adcData) {
250  return ((((static_cast<i16>(adcData >> 4) - MinADCValue) / float(MaxADCValue - MinADCValue)) * 2.0F) - 1.0F) * 100.0F; // Convert the 11 bit tow's complement value to a i8 ranged [-100,100]
251  }
252 
253  };
254 
255 }
bsp::ygg::prph::Joystick::JoystickData::pos
Position pos
Position.
Definition: joystick.hpp:54
bsp::Register
MMIO Register abstraction. Gives access to bitfields within the register as well as a reference to th...
Definition: registers.hpp:90
u16
uint16_t u16
Definition: types.h:37
utils.hpp
Commonly used helper functions.
u8
uint8_t u8
Unsigned integer definitions.
Definition: types.h:36
i16
int16_t i16
Definition: types.h:47
bsp::ygg::prph::Joystick::Position::y
i16 y
Y Axis.
Definition: joystick.hpp:47
bsp::ygg::prph::Joystick::getRight
static JoystickData getRight()
Get the joystick data for the right joystick.
Definition: joystick.hpp:96
types.hpp
Commonly used type definitions and helper templates.
bsp::ygg::prph::Joystick::Position
Signed position data.
Definition: joystick.hpp:45
bsp::enumValue
auto enumValue(T value)
Casts a scoped enum type into its underlying value.
Definition: utils.hpp:151
bsp::ygg::prph::Joystick::JoystickData::pressed
bool pressed
State of the joystick button.
Definition: joystick.hpp:56
bsp::ygg::prph::Joystick::JoystickData::mag
u16 mag
Magnitude / radius from the center.
Definition: joystick.hpp:55
i8
int8_t i8
Signed integer definitions.
Definition: types.h:46
bsp::ygg::prph::Joystick::JoystickData
Joystick data.
Definition: joystick.hpp:53
bsp::ygg::prph::Joystick::setDeadzone
static void setDeadzone(u8 deadzone)
Set both joystick's deadzone.
Definition: joystick.hpp:116
bsp::ygg::prph::Joystick::getDeadzone
static u8 getDeadzone()
Get the current Joystick deadzone.
Definition: joystick.hpp:126
bsp::ygg::prph::Joystick::Joystick
Joystick()=delete
bsp::ygg::prph::Joystick::Position::x
i16 x
X Axis.
Definition: joystick.hpp:46
bsp::ygg::prph::Joystick::init
static bool init()
Initialization function.
Definition: joystick.hpp:65
bsp::ygg::prph::Joystick
Joystick driver using the TLA2024IRUGT ADCS.
Definition: joystick.hpp:38
attributes.hpp
Commonly used C++ and GNU attributes.
bsp::ygg::prph::Joystick::getLeft
static JoystickData getLeft()
Get the joystick data for the left joystick.
Definition: joystick.hpp:75
bsp::core::delay
ALWAYS_INLINE void delay(u32 ms)
Delays execution by a certain number of milliseconds.
Definition: cortex.hpp:39
bsp::ygg::prph
Definition: color_sensor.hpp:32