Arduino-SPI
Serial Peripheral Interface (SPI) library for Arduino
SPI.h
Go to the documentation of this file.
1 
19 #ifndef HARDWARE_AVR_SPI_H
20 #define HARDWARE_AVR_SPI_H
21 
22 #include "GPIO.h"
23 #include "SPI.h"
24 
28 namespace Hardware {
29 
30 #if defined(SPDR)
31 class SPI : public ::SPI {
32 public:
36  SPI() :
37  ::SPI()
38  {
39  m_ss.output();
40  m_sck.output();
41  m_mosi.output();
42  m_miso.input();
43  }
44 
51  virtual uint8_t prescale(uint32_t frequency)
52  {
53  uint16_t scale = F_CPU / frequency;
54  if (scale <= 2) return (0b100);
55  if (scale <= 4) return (0b000);
56  if (scale <= 8) return (0b101);
57  if (scale <= 16) return (0b001);
58  if (scale <= 32) return (0b110);
59  if (scale <= 64) return (0b111);
60  return (0b011);
61  }
62 
70  virtual void acquire(uint8_t mode, uint8_t bitorder, uint8_t prescale)
71  {
72  // Wait for bus manager to be released
73  lock();
74 
75  // Set control registers: mode, bitorder and clock
76  SPCR = _BV(SPE)
77  | _BV(MSTR)
78  | (bitorder == LSBFIRST ? _BV(DORD) : 0)
79  | ((mode & 0x03) << CPHA)
80  | (prescale & 0x03);
81  SPSR = ((prescale >> 2) & 0x01);
82  }
83 
90  virtual uint8_t transfer(uint8_t value)
91  __attribute__((always_inline))
92  {
93  SPDR = value;
94  __asm__ __volatile__("nop" ::: "memory");
95  loop_until_bit_is_set(SPSR, SPIF);
96  return (SPDR);
97  }
98 
107  virtual void transfer(void* dest, const void* src, size_t count)
108  {
109  if (count == 0 || dest == NULL || src == NULL) return;
110  const uint8_t* sp = (const uint8_t*) src;
111  uint8_t* dp = (uint8_t*) dest;
112  uint8_t value = *sp++;
113  SPDR = value;
114  while (--count) {
115  value = *sp++;
116  __asm__ __volatile__("" ::: "memory");
117  loop_until_bit_is_set(SPSR, SPIF);
118  SPDR = value;
119  __asm__ __volatile__("" ::: "memory");
120  *dp++ = SPDR;
121  }
122  loop_until_bit_is_set(SPSR, SPIF);
123  *dp = SPDR;
124  }
125 
132  virtual void read(void* buf, size_t count)
133  {
134  if (count == 0 || buf == NULL) return;
135  uint8_t* bp = (uint8_t*) buf;
136  SPDR = 0;
137  while (--count) {
138  __asm__ __volatile__("nop" ::: "memory");
139  loop_until_bit_is_set(SPSR, SPIF);
140  SPDR = 0;
141  __asm__ __volatile__("" ::: "memory");
142  *bp++ = SPDR;
143  }
144  loop_until_bit_is_set(SPSR, SPIF);
145  *bp = SPDR;
146  }
147 
154  virtual void write(const void* buf, size_t count)
155  {
156  if (count == 0 || buf == NULL) return;
157  uint8_t* bp = (uint8_t*) buf;
158  uint8_t value = *bp++;
159  SPDR = value;
160  while (--count) {
161  value = *bp++;
162  __asm__ __volatile__("" ::: "memory");
163  loop_until_bit_is_set(SPSR, SPIF);
164  SPDR = value;
165  __asm__ __volatile__("" ::: "memory");
166  }
167  loop_until_bit_is_set(SPSR, SPIF);
168  }
169 
170 protected:
172  GPIO<BOARD::SS> m_ss;
173 
175  GPIO<BOARD::SCK> m_sck;
176 
178  GPIO<BOARD::MOSI> m_mosi;
179 
181  GPIO<BOARD::MISO> m_miso;
182 };
183 
184 #elif defined(USIDR)
185 
186 class SPI : public ::SPI {
187 public:
191  SPI() :
192  ::SPI()
193  {
194  m_ss.output();
195  m_sck.output();
196  m_mosi.output();
197  m_miso.input();
198  }
199 
207  virtual void acquire(uint8_t mode, uint8_t bitorder, uint8_t prescale)
208  {
209  // Wait for bus manager to be released
210  lock();
211 
212  // Not used: only MSBFIRST bitorder and max frequency
213  (void) bitorder;
214  (void) prescale;
215 
216  // Set clock polarity
217  m_sck.write(mode & 0x02);
218 
219  // Cache clocking command
220  m_usicr = (_BV(USIWM0) | _BV(USICS1) | _BV(USICLK) | _BV(USITC));
221  if (mode == 1 || mode == 2) m_usicr |= _BV(USICS0);
222  }
223 
230  virtual uint8_t transfer(uint8_t value)
231  {
232  USIDR = value;
233  USISR = _BV(USIOIF);
234  register uint8_t cntl = m_usicr;
235  do {
236  USICR = cntl;
237  } while ((USISR & _BV(USIOIF)) == 0);
238  return (USIDR);
239  }
240 
241 protected:
243  GPIO<BOARD::SS> m_ss;
244 
246  GPIO<BOARD::SCK> m_sck;
247 
249  GPIO<BOARD::MOSI> m_mosi;
250 
252  GPIO<BOARD::MISO> m_miso;
253 
255  uint8_t m_usicr;
256 };
257 #endif
258 
259 };
260 #endif
virtual void acquire(uint8_t mode, uint8_t bitorder, uint8_t prescale)
Definition: SPI.h:70
Definition: SPI.h:28
virtual void transfer(void *dest, const void *src, size_t count)
Definition: SPI.h:107
virtual uint8_t transfer(uint8_t value)
Definition: SPI.h:90
virtual uint8_t prescale(uint32_t frequency)
Definition: SPI.h:51
void lock()
Definition: SPI.h:252
virtual void write(const void *buf, size_t count)
Definition: SPI.h:154
GPIO< BOARD::SCK > m_sck
Definition: SPI.h:175
virtual void read(void *buf, size_t count)
Definition: SPI.h:132
GPIO< BOARD::MOSI > m_mosi
Definition: SPI.h:178
GPIO< BOARD::SS > m_ss
Definition: SPI.h:172
GPIO< BOARD::MISO > m_miso
Definition: SPI.h:181