Raspberry Pi Weighting Control System
This project serves as a simple weighting control system, that was realized as a Bachelor Thesis
Functions | Variables
keyboard Namespace Reference

Functions

uint16_t buffer_to_keycode (const uint8_t *rx_buffer)
 Concats keycode from rx_buffer into one (uint16_t) variable. rx_buffer is 4 bytes (this is assumed to always be true -> no error checking). Only middle bytes (index 1 and 2) are the actual keycode (byte_0 = cs, byte_3 = 00) More...
 
void push_event (uint16_t scancode, uint8_t flags)
 Creates and pushes event into event_queue. More...
 
kb_eventpoll_event ()
 Polls event from queue into param event Returns 1 on success because it is inteded to return "true" on successfull event pop. More...
 
void clear_event_queue ()
 With this the event queue can be cleared but all events are discarded. This can be used if limiting the maximum number of handled events. More...
 
int init (const char *device, uint8_t mode, uint32_t speed, uint16_t delay, uint8_t bits_per_word)
 Initializes spi_config and my_spi global variables and starts SPI. More...
 
int init_from_conf ()
 Initializes my_spi with config loaded from config file into app_workspace. Starts SPI. More...
 
void start_capturing_events ()
 Infinite loop that reads SPI keyboard. Runs in it's own thread! More...
 
void clean ()
 Stops event capturing and closes SPI. More...
 
bool get_kb_testing_inner ()
 
void set_kb_testing_inner (bool val)
 

Variables

std::queue< kb_eventevent_queue
 
std::mutex eq_mutex
 
bool kb_testing = false
 
std::mutex test_mtx
 
unsigned long responses_sum = 0
 
int responses_passed = 0
 
std::unique_ptr< spi_config_t > spi_config
 
std::unique_ptr< SPI > my_spi = nullptr
 
bool capturing_events = true
 

Function Documentation

◆ buffer_to_keycode()

uint16_t keyboard::buffer_to_keycode ( const uint8_t *  rx_buffer)

Concats keycode from rx_buffer into one (uint16_t) variable. rx_buffer is 4 bytes (this is assumed to always be true -> no error checking). Only middle bytes (index 1 and 2) are the actual keycode (byte_0 = cs, byte_3 = 00)

Parameters
rx_bufferread byte buffer
Returns
uint16_t resulting keycode as one value

Definition at line 239 of file keyboard.cpp.

239  {
240  uint16_t key = 0;
241  key = (key | rx_buffer[1]) << 8;
242  key |= rx_buffer[2];
243  return key;
244  }

◆ clean()

void keyboard::clean ( )

Stops event capturing and closes SPI.

Definition at line 209 of file keyboard.cpp.

209  {
210  spdlog::info("keyboard.cpp - Cleaning SPI keyboard");
211  capturing_events = false;
212  // my_spi is unique_ptr, should destruct automatically
213  }
bool capturing_events
Definition: keyboard.cpp:36

◆ clear_event_queue()

void keyboard::clear_event_queue ( )

With this the event queue can be cleared but all events are discarded. This can be used if limiting the maximum number of handled events.

Definition at line 70 of file keyboard.cpp.

70  {
71  for (size_t i = 0; i < event_queue.size(); i++) {
72  event_queue.pop();
73  }
74  }
std::queue< kb_event > event_queue
Definition: keyboard.cpp:24

◆ get_kb_testing_inner()

bool keyboard::get_kb_testing_inner ( )

Returns the kb_testing flag value

Definition at line 216 of file keyboard.cpp.

216  {
217  std::lock_guard<std::mutex> kb_guard(test_mtx);
218  return kb_testing;
219  }
bool kb_testing
Definition: keyboard.cpp:29
std::mutex test_mtx
Definition: keyboard.cpp:30

◆ init()

int keyboard::init ( const char *  device,
uint8_t  mode,
uint32_t  speed,
uint16_t  delay,
uint8_t  bits_per_word 
)

Initializes spi_config and my_spi global variables and starts SPI.

Parameters
device
mode
speed
delay
bits_per_word
Returns
int: 0 on success, other values on error

Definition at line 86 of file keyboard.cpp.

86  {
87  spi_config = std::unique_ptr<spi_config_t>(new spi_config_t());
88  spi_config->mode = mode;
89  spi_config->speed = speed;
90  spi_config->delay = delay;
91  spi_config->bits_per_word = bits_per_word;
92 
93  spdlog::info("keyboard.cpp - Initializing SPI keyboard (through parameters, enable debug to print config");
94  spdlog::debug("keyboard.cpp - SPI conf dev: {0}" , device);
95  spdlog::debug("keyboard.cpp - SPI conf mode: {0}" , spi_config->mode);
96  spdlog::debug("keyboard.cpp - SPI conf bits_p_w: {0}" , spi_config->bits_per_word);
97  spdlog::debug("keyboard.cpp - SPI conf speed: {0}" , spi_config->speed);
98  spdlog::debug("keyboard.cpp - SPI conf delay: {0}" , spi_config->delay);
99 
100  my_spi = std::unique_ptr<SPI>(new SPI(device, spi_config.get()));
101 
102  if (!my_spi->begin()) {
103  spdlog::critical("keyboard.cpp - Failed to start SPI communication for keyboard");
104  return 1;
105  }
106 
107  spdlog::info("keyboard.cpp - Successfully initialized SPI keyboard");
108  return 0;
109  }
std::unique_ptr< SPI > my_spi
Definition: keyboard.cpp:35
std::unique_ptr< spi_config_t > spi_config
Definition: keyboard.cpp:34

◆ init_from_conf()

int keyboard::init_from_conf ( )

Initializes my_spi with config loaded from config file into app_workspace. Starts SPI.

Returns
int: 0 on success, other values on error

Definition at line 116 of file keyboard.cpp.

116  {
117  app_workspace_ns::spi_config *config = &(app_workspace::get_instance()->main_config->keyb_conf);
118  spdlog::info("keyboard.cpp - Initializing SPI keyboard with config (enable debug to print config)");
119  spdlog::debug("keyboard.cpp - SPI conf dev: {0}" , config->dev);
120  spdlog::debug("keyboard.cpp - SPI conf mode: {0}" , config->config->mode);
121  spdlog::debug("keyboard.cpp - SPI conf bits_p_w: {0}", config->config->bits_per_word);
122  spdlog::debug("keyboard.cpp - SPI conf speed: {0}" , config->config->speed);
123  spdlog::debug("keyboard.cpp - SPI conf delay: {0}" , config->config->delay);
124 
125  my_spi = std::unique_ptr<SPI>(new SPI(config->dev.c_str(), config->config.get()));
126 
127  if (!my_spi->begin()) {
128  spdlog::critical("keyboard.cpp - Failed to start SPI communication for keyboard");
129  return 1;
130  }
131 
132  spdlog::info("keyboard.cpp - Successfully initialized SPI keyboard");
133  return 0;
134  }
static std::unique_ptr< app_workspace > & get_instance()
Get the instance app_workspace which is a singleton.
Structure holding SPI device and SPI config which is a library structure "spi_config_t".
std::unique_ptr< spi_config_t > config

◆ poll_event()

kb_event * keyboard::poll_event ( )

Polls event from queue into param event Returns 1 on success because it is inteded to return "true" on successfull event pop.

Parameters
event
Returns
int: 0 on error, 1 on success

Definition at line 58 of file keyboard.cpp.

58  {
59  if (event_queue.size() <= 0)
60  return NULL;
61 
62  std::lock_guard<std::mutex> eq_guard(eq_mutex);
63 
64  kb_event* res = &event_queue.front();
65  event_queue.pop();
66 
67  return res;
68  }
std::mutex eq_mutex
Definition: keyboard.cpp:25
Structure of SPI keyboard event, Contains pressed scancode, flags and timestamp of event creation.
Definition: keyboard.h:23

◆ push_event()

void keyboard::push_event ( uint16_t  scancode,
uint8_t  flags 
)

Creates and pushes event into event_queue.

Parameters
scancodeone value keycode
downboolean - true if key is being held down, false (= up) on release of the key

Definition at line 252 of file keyboard.cpp.

252  {
253  std::lock_guard<std::mutex> eq_guard(eq_mutex);
254 
255  kb_event event;
256  event.scancode = scancode;
257  event.flags = flags;
258  gettimeofday(&event.timestamp, NULL);
259  event_queue.push(event);
260  }
struct timeval timestamp
Definition: keyboard.h:26
uint16_t scancode
Definition: keyboard.h:24

◆ set_kb_testing_inner()

void keyboard::set_kb_testing_inner ( bool  val)

Sets the kb_testing flag value

Definition at line 222 of file keyboard.cpp.

222  {
223  std::lock_guard<std::mutex> kb_guard(test_mtx);
224  kb_testing = val;
225  }

◆ start_capturing_events()

void keyboard::start_capturing_events ( )

Infinite loop that reads SPI keyboard. Runs in it's own thread!

Definition at line 140 of file keyboard.cpp.

140  {
141  // need 4 bytes to correctly read key code (aka scan code)
142  // 1st byte always == 00 (or ff) - chipselect, need 4th byte to correctly read the bytes inbetween
143  uint8_t rx_buffer[4] = {0};
144  uint8_t event_flags = 0;
145  std::mutex tst_mtx;
146  uint16_t prev_scancode = 0, cur_scancode = 0;
147  std::chrono::time_point<std::chrono::high_resolution_clock> last_read;
148  //struct timeval lp_time, cp_time; // lp = last_press, cp = current_press
149 
150  spdlog::info("keyboard.cpp - Starting event capturing.");
151 
152  while (capturing_events) {
153  prev_scancode = cur_scancode;
154 
155  event_flags = 0;
156  memset(rx_buffer, 0, 4);
157  my_spi->read(rx_buffer, 4);
158 
159  cur_scancode = buffer_to_keycode(rx_buffer);
160 
161  if (prev_scancode != 0x0000 || cur_scancode != 0x0000) {
162  if (cur_scancode != 0x0000)
163  event_flags |= KB_FLAGS_KEY_DOWN;
164  if (cur_scancode == prev_scancode)
165  event_flags |= KB_FLAGS_REPEATING;
166  if (get_kb_testing_inner()) {
167  std::chrono::time_point<std::chrono::high_resolution_clock> now =
168  std::chrono::high_resolution_clock::now();
169  unsigned long us_diff =
170  std::chrono::duration_cast<std::chrono::microseconds>(now - last_read).count();
171  unsigned long ms_diff = us_diff / 1000;
172  last_read = now;
173 
174  tst_mtx.lock();
175  app_workspace::get_instance()->kb_delay_us = us_diff;
176  app_workspace::get_instance()->kb_delay_ms = ms_diff;
177  tst_mtx.unlock();
178 
179  spdlog::info("event_keyboard.cpp - keyboard delay test: {0} ms ({1} us)", ms_diff, us_diff);
180 
182  spdlog::warn("event_keyboard.cpp - avarage delay over {0} samples is: {1} ms ({2} us)",
185  responses_passed = 0;
186  responses_sum = 0;
187  }
188 
190  responses_sum += us_diff;
191 
192  event_flags |= KB_FLAGS_TEST;
193  }
194 
195  if (cur_scancode == 0x0000) // if current_scancode is 0, send prev event as KEY UP
196  push_event(prev_scancode, event_flags);
197  else
198  push_event(cur_scancode, event_flags);
199  }
200 
201  usleep(READ_INTERVAL); // sleep between reads
202  }
203  }
#define READ_INTERVAL
Definition: keyboard.cpp:15
#define RESPONSES_AVG_CNT
Definition: keyboard.cpp:16
@ KB_FLAGS_REPEATING
Definition: keyboard.h:14
@ KB_FLAGS_TEST
Definition: keyboard.h:15
@ KB_FLAGS_KEY_DOWN
Definition: keyboard.h:13
void push_event(uint16_t scancode, uint8_t flags)
Creates and pushes event into event_queue.
Definition: keyboard.cpp:252
uint16_t buffer_to_keycode(const uint8_t *rx_buffer)
Concats keycode from rx_buffer into one (uint16_t) variable. rx_buffer is 4 bytes (this is assumed to...
Definition: keyboard.cpp:239
int responses_passed
Definition: keyboard.cpp:32
bool get_kb_testing_inner()
Definition: keyboard.cpp:216
unsigned long responses_sum
Definition: keyboard.cpp:31

Variable Documentation

◆ capturing_events

bool keyboard::capturing_events = true

Definition at line 36 of file keyboard.cpp.

◆ eq_mutex

std::mutex keyboard::eq_mutex

Definition at line 25 of file keyboard.cpp.

◆ event_queue

std::queue<kb_event> keyboard::event_queue

Definition at line 24 of file keyboard.cpp.

◆ kb_testing

bool keyboard::kb_testing = false

Definition at line 29 of file keyboard.cpp.

◆ my_spi

std::unique_ptr<SPI> keyboard::my_spi = nullptr

Definition at line 35 of file keyboard.cpp.

◆ responses_passed

int keyboard::responses_passed = 0

Definition at line 32 of file keyboard.cpp.

◆ responses_sum

unsigned long keyboard::responses_sum = 0

Definition at line 31 of file keyboard.cpp.

◆ spi_config

std::unique_ptr<spi_config_t> keyboard::spi_config

Definition at line 34 of file keyboard.cpp.

◆ test_mtx

std::mutex keyboard::test_mtx

Definition at line 30 of file keyboard.cpp.