COSA
An Object-Oriented Platform for Arduino Programming
TWI.hh
Go to the documentation of this file.
1 
21 #ifndef COSA_USI_TWI_HH
22 #define COSA_USI_TWI_HH
23 
24 #include "Cosa/Types.h"
25 #if defined(BOARD_ATTINY)
26 #include "Cosa/IOPin.hh"
27 #include "Cosa/Event.hh"
28 #include "Cosa/Power.hh"
37 class TWI {
38 public:
43  class Driver {
44  public:
49  Driver(uint8_t addr) :
50  m_addr(addr << 1),
51  m_async(false)
52  {}
53 
57  bool is_async() const
58  {
59  return (m_async);
60  }
61 
65  void sync_request()
66  {
67  m_async = false;
68  }
69 
73  void async_request()
74  {
75  m_async = true;
76  }
77 
85  virtual void on_completion(uint8_t type, int count)
86  {
87  UNUSED(type);
88  UNUSED(count);
89  }
90 
91  protected:
93  uint8_t m_addr;
94 
96  bool m_async;
97 
99  friend class TWI;
100  friend void ::USI_START_vect(void);
101  friend void ::USI_OVF_vect(void);
102  };
103 
109  class Slave : public Driver, public Event::Handler {
110  public:
115  Slave(uint8_t addr) : TWI::Driver(addr), Event::Handler() {}
116 
123  void read_buf(void* buf, size_t size);
124 
131  void write_buf(void* buf, size_t size);
132 
136  void begin();
137 
145  virtual void on_completion(uint8_t type, int count)
146  {
147  Event::push(type, this, count);
148  }
149 
160  virtual void on_request(void* buf, size_t size) = 0;
161 
162  protected:
171  virtual void on_event(uint8_t type, uint16_t value);
172 
174  friend void ::USI_START_vect(void);
175  friend void ::USI_OVF_vect(void);
176  };
177 
182  TWI();
183 
188  void acquire(TWI::Driver* dev);
189 
194  void release();
195 
203  int write(void* buf, size_t size);
204 
213  int write(uint8_t header, void* buf = 0, size_t size = 0);
214 
223  int write(uint16_t header, void* buf = 0, size_t size = 0);
224 
232  int read(void* buf, size_t size);
233 
238  void set_freq(uint32_t hz)
239  {
240  UNUSED(hz);
241  }
242 
246  void powerup()
247  {
248  power_usi_enable();
249  }
250 
254  void powerdown()
255  {
256  power_usi_disable();
257  }
258 
259 private:
263  enum State {
264  // Idle, waiting for start condition
265  IDLE,
266  // Check start condition
267  START_CHECK,
268  // Slave transmission states (Master read operation)
269  READ_REQUEST,
270  READ_COMPLETED,
271  ACK_CHECK,
272  // Slave receiver states (Master write operation)
273  WRITE_REQUEST,
274  WRITE_COMPLETED,
275  // Slave service state (Response to write)
276  SERVICE_REQUEST
277  } __attribute__((packed));
278 
282  enum {
283  WRITE_OP = 0x00,
284  READ_OP = 0x01,
285  ADDR_MASK = 0xfe
286  } __attribute__((packed));
287 
291  enum {
292  // Clear all interrupt flags
293  SR_CLEAR_ALL = _BV(USISIF) | _BV(USIOIF) | _BV(USIPF) | _BV(USIDC),
294  // Clear all flags, except Start Condition.
295  SR_CLEAR = _BV(USIOIF) | _BV(USIPF) | _BV(USIDC),
296  // Clear flags. Set USI counter to shift 1 bit (2 edges)
297  SR_CLEAR_ACK = SR_CLEAR | (0x0E << USICNT0),
298  // Clear flags. Set USI counter to shift 8 bits (16 edges)
299  SR_CLEAR_DATA = SR_CLEAR | (0x0 << USICNT0),
300  // Set USI TWI mode(0). External clock source
301  CR_SERVICE_MODE = _BV(USIWM1) | _BV(USICS1),
302  // Enable start condition. Set USI TWI mode(0). External clock source
303  CR_START_MODE = _BV(USISIE) | _BV(USIWM1) | _BV(USICS1),
304  // Enable start and overflow. Set USI TWI mode(1). External clock
305  CR_TRANSFER_MODE = _BV(USISIE) | _BV(USIOIE) | _BV(USIWM1) | _BV(USIWM0)
306  | _BV(USICS1),
307  // Master initialization. Software clock strobe
308  CR_INIT_MODE = _BV(USIWM1) | _BV(USICS1) | _BV(USICLK),
309  // Master data transfer. Software clock strobe
310  CR_DATA_MODE = _BV(USIWM1) | _BV(USICS1) | _BV(USICLK) | _BV(USITC)
311  } __attribute__((packed));
312 
316  static const uint8_t HEADER_MAX = 4;
317  static const uint8_t VEC_MAX = 4;
318  static const uint8_t WRITE_IX = 0;
319  static const uint8_t READ_IX = 1;
320  uint8_t m_header[HEADER_MAX];
321  iovec_t m_vec[VEC_MAX];
322  IOPin m_sda;
323  IOPin m_scl;
324  volatile State m_state;
325  volatile uint8_t* m_next;
326  volatile uint8_t* m_last;
327  volatile int m_count;
328  Driver* m_dev;
329  volatile bool m_busy;
330 
335  State state() const
336  {
337  return (m_state);
338  }
339 
344  void state(State state)
345  {
346  m_state = state;
347  }
348 
353  void mode(IOPin::Mode mode)
354  {
355  m_sda.mode(mode);
356  if (mode == IOPin::INPUT_MODE) m_sda.set();
357  }
358 
363  void buf(uint8_t ix)
364  {
365  if (ix > VEC_MAX) return;
366  m_next = (uint8_t*) m_vec[ix].buf;
367  m_last = m_next + m_vec[ix].size;
368  m_count = 0;
369  }
370 
375  uint8_t available()
376  {
377  return (m_last - m_next);
378  }
379 
386  bool put(uint8_t data)
387  {
388  *m_next++ = data;
389  m_count += 1;
390  return (m_next < m_last);
391  }
392 
399  bool get(uint8_t& data)
400  {
401  if (m_next == m_last) return (false);
402  data = *m_next++;
403  m_count += 1;
404  return (true);
405  }
406 
412  bool start();
413 
420  uint8_t transfer(uint8_t data, uint8_t bits = CHARBITS);
421 
427  bool stop();
428 
436  int request(uint8_t op);
437 
439  friend void ::USI_START_vect(void);
440  friend void ::USI_OVF_vect(void);
441 };
442 #endif
443 #endif
Definition: TWI.hh:51
void powerdown()
Definition: TWI.hh:362
void async_request()
Definition: TWI.hh:94
void USI_START_vect(void)
void mode(Mode mode)
Definition: IOPin.hh:56
void set_freq(uint32_t hz)
Definition: TWI.hh:345
void set() const
Definition: OutputPin.hh:85
Definition: Types.h:391
bool m_async
Definition: TWI.hh:117
void release()
Definition: TWI.cpp:58
bool is_async() const
Definition: TWI.hh:78
#define CHARBITS
Definition: Types.h:57
uint8_t m_addr
Definition: TWI.hh:114
size_t size
Size of buffer in bytes.
Definition: Types.h:393
void USI_OVF_vect(void)
int read(void *buf, size_t size)
Definition: TWI.hh:326
int write(void *buf, size_t size)
Definition: TWI.hh:282
#define UNUSED(x)
Definition: ATmega328P.hh:31
Driver(uint8_t addr)
Definition: TWI.hh:70
Definition: IOPin.hh:29
Mode
Definition: IOPin.hh:31
void acquire(TWI::Driver *dev)
Definition: TWI.cpp:36
void powerup()
Definition: TWI.hh:354
Definition: Event.hh:39
virtual void on_completion(uint8_t type, int count)
Definition: TWI.hh:106
void sync_request()
Definition: TWI.hh:86
friend class TWI
Definition: TWI.hh:120
static bool push(uint8_t type, Handler *target, uint16_t value=0)
Definition: Event.hh:180