COSA
An Object-Oriented Platform for Arduino Programming
SOFT_SPI.cpp
Go to the documentation of this file.
1 
21 #include "Cosa/Soft/SPI.hh"
22 
23 using namespace Soft;
24 
26  Pulse pulse,
27  Clock clock,
28  uint8_t mode,
29  Order order,
30  Interrupt::Handler* irq) :
31  m_irq(irq),
32  m_cs(cs, (pulse == 0)),
33  m_pulse(pulse),
34  m_mode(mode),
35  m_order(order)
36 {
37  UNUSED(clock);
38  m_next = spi.m_list;
39  spi.m_list = this;
40 }
41 
42 void
44 {
45  // Acquire the device driver. Wait if busy. Synchronized update
46  uint8_t key = lock();
47  while (UNLIKELY(m_busy)) {
48  unlock(key);
49  yield();
50  key = lock();
51  }
52  // Set current device and mark as busy
53  m_busy = true;
54  m_dev = dev;
55  // Set clock polarity
56  m_sck.write(dev->m_mode & 0x02);
57  // Disable all interrupt sources on SPI bus
58  for (SPI::Driver* dev = m_list; dev != NULL; dev = dev->m_next)
59  if (dev->m_irq != NULL) dev->m_irq->disable();
60  unlock(key);
61 }
62 
63 void
65 {
66  // Lock the device driver update
67  uint8_t key = lock();
68  // Release the device driver
69  m_busy = false;
70  m_dev = NULL;
71  // Enable all interrupt sources on SPI bus
72  for (SPI::Driver* dev = m_list; dev != NULL; dev = dev->m_next)
73  if (dev->m_irq != NULL) dev->m_irq->enable();
74  unlock(key);
75 }
76 
77 bool
79 {
80  if (dev->m_next != NULL) return (false);
81  dev->m_next = m_list;
82  m_list = dev;
83  return (true);
84 }
85 
86 uint8_t
87 SPI::transfer(uint8_t value)
88 {
89  uint8_t bits = CHARBITS;
90  if (m_dev->m_order == MSB_ORDER) {
91  synchronized do {
92  m_mosi._write(value & 0x80);
93  m_sck._toggle();
94  value <<= 1;
95  if (m_miso.is_set()) value |= 0x01;
96  m_sck._toggle();
97  } while (--bits);
98  }
99  else {
100  synchronized do {
101  m_mosi._write(value & 0x01);
102  m_sck._toggle();
103  value >>= 1;
104  if (m_miso.is_set()) value |= 0x80;
105  m_sck._toggle();
106  } while (--bits);
107  }
108  return (value);
109 }
110 
Order
Definition: SPI.hh:72
Definition: Clock.hh:33
void acquire(Driver *dev)
Definition: SPI.cpp:255
Driver(Board::DigitalPin cs, Pulse pulse=DEFAULT_PULSE, Clock clock=DEFAULT_CLOCK, uint8_t mode=0, Order order=MSB_ORDER, Interrupt::Handler *irq=NULL)
Pulse
Definition: SPI.hh:79
#define NULL
Definition: Types.h:101
Definition: SPI.hh:32
Driver * m_next
List of drivers.
Definition: SPI.hh:164
virtual void disable()
Definition: Interrupt.hh:53
void release()
Definition: SPI.cpp:281
uint8_t lock()
Definition: Types.h:319
bool attach(Driver *dev)
Definition: SPI.cpp:246
#define CHARBITS
Definition: Types.h:57
uint8_t transfer(uint8_t data)
Definition: SPI.hh:326
void(* yield)()
#define UNUSED(x)
Definition: ATmega328P.hh:31
uint8_t m_mode
Mode for phase and transition.
Definition: SPI.hh:148
void unlock(uint8_t key)
Definition: Types.h:331
Driver * m_next
List of drivers.
Definition: SPI.hh:144
SPI spi
Definition: SPI.cpp:29
Most significant bit first.
Definition: SPI.hh:73
Interrupt::Handler * m_irq
Interrupt handler.
Definition: SPI.hh:145
#define UNLIKELY(x)
Definition: Types.h:153