eBoard ①⑧⑨
Written for SIA 2017/2018
eagle_TwoWire.h
Go to the documentation of this file.
1 #ifndef EAGLE_EBOARD_HELPLIB_TWOWIRE
2  #define EAGLE_EBOARD_HELPLIB_TWOWIRE
3 
12 //=====================================================================================================================================================
13 // TwoWire
14 //=====================================================================================================================================================
15 
16  #include <inttypes.h>
17  #include "Stream.h"
18 
19  #define BUFFER_LENGTH 32
20  namespace eagle_impl {
21 
22  //-------------------------------------------------------------------------------------------------------------------------------------------------
23  // class
24  //-------------------------------------------------------------------------------------------------------------------------------------------------
25 
42  class TwoWire : public Stream {
43  private:
45  static uint8_t rxBuffer[];
47  static uint8_t rxBufferIndex;
49  static uint8_t rxBufferLength;
50 
52  static uint8_t txAddress;
54  static uint8_t txBuffer[];
56  static uint8_t txBufferIndex;
58  static uint8_t txBufferLength;
59 
61  static uint8_t transmitting;
63  static void (*user_onRequest)(void);
68  static void (*user_onReceive)(int numBytes);
70  static void onRequestService(void);
76  static void onReceiveService(uint8_t* inBytes, int numBytes);
77 
78  public:
80  TwoWire();
82  void begin();
87  void begin(uint8_t address);
93  void begin(int address);
98  void beginTransmission(uint8_t address);
104  void beginTransmission(int address);
115  uint8_t endTransmission(void);
126  uint8_t endTransmission(uint8_t sendStop);
134  uint8_t requestFrom(uint8_t address, uint8_t quantity);
142  uint8_t requestFrom(uint8_t address , uint8_t quantity, uint8_t sendStop);
150  uint8_t requestFrom(int address, int quantity);
159  uint8_t requestFrom(int address, int quantity, int sendStop);
168  virtual size_t write(uint8_t data);
176  virtual size_t write(const uint8_t *data, size_t quantity);
181  virtual int available(void);
187  virtual int read(void);
193  virtual int peek(void);
200  void onReceive( void (*function)(int) );
207  void onRequest( void (*function)(void) );
208 
209  /* Removed due to: not needed
210  inline size_t write(unsigned long n) { return write((uint8_t)n); }
211  inline size_t write(long n) { return write((uint8_t)n); }
212  inline size_t write(unsigned int n) { return write((uint8_t)n); }
213  inline size_t write(int n) { return write((uint8_t)n); }
214  */
215  using Print::write;
216  };
217  }
218  extern "C" {
219  #include <stdlib.h>
220  #include <string.h>
221  #include <inttypes.h>
222  //#include "twi.h"
223  }
224 
226 
227  //-------------------------------------------------------------------------------------------------------------------------------------------------
228  // definitions
229  //-------------------------------------------------------------------------------------------------------------------------------------------------
230 
231  extern TwoWire Wire;
232  uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
233  uint8_t TwoWire::rxBufferIndex = 0;
234  uint8_t TwoWire::rxBufferLength = 0;
235 
236  uint8_t TwoWire::txAddress = 0;
237  uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
238  uint8_t TwoWire::txBufferIndex = 0;
239  uint8_t TwoWire::txBufferLength = 0;
240 
241  uint8_t TwoWire::transmitting = 0;
242  void (*TwoWire::user_onRequest)(void);
243  void (*TwoWire::user_onReceive)(int);
244 
245  TwoWire::TwoWire() {}
246 
247  void TwoWire::begin(void) {
248  rxBufferIndex = 0;
249  rxBufferLength = 0;
250 
251  txBufferIndex = 0;
252  txBufferLength = 0;
253 
254  twi_init();
255  }
256 
257  void TwoWire::begin(uint8_t address) {
258  twi_setAddress(address);
259  twi_attachSlaveTxEvent(onRequestService);
260  twi_attachSlaveRxEvent(onReceiveService);
261  begin();
262  }
263 
264  void TwoWire::begin(int address) {
265  begin((uint8_t)address);
266  }
267 
268  uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
269  if(quantity > BUFFER_LENGTH){
270  quantity = BUFFER_LENGTH;
271  }
272  uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
273  rxBufferIndex = 0;
274  rxBufferLength = read;
275 
276  return read;
277  }
278 
279  uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) {
280  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
281  }
282 
283  uint8_t TwoWire::requestFrom(int address, int quantity) {
284  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
285  }
286 
287  uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) {
288  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
289  }
290 
291  void TwoWire::beginTransmission(uint8_t address) {
292  transmitting = 1;
293  txAddress = address;
294  txBufferIndex = 0;
295  txBufferLength = 0;
296  }
297 
298  void TwoWire::beginTransmission(int address) {
299  beginTransmission((uint8_t)address);
300  }
301 
302  uint8_t TwoWire::endTransmission(uint8_t sendStop) {
303  int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
304  txBufferIndex = 0;
305  txBufferLength = 0;
306  transmitting = 0;
307  return ret;
308  }
309 
310  uint8_t TwoWire::endTransmission(void){
311  return endTransmission(true);
312  }
313 
314  size_t TwoWire::write(uint8_t data) {
315  if(transmitting) {
316  if(txBufferLength >= BUFFER_LENGTH) {
317  setWriteError();
318  return 0;
319  }
320  txBuffer[txBufferIndex] = data;
321  ++txBufferIndex;
322  txBufferLength = txBufferIndex;
323  }else{
324  twi_transmit(&data, 1);
325  }
326  return 1;
327  }
328 
329  size_t TwoWire::write(const uint8_t *data, size_t quantity) {
330  if(transmitting){
331  for(size_t i = 0; i < quantity; ++i) {
332  write(data[i]);
333  }
334  }else{
335  twi_transmit(data, quantity);
336  }
337  return quantity;
338  }
339 
340  int TwoWire::available(void) {
341  return rxBufferLength - rxBufferIndex;
342  }
343 
344  int TwoWire::read(void) {
345  int8_t value = -1;
346 
347  if(rxBufferIndex < rxBufferLength) {
348  value = rxBuffer[rxBufferIndex];
349  ++rxBufferIndex;
350  }
351 
352  return value;
353  }
354 
355  int TwoWire::peek(void) {
356  int value = -1;
357 
358  if(rxBufferIndex < rxBufferLength) {
359  value = rxBuffer[rxBufferIndex];
360  }
361 
362  return value;
363  }
364 
365  void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) {
366  if(!user_onReceive){
367  return;
368  }
369 
370  if(rxBufferIndex < rxBufferLength) {
371  return;
372  }
373 
374  for(uint8_t i = 0; i < numBytes; ++i) {
375  rxBuffer[i] = inBytes[i];
376  }
377  rxBufferIndex = 0;
378  rxBufferLength = numBytes;
379  user_onReceive(numBytes);
380  }
381 
382  void TwoWire::onRequestService(void) {
383  if(!user_onRequest) return;
384 
385  txBufferIndex = 0;
386  txBufferLength = 0;
387  user_onRequest();
388  }
389 
390  void TwoWire::onReceive( void (*function)(int) ) {
391  user_onReceive = function;
392  }
393 
394  void TwoWire::onRequest( void (*function)(void) ) {
395  user_onRequest = function;
396  }
397 
400 
401  TwoWire Wire = TwoWire();
402 
403  #define TwoWire_h
404 
406 
407 #endif
void onRequest(void(*function)(void))
this will set the user_onRequest method
virtual size_t write(uint8_t data)
this will write a single unsigned 8-bit value to address
static void(* user_onReceive)(int numBytes)
twi slave [Rx]receive-event user def handler
Definition: eagle_TwoWire.h:68
void twi_setAddress(uint8_t)
static uint8_t rxBufferIndex
this defines the rxBuffer Index - current position in rxBuffer array
Definition: eagle_TwoWire.h:47
static uint8_t txBufferIndex
this defines the txBuffer Index - current position in txBuffer array
Definition: eagle_TwoWire.h:56
static void onRequestService(void)
twi slave [Tx]transmitting-event handler
[I2C] This is used to avoid path resolving issues and defines the common known Arduino Wire-Interface...
Definition: eagle_TwoWire.h:42
static uint8_t transmitting
&#39;boolean&#39; value. Set to 1 if transmitting => in master write mode
Definition: eagle_TwoWire.h:61
uint8_t twi_transmit(const uint8_t *, uint8_t)
uint8_t twi_readFrom(uint8_t, uint8_t *, uint8_t, uint8_t)
static uint8_t rxBufferLength
this defines the length of rxBuffer
Definition: eagle_TwoWire.h:49
static uint8_t txAddress
this defines the txAddress the transmitting Dta
Definition: eagle_TwoWire.h:52
static uint8_t txBuffer[]
this defines the txBuffer used to enable delayed read
Definition: eagle_TwoWire.h:54
this namespace contains all the don&#39;t use manually classes ;)
#define BUFFER_LENGTH
Definition: eagle_TwoWire.h:19
virtual int read(void)
this will read a single byte from rxBuffer and increment the Index
uint8_t twi_writeTo(uint8_t, uint8_t *, uint8_t, uint8_t, uint8_t)
uint8_t requestFrom(uint8_t address, uint8_t quantity)
this will read a specific quantity of bytes from a specific address
static void onReceiveService(uint8_t *inBytes, int numBytes)
twi slave [Rx]receive-event handler
void begin()
begin the TwoWire communcation without any data set
TwoWire()
The constructor of the TwoWire class.
void beginTransmission(uint8_t address)
this will start a new transmission to a specific address => master mode
virtual int peek(void)
this will read a single byte from rxBuffer without increment the Index
void twi_attachSlaveRxEvent(void(*)(uint8_t *, int))
void onReceive(void(*function)(int))
this will set the user_onReceive method
static uint8_t txBufferLength
this defines the length of txBuffer
Definition: eagle_TwoWire.h:58
TwoWire Wire
this is the well-known Arduino Wire Interface, just a little bit &#39;modified&#39; ;P
void twi_init(void)
uint8_t endTransmission(void)
this will end the transmission and send the STOP-sequence
virtual int available(void)
this will return the amount of rxBuffer left
static void(* user_onRequest)(void)
twi slave [Tx]transmitting-event user def handler
Definition: eagle_TwoWire.h:63
static uint8_t rxBuffer[]
this defines the rxBuffer used to enable delayed read
Definition: eagle_TwoWire.h:45
void twi_attachSlaveTxEvent(void(*)(void))