Embedded C Firmware Library : Arduino / Atmega328p  1
Register Level Embedded C Hardware Abstraction Library for AVR ATmega48A/PA/88A/PA/168A/PA/328/P or Arduino UNO/NANO/MINI
avr_spi.h
Go to the documentation of this file.
1 
33 #ifndef AVR_SPI_H_
34 #define AVR_SPI_H_
35 
36 #include <avr/io.h>
37 #include <avr/interrupt.h>
38 #include "avr_macros.h"
39 #include "avr_utils.h"
40 
41 #pragma message ( "avr_spi.h included" )
42 
47 #define SPI_MODE_MASTER (1<<MSTR)
48 #define SPI_MODE_SLAVE (0<<MSTR)
49 #define SPI_MODE_MASK (1<<MSTR)
56 #define SPI_ENABLE (1<<SPE)
63 #define SPI_PRESCALER_4 (0<<SPR1) | (0<<SPR0)
64 #define SPI_PRESCALER_16 (1<<SPR0)
65 #define SPI_PRESCALER_64 (1<<SPR1)
66 #define SPI_PRESCALER_128 (1<<SPR1) | (1<<SPR0)
67 #define SPI_PRESCALER_MASK (1<<SPR1) | (1<<SPR0)
68 #define SPI_PRESCALER_SPEED_DOUBLE (1<<SPI2X)
69 #define SPI_PRESCALER_SPEED_NORMAL (0<<SPI2X)
70 #define SPI_PRESCALER_SPEED_MASK (1<<SPI2X)
77 #define SPI_DATA_MODE_0 (0<<CPOL) | (0<<CPHA)
78 #define SPI_DATA_MODE_1 (1<<CPHA)
79 #define SPI_DATA_MODE_2 (1<<CPOL)
80 #define SPI_DATA_MODE_3 (1<<CPOL) | (1<<CPHA)
81 #define SPI_DATA_MODE_MASK (1<<CPOL) | (1<<CPHA)
88 #define SPI_DATA_ORDER_LSB_FIRST (1<<DORD)
89 #define SPI_DATA_ORDER_MSB_FIRST (0<<DORD)
90 #define SPI_DATA_ORDER_MASK (1<<DORD)
97 #define SPI_MISO_PIN (1<<4)
98 #define SPI_MOSI_PIN (1<<3)
99 #define SPI_SCK_PIN (1<<5)
100 #define SPI_SS_PIN (1<<2)
101 #define SPI_PORT PORTB
102 #define SPI_DDR DDRB
103 
109 typedef struct SPI_ConfigData
110 {
111  uint8_t MasterSlaveSelect;
112  uint8_t Prescaler;
113  uint8_t DoubleSpeed;
114  uint8_t DataMode;
115  uint8_t DataOrder;
123 void SPI_Init(SPI_ConfigData Data);
124 void SPI_DeInit();
131 uint8_t SPI_ReceiveByte();
132 uint16_t SPI_ReceiveTwoBytes();
133 void SPI_ReceiveBytes(uint8_t *Buffer, uint8_t Size);
140 void SPI_TransmitByte(uint8_t Buffer);
141 void SPI_TransmitTwoBytes(uint16_t Buffer);
142 void SPI_TransmitBytes(uint8_t *Buffer, uint8_t Size);
149 uint8_t SPI_TransReceiveByte(uint8_t Buffer);
150 uint16_t SPI_TransReceiveTwoBytes(uint16_t Buffer);
151 void SPI_TransReceiveBytes(uint8_t *Buffer, uint8_t Size);
169 {
170  /* Configure SPI Pins */
171  if (Data.MasterSlaveSelect == SPI_MODE_MASTER)
172  {
173  SPI_PORT |= SPI_SS_PIN;
174  SPI_DDR |= SPI_SS_PIN;
175 
176  /* Configure SPI HW */
177  SPCR = Data.MasterSlaveSelect | Data.DataOrder | Data.DataMode | SPI_ENABLE | Data.Prescaler; // | SPI_INTERRUPT_ENABLE
178  SPSR = Data.DoubleSpeed;
179 
180  SPI_DDR |= SPI_SCK_PIN;
181  SPI_DDR |= SPI_MOSI_PIN;
182  SPI_DDR &= ~SPI_MISO_PIN;
183  }
184  else if (Data.MasterSlaveSelect == SPI_MODE_SLAVE)
185  {
186  SPI_DDR &= ~SPI_MOSI_PIN;
187  SPI_DDR |= SPI_MISO_PIN;
188  SPI_DDR &= ~SPI_SCK_PIN;
189  SPI_DDR &= ~SPI_SS_PIN;
190 
191  /* Configure SPI HW */
192  SPCR = Data.MasterSlaveSelect | Data.DataOrder | Data.DataMode | SPI_ENABLE | Data.Prescaler; // | SPI_INTERRUPT_ENABLE
193  SPSR = Data.DoubleSpeed;
194  }
195 
196  /* Enable Global Interrupt */
197  sei();
198 
199 }
200 
207 {
208  SPCR = 0x00;
209  SPSR = 0x00;
210 }
211 
218 {
219  uint8_t DataByte;
220  SPI_PORT &= ~(1<<2);
221  SPDR = 0x00;
222  while(!(SPSR & (1<<SPIF)));
223  DataByte = SPDR;
224  SPI_PORT |= (1<<2);
225  return DataByte;
226 }
227 
234 {
235  union
236  {
237  uint16_t val;
238  struct
239  {
240  uint8_t lsb;
241  uint8_t msb;
242  };
243  } out;
244 
245  SPI_PORT &= ~(SPI_SS_PIN);
246  if (!(SPCR & (SPI_DATA_ORDER_LSB_FIRST)))
247  {
248  SPDR = 0x00;
249  asm volatile("nop");
250  while (!(SPSR & (1<<SPIF))) ;
251  out.msb = SPDR;
252  SPDR = 0x00;
253  asm volatile("nop");
254  while (!(SPSR & (1<<SPIF))) ;
255  out.lsb = SPDR;
256  }
257  else
258  {
259  SPDR = 0x00;
260  asm volatile("nop");
261  while (!(SPSR & (1<<SPIF))) ;
262  out.lsb = SPDR;
263  SPDR = 0x00;
264  asm volatile("nop");
265  while (!(SPSR & (1<<SPIF))) ;
266  out.msb = SPDR;
267  }
268  SPI_PORT |= (SPI_SS_PIN);
269  return out.val;
270 }
271 
279 void SPI_ReceiveBytes(uint8_t *Buffer, uint8_t Size)
280 {
281  if (Size == 0) return;
282 
283  SPI_PORT &= ~(SPI_SS_PIN);
284  while (Size-- > 0)
285  {
286  SPDR = 0x00;
287  while (!(SPSR & (1<<SPIF)));
288  *(Buffer++) = SPDR;
289 
290  }
291  SPI_PORT |= (SPI_SS_PIN);
292 }
293 
299 void SPI_TransmitByte(uint8_t Buffer)
300 {
301  SPI_PORT &= ~(1<<2);
302  SPDR = Buffer;
303  asm volatile("nop");
304  while(!(SPSR & (1<<SPIF)));
305  SPI_PORT |= (1<<2);
306 }
307 
313 void SPI_TransmitTwoBytes(uint16_t Buffer)
314 {
315  union
316  {
317  uint16_t val;
318  struct
319  {
320  uint8_t lsb;
321  uint8_t msb;
322  };
323  } in;
324 
325  in.val = Buffer;
326 
327  SPI_PORT &= ~(SPI_SS_PIN);
328  if (!(SPCR & (SPI_DATA_ORDER_LSB_FIRST)))
329  {
330  SPDR = in.msb;
331  asm volatile("nop");
332  while (!(SPSR & (1<<SPIF))) ;
333  SPDR = in.lsb;
334  asm volatile("nop");
335  while (!(SPSR & (1<<SPIF))) ;
336  }
337  else
338  {
339  SPDR = in.lsb;
340  asm volatile("nop");
341  while (!(SPSR & (1<<SPIF))) ;
342  SPDR = in.msb;
343  asm volatile("nop");
344  while (!(SPSR & (1<<SPIF))) ;
345  }
346  SPI_PORT |= (SPI_SS_PIN);
347 }
348 
356 void SPI_TransmitBytes(uint8_t *Buffer, uint8_t Size)
357 {
358  if (Size == 0) return;
359 
360  SPI_PORT &= ~(SPI_SS_PIN);
361  while (Size-- > 0)
362  {
363  SPDR = *(Buffer++);
364  while (!(SPSR & (1<<SPIF)));
365  }
366  SPI_PORT |= (SPI_SS_PIN);
367 }
368 
374 uint8_t SPI_TransReceiveByte(uint8_t Buffer)
375 {
376  uint8_t DataByte;
377  SPI_PORT &= ~(SPI_SS_PIN);
378  SPDR = Buffer;
379  asm volatile("nop");
380  while(!(SPSR & (1<<SPIF)));
381  DataByte = SPDR;
382  SPI_PORT |= (SPI_SS_PIN);
383  return DataByte;
384 }
385 
391 uint16_t SPI_TransReceiveTwoBytes(uint16_t Buffer)
392 {
393  union
394  {
395  uint16_t val;
396  struct
397  {
398  uint8_t lsb;
399  uint8_t msb;
400  };
401  } in, out;
402 
403  in.val = Buffer;
404 
405  SPI_PORT &= ~(SPI_SS_PIN);
406  if (!(SPCR & (SPI_DATA_ORDER_LSB_FIRST)))
407  {
408  SPDR = in.msb;
409  asm volatile("nop");
410  while (!(SPSR & (1<<SPIF))) ;
411  out.msb = SPDR;
412  SPDR = in.lsb;
413  asm volatile("nop");
414  while (!(SPSR & (1<<SPIF))) ;
415  out.lsb = SPDR;
416  }
417  else
418  {
419  SPDR = in.lsb;
420  asm volatile("nop");
421  while (!(SPSR & (1<<SPIF))) ;
422  out.lsb = SPDR;
423  SPDR = in.msb;
424  asm volatile("nop");
425  while (!(SPSR & (1<<SPIF))) ;
426  out.msb = SPDR;
427  }
428  SPI_PORT |= (SPI_SS_PIN);
429  return out.val;
430 }
431 
439 void SPI_TransReceiveBytes(uint8_t *Buffer, uint8_t Size)
440 {
441  if (Size == 0) return;
442 
443  SPI_PORT &= ~(SPI_SS_PIN);
444  while (Size-- > 0)
445  {
446  SPDR = *(Buffer);
447  while (!(SPSR & (1<<SPIF)));
448  *(Buffer++) = SPDR;
449 
450  }
451  SPI_PORT |= (SPI_SS_PIN);
452 }
453 
454 #endif /* AVR_SPI_H_ */
SPI_ReceiveTwoBytes
uint16_t SPI_ReceiveTwoBytes()
Public Function to Receive 2 Bytes / 16 Bits of Data in Polling.
Definition: avr_spi.h:233
SPI_ConfigData
Definition: avr_spi.h:110
SPI_TransReceiveByte
uint8_t SPI_TransReceiveByte(uint8_t Buffer)
Public Function to TransReceive 1 Byte of Data in Polling.
Definition: avr_spi.h:374
SPI_TransmitTwoBytes
void SPI_TransmitTwoBytes(uint16_t Buffer)
Public Function to Transmit 2 Bytes / 16 Bits of Data in Polling.
Definition: avr_spi.h:313
avr_utils.h
Library for Utility Functions.
SPI_Init
void SPI_Init(SPI_ConfigData Data)
Public Function to Configure and Initialize SPI.
Definition: avr_spi.h:168
SPI_DATA_ORDER_LSB_FIRST
#define SPI_DATA_ORDER_LSB_FIRST
Definition: avr_spi.h:88
SPI_ENABLE
#define SPI_ENABLE
Definition: avr_spi.h:56
SPI_TransReceiveBytes
void SPI_TransReceiveBytes(uint8_t *Buffer, uint8_t Size)
Public Function to TransReceive Multiple Bytes of Data in Polling.
Definition: avr_spi.h:439
SPI_ReceiveBytes
void SPI_ReceiveBytes(uint8_t *Buffer, uint8_t Size)
Public Function to Receive Multiple Bytes of Data in Polling.
Definition: avr_spi.h:279
avr_macros.h
Library for all common Macro Definition.
SPI_MODE_MASTER
#define SPI_MODE_MASTER
Definition: avr_spi.h:47
SPI_TransmitBytes
void SPI_TransmitBytes(uint8_t *Buffer, uint8_t Size)
Public Function to Transmit Multiple Bytes of Data in Polling.
Definition: avr_spi.h:356
SPI_TransReceiveTwoBytes
uint16_t SPI_TransReceiveTwoBytes(uint16_t Buffer)
Public Function to TransReceive 2 Byte / 16 Bits of Data in Polling.
Definition: avr_spi.h:391
SPI_TransmitByte
void SPI_TransmitByte(uint8_t Buffer)
Public Function to Transmit 1 Byte of Data in Polling.
Definition: avr_spi.h:299
SPI_DeInit
void SPI_DeInit()
Public Function to De-Initialize SPI.
Definition: avr_spi.h:206
SPI_ReceiveByte
uint8_t SPI_ReceiveByte()
Public Function to Receive 1 Byte of Data in Polling.
Definition: avr_spi.h:217
SPI_MODE_SLAVE
#define SPI_MODE_SLAVE
Definition: avr_spi.h:48