GlobLib
HAL and API libraries for MCUs and hardware.
stm32f103cb_spi.c
Go to the documentation of this file.
1 /*!**************************************************************************
2  @file stm32f103cb_spi.c
3  @brief Source file for stm32f103cb SPI
4  @author Stuart Ianna
5  @version 0.1
6  @date July 2018
7  @copyright GNU GPLv3
8  @warning None
9  @bug
10 
11  @details
12 
13  @par Compilers
14  - arm-none-eabi-gcc (15:4.9.3+svn231177-1) 4.9.3 20150529 (prerelease)
15 ******************************************************************************/
16 
17 #include "stm32f103cb_spi.h"
18 
19 //Used when calculating the serial clock divisor
20 void spi_setSpeed(spi_periph periph, uint16_t divisor);
21 
22 void spi1_put(uint16_t data);
23 void spi2_put(uint16_t data);
24 uint16_t spi1_get(void);
25 uint16_t spi2_get(void);
26 
27 //ISR function pointers
28 static void (*spi1_tx_handler)(void);
29 static void (*spi1_rx_handler)(uint16_t);
30 static void (*spi2_tx_handler)(void);
31 static void (*spi2_rx_handler)(uint16_t);
32 
34 
35  switch(periph){
36 
37  case SPI_1:
38 
39  //SPI clock
40  rcc_periph_clock_enable(RCC_SPI1);
41 
42  //GPIO pins
46 
47  spi_reset(SPI1);
53  spi_enable_software_slave_management(SPI1);
54  spi_set_nss_high(SPI1);
55  spi_set_master_mode(SPI1);
56  spi_enable(SPI1);
57  break;
58 
59  case SPI_2:
60 
61  //SPI clock
62  rcc_periph_clock_enable(RCC_SPI2);
63 
64  //GPIO pins
68 
69  spi_reset(SPI2);
75  spi_enable_software_slave_management(SPI2);
76  spi_set_nss_high(SPI2);
77  spi_set_master_mode(SPI2);
78  spi_enable(SPI2);
79  break;
80 
81  default:
82 
83  if(MCU_debugIsEnabled()){
84 
86  }
87  return E_SPI_PORT;
88  break;
89  }
90 
91  return E_SPI_NOERROR;
92 
93 }
94 mcu_error SPI_enableTxISR(spi_periph periph, void(*handler)(void)){
95 
96  switch(periph){
97 
98  case SPI_1:
99 
100  nvic_disable_irq(NVIC_SPI1_IRQ);
101  spi1_tx_handler = handler;
102  spi_enable_tx_buffer_empty_interrupt(SPI1);
103  nvic_enable_irq(NVIC_SPI1_IRQ);
104  break;
105 
106  case SPI_2:
107 
108  nvic_disable_irq(NVIC_SPI2_IRQ);
109  spi2_tx_handler = handler;
110  spi_enable_tx_buffer_empty_interrupt(SPI2);
111  nvic_enable_irq(NVIC_SPI2_IRQ);
112  break;
113 
114  default:
115 
116  if(MCU_debugIsEnabled()){
117 
119  }
120  return E_SPI_PORT;
121  break;
122  }
123  return E_SPI_NOERROR;
124 }
125 
126 mcu_error SPI_enableRxISR(spi_periph periph, void(*handler)(uint16_t)){
127 
128  switch(periph){
129 
130  case SPI_1:
131 
132  nvic_disable_irq(NVIC_SPI1_IRQ);
133  spi1_rx_handler = handler;
134  spi_enable_rx_buffer_not_empty_interrupt(SPI1);
135  nvic_enable_irq(NVIC_SPI1_IRQ);
136  break;
137 
138  case SPI_2:
139 
140  nvic_disable_irq(NVIC_SPI2_IRQ);
141  spi2_rx_handler = handler;
142  spi_enable_rx_buffer_not_empty_interrupt(SPI2);
143  nvic_enable_irq(NVIC_SPI2_IRQ);
144  break;
145 
146  default:
147 
148  if(MCU_debugIsEnabled()){
149 
151  }
152  return E_SPI_PORT;
153  break;
154  }
155 
156  return E_SPI_NOERROR;
157 }
158 
160 
161  switch(periph){
162 
163  case SPI_1:
164 
165  spi_disable_tx_buffer_empty_interrupt(SPI1);
166 
167  //Disable nvic if no interrupts enabled
168  if(!(SPI_CR2(SPI1) & SPI_CR2_RXNEIE)){
169 
170  nvic_disable_irq(NVIC_SPI1_IRQ);
171  }
172  break;
173 
174  case SPI_2:
175 
176  spi_disable_tx_buffer_empty_interrupt(SPI2);
177 
178  //Disable nvic if no interrupts enabled
179  if(!(SPI_CR2(SPI2) & SPI_CR2_RXNEIE)){
180 
181  nvic_disable_irq(NVIC_SPI2_IRQ);
182  }
183  break;
184 
185  default:
186 
187  if(MCU_debugIsEnabled()){
188 
190  }
191  return E_SPI_PORT;
192  break;
193  }
194 
195  return E_SPI_NOERROR;
196 }
197 
199 
200  switch(periph){
201 
202  case SPI_1:
203 
204  spi_disable_rx_buffer_not_empty_interrupt(SPI1);
205 
206  //Disable nvic if no interrupts enabled
207  if(!(SPI_CR2(SPI1) & SPI_CR2_TXEIE)){
208 
209  nvic_disable_irq(NVIC_SPI1_IRQ);
210  }
211  break;
212 
213  case SPI_2:
214 
215  spi_disable_rx_buffer_not_empty_interrupt(SPI2);
216  //Disable nvic if no interrupts enabled
217  if(!(SPI_CR2(SPI1) & SPI_CR2_TXEIE)){
218 
219  nvic_disable_irq(NVIC_SPI2_IRQ);
220  }
221  break;
222 
223  default:
224 
225  if(MCU_debugIsEnabled()){
226 
228  }
229  return E_SPI_PORT;
230  break;
231  }
232 
233  return E_SPI_NOERROR;
234 }
235 
236 void spi1_isr(void){
237 
238  if(SPI_SR(SPI1) & SPI_SR_TXE){
239 
240  spi1_tx_handler();
241  }
242  if(SPI_SR(SPI1) & SPI_SR_RXNE){
243 
244  spi1_rx_handler(SPI_DR(SPI1));
245  }
246 }
247 
248 void spi2_isr(void){
249 
250  if(SPI_SR(SPI2) & SPI_SR_TXE){
251 
252  spi2_tx_handler();
253  }
254  if(SPI_SR(SPI2) & SPI_SR_RXNE){
255 
256  spi2_rx_handler(SPI_DR(SPI2));
257  }
258 
259 
260 }
261 
263 
264 
265  switch(periph){
266 
267  case SPI_1:
268 
269  spi_setSpeed(periph,CLOCK_getSpeed()/speed);
270  break;
271 
272  case SPI_2:
273 
274  spi_setSpeed(periph,CLOCK_getSpeedAlternate()/speed);
275  break;
276 
277  default:
278 
279  if(MCU_debugIsEnabled()){
280 
282  }
283  return E_SPI_PORT;
284  break;
285  }
286 
287  return E_SPI_NOERROR;
288 
289 }
290 
291 void spi_setSpeed(spi_periph periph, uint16_t divisor){
292 
293  uint8_t scalar;
294 
295  if(divisor > 128){
296 
297  scalar = SPI_CR1_BR_FPCLK_DIV_256;
298  }
299  else if(divisor > 64){
300 
301  scalar = SPI_CR1_BR_FPCLK_DIV_128;
302  }
303  else if(divisor > 32){
304 
305  scalar = SPI_CR1_BR_FPCLK_DIV_64;
306  }
307  else if(divisor > 16){
308 
309  scalar = SPI_CR1_BR_FPCLK_DIV_32;
310  }
311  else if(divisor > 8){
312 
313  scalar = SPI_CR1_BR_FPCLK_DIV_16;
314  }
315  else if(divisor > 4){
316 
317  scalar = SPI_CR1_BR_FPCLK_DIV_8;
318  }
319  else if(divisor > 2){
320 
321  scalar = SPI_CR1_BR_FPCLK_DIV_4;
322  }
323  else{
324 
325  scalar = SPI_CR1_BR_FPCLK_DIV_2;
326  }
327 
328  switch(periph){
329 
330  case SPI_1:
331 
332  spi_set_baudrate_prescaler(SPI1,scalar);
333  break;
334 
335  case SPI_2:
336 
337  spi_set_baudrate_prescaler(SPI2,scalar);
338  break;
339  }
340 
341  return;
342 }
343 
345 
346  switch(periph){
347 
348  case SPI_1:
349 
350  if(clock == SPI_CLOCK_HIGH){
351 
352  spi_set_clock_polarity_1(SPI1);
353 
354  }
355  else{
356 
357  spi_set_clock_polarity_0(SPI1);
358  }
359 
360  break;
361 
362  case SPI_2:
363 
364  if(clock == SPI_CLOCK_HIGH){
365 
366  spi_set_clock_polarity_1(SPI2);
367 
368  }
369  else{
370 
371  spi_set_clock_polarity_0(SPI2);
372  }
373  break;
374 
375  default:
376 
377  if(MCU_debugIsEnabled()){
378 
380  }
381  return E_SPI_PORT;
382  break;
383  }
384 
385  return E_SPI_NOERROR;
386 }
387 
389 
390  switch(periph){
391 
392  case SPI_1:
393 
394  if(data == SPI_DATA_8){
395 
396  spi_set_dff_8bit(SPI1);
397 
398  }
399  else{
400 
401  spi_set_dff_16bit(SPI1);
402  }
403  break;
404 
405  case SPI_2:
406 
407  if(data == SPI_DATA_8){
408 
409  spi_set_dff_8bit(SPI2);
410 
411  }
412  else{
413 
414  spi_set_dff_16bit(SPI2);
415  }
416  break;
417 
418  default:
419 
420  if(MCU_debugIsEnabled()){
421 
423  }
424  return E_SPI_PORT;
425  break;
426  }
427 
428  return E_SPI_NOERROR;
429 }
430 
432 
433  switch(periph){
434 
435  case SPI_1:
436 
437  if(endian == SPI_LSB){
438 
439  spi_send_lsb_first(SPI1);
440  }
441  else{
442 
443  spi_send_msb_first(SPI1);
444  }
445  break;
446 
447  case SPI_2:
448 
449  if(endian == SPI_LSB){
450 
451  spi_send_lsb_first(SPI2);
452  }
453  else{
454 
455  spi_send_msb_first(SPI2);
456  }
457  break;
458 
459  default:
460 
461  if(MCU_debugIsEnabled()){
462 
464  }
465  return E_SPI_PORT;
466  break;
467  }
468 
469  return E_SPI_NOERROR;
470 }
471 
473 
474  switch(periph){
475 
476  case SPI_1:
477 
478  if(phase == SPI_PHASE_FIRST){
479 
480  spi_set_clock_phase_0(SPI1);
481  }
482  else{
483 
484  spi_set_clock_phase_1(SPI1);
485  }
486  break;
487 
488  case SPI_2:
489 
490  if(phase == SPI_PHASE_FIRST){
491 
492  spi_set_clock_phase_0(SPI2);
493  }
494  else{
495 
496  spi_set_clock_phase_1(SPI2);
497  }
498  break;
499  default:
500 
501  if(MCU_debugIsEnabled()){
502 
504  }
505  return E_SPI_PORT;
506  break;
507  }
508 
509  return E_SPI_NOERROR;
510 }
511 
513 
514  switch(periph){
515 
516  case SPI_1:
517 
518  return &spi1_get;
519  break;
520 
521  case SPI_2:
522 
523  return &spi2_get;
524  break;
525  }
526 
527  return NULL;
528 
529 }
530 
532 
533  switch(periph){
534 
535  case SPI_1:
536 
537  return &spi1_put;
538  break;
539 
540  case SPI_2:
541 
542  return &spi2_put;
543  break;
544  }
545 
546  return NULL;
547 }
548 
549 mcu_error SPI_put(spi_periph periph, uint16_t data){
550 
551  switch(periph){
552 
553  case SPI_1:
554 
555  spi1_put(data);
556  break;
557 
558  case SPI_2:
559 
560  spi2_put(data);
561  break;
562 
563  default:
564 
565  if(MCU_debugIsEnabled()){
566 
568  }
569  return E_SPI_PORT;
570  break;
571  }
572 
573  return E_SPI_NOERROR;
574 
575 }
576 
577 uint16_t SPI_get(spi_periph periph){
578 
579  switch(periph){
580 
581  case SPI_1:
582 
583  return spi1_get();
584  break;
585 
586  case SPI_2:
587 
588  return spi2_get();
589  break;
590  default:
591 
592  return 0;
593  break;
594  }
595  return 0;
596 }
597 
598 void spi1_put(uint16_t data){
599 
600  //Wait for data to be sent
601  SPI_DR(SPI1) = data;
602  while(SPI_SR(SPI1) & SPI_SR_BSY);
603 
604 }
605 
606 void spi2_put(uint16_t data){
607 
608  //Wait for data to be sent
609  SPI_DR(SPI2) = data;
610  while(SPI_SR(SPI2) & SPI_SR_BSY);
611 }
612 
613 uint16_t spi1_get(){
614 
615  //Wait for something to arrive
616  while(SPI_SR(SPI1) & SPI_SR_BSY);
617  return SPI_DR(SPI1);
618 }
619 
620 uint16_t spi2_get(){
621 
622  //Wait for something to arrive
623  while(SPI_SR(SPI2) & SPI_SR_BSY);
624  return SPI_DR(SPI2);
625 }
626 
627 void SPI_write(spi_periph periph, gpio_port port, gpio_pin pin,
628  spi_csPol polarity, uint16_t address, uint16_t data){
629 
630  if(polarity == SPI_CS_HIGH){
631 
632  pinLow(port,pin);
633  pinHigh(port,pin);
634  }
635  else{
636 
637  pinHigh(port,pin);
638  pinLow(port,pin);
639  }
640 
641  SPI_put(periph,address);
642  SPI_put(periph,data);
643 
644  if(polarity == SPI_CS_HIGH){
645 
646  pinLow(port,pin);
647  }
648  else{
649 
650  pinHigh(port,pin);
651  }
652 
653 }
654 
656  spi_csPol polarity, uint16_t address, uint16_t *data, uint16_t count){
657 
658  //More efficient to switch to SPI port here
659  if(polarity == SPI_CS_HIGH){
660 
661  pinLow(port,pin);
662  pinHigh(port,pin);
663  }
664  else{
665 
666  pinHigh(port,pin);
667  pinLow(port,pin);
668  }
669 
670  switch(periph){
671 
672  case SPI_1:
673 
674  spi1_put(address);
675  for(uint16_t i = 0; i < count; i++){
676 
677  spi1_put(data[i]);
678  }
679  break;
680 
681  case SPI_2:
682 
683  spi2_put(address);
684  for(uint16_t i = 0; i < count; i++){
685 
686  spi2_put(data[i]);
687  }
688  break;
689 
690  default:
691  break;
692  }
693 
694  if(polarity == SPI_CS_HIGH){
695 
696  pinLow(port,pin);
697  }
698  else{
699 
700  pinHigh(port,pin);
701  }
702 
703 }
704 
705 uint16_t SPI_read(spi_periph periph, gpio_port port, gpio_pin pin,
706  spi_csPol polarity, uint16_t address){
707 
708  uint16_t data = 0;
709 
710  //More efficient to switch to SPI port here
711  if(polarity == SPI_CS_HIGH){
712 
713  pinLow(port,pin);
714  pinHigh(port,pin);
715  }
716  else{
717 
718  pinHigh(port,pin);
719  pinLow(port,pin);
720  }
721 
722  switch(periph){
723 
724  case SPI_1:
725 
726  spi1_put(address);
727  spi1_get(); //Dummy read to clear receive buffer
728  spi1_put(0xFF); //Dummy write to get some data back
729  data = spi1_get();
730  break;
731 
732  case SPI_2:
733 
734  spi2_put(address);
735  spi2_get(); //Dummy read to clear receive buffer
736  spi2_put(0xFF); //Dummy write to get some data back
737  data = spi2_get();
738  break;
739 
740  default:
741  break;
742  }
743 
744 
745  //More efficient to switch to SPI port here
746  if(polarity == SPI_CS_HIGH){
747 
748  pinLow(port,pin);
749  }
750  else{
751 
752  pinHigh(port,pin);
753  }
754 
755  return data;
756 }
757 
758 void SPI_repeatRead(spi_periph periph, gpio_port port, gpio_pin pin,
759  spi_csPol polarity, uint16_t address, uint16_t *data, uint16_t count){
760 
761  //More efficient to switch to SPI port here
762  if(polarity == SPI_CS_HIGH){
763 
764  pinLow(port,pin);
765  pinHigh(port,pin);
766  }
767  else{
768 
769  pinHigh(port,pin);
770  pinLow(port,pin);
771  }
772 
773 
774  switch(periph){
775 
776  case SPI_1:
777 
778  spi1_put(address);
779  spi1_get(); //Dummy read to clear receive buffer
780 
781  for(uint16_t i = 0; i < count; i++){
782 
783  spi1_put(0xFF); //Dummy write to get some data back
784  data[i] = spi1_get();
785  }
786 
787  break;
788 
789  case SPI_2:
790 
791  spi2_put(address);
792  spi2_get(); //Dummy read to clear receive buffer
793  for(uint16_t i = 0; i < count; i++){
794 
795  spi2_put(0xFF); //Dummy write to get some data back
796  data[i] = spi2_get();
797  }
798  break;
799 
800  default:
801  break;
802  }
803 
804  //More efficient to switch to SPI port here
805  if(polarity == SPI_CS_HIGH){
806 
807  pinLow(port,pin);
808  }
809  else{
810 
811  pinHigh(port,pin);
812  }
813 
814 }
815 
gpio_port
GPIO ports available for the MCU.
mcu_error SPI_setClockPolarity(spi_periph periph, spi_clock clock)
Sets the polarity of the clock during the idle state.
The second SPI peripheral.
mcu_error SPI_setDataFrame(spi_periph periph, spi_data data)
Sets the size of the data frame for one transmission.
#define SPI_DEFAULT_SPEED
Serial clock rate.
#define SPI_DEFAULT_ENDIAN
Data frame order.
mcu_error SPI_enableTxISR(spi_periph periph, void(*handler)(void))
Enable the peripheral&#39;s transmit interrupt.
spi_speed
Clock rates for the serial clock.
spi_u16_fp_v SPI_getGetAdd(spi_periph periph)
Get the function address of the get function for the port.
void pinLow(gpio_port port, gpio_pin pin)
Set a given gpio pin on a port to logic low.
spi_v_fp_u16 SPI_getPutAdd(spi_periph periph)
Get the function address of the put function for the port.
One data frame is 8 bits.
void SPI_write(spi_periph periph, gpio_port port, gpio_pin pin, spi_csPol polarity, uint16_t address, uint16_t data)
Write a data frame to a slave device using standard protocole.
Captured on first transition.
void MCU_printError(mcu_error errorNum)
Print a given error number as a character stream.
Error SPI: No error.
uint8_t MCU_debugIsEnabled(void)
Checks if debug is enabled.
Setup the port for output SPI.
void pinHigh(gpio_port port, gpio_pin pin)
Set a given gpio pin on a port to logic high.
spi_clock
The idle state the clock line is left with no activity.
uint32_t CLOCK_getSpeed(void)
Get the current clock speed of the device.
Error SPI: Port doesn&#39;t exist.
mcu_error SPI_setPhase(spi_periph periph, spi_phase phase)
Sets the phase of the clock.
#define SPI_DEFAULT_PHASE
Clock capture edge relative to clock.
void(* spi_v_fp_u16)(uint16_t)
Funtion point typedef for void(*fp)(uint8_t)
spi_data
The number of data bits send in one transmission.
gpio_pin
GPIO pins available for each port.
spi_csPol
The polarity of the chip select pin.
Pin 13 of the port.
mcu_error SPI_setSpeed(spi_periph periph, spi_speed speed)
Sets the speed of the serial clock.
mcu_error SPI_enableRxISR(spi_periph periph, void(*handler)(uint16_t))
Enable the peripheral&#39;s receive interrupt.
Pin 7 of the port.
#define SPI_DEFAULT_DATA
Data frame size.
mcu_error SPI_setEndian(spi_periph periph, spi_endian endian)
Sets order of the transmitted data frame.
mcu_error SPI_disableTxISR(spi_periph periph)
Disable the peripheral&#39;s transmit interrupt.
spi_endian
Byte order for send data.
Pin 6 of the port.
uint32_t CLOCK_getSpeedAlternate(void)
Get the current clock speed of the alternate bus.
Chip select pin is active high.
uint16_t SPI_read(spi_periph periph, gpio_port port, gpio_pin pin, spi_csPol polarity, uint16_t address)
Read a data frame from the slave device using standard protocole.
Port B of the MCU.
void SPI_repeatRead(spi_periph periph, gpio_port port, gpio_pin pin, spi_csPol polarity, uint16_t address, uint16_t *data, uint16_t count)
Read multiple data frames from the slave device using standard protocole.
mcu_error SPI_setup(spi_periph periph)
Sets up the SPI peripheral with standard setting doneted with macro defines.
Header file for stm32f103cb SPI.
uint16_t SPI_get(spi_periph periph)
Recieve a byte from the recieve buffer. (blocking)
Pin 15 of the port.
mcu_error pinSetup(gpio_mode mode, gpio_port port, gpio_pin pin)
Setup a GPIO pin for a given function.
Clock is high when idle.
Data is sent LSB first.
The first SPI peripheral.
spi_phase
The phase at which the data is captured on the clock line.
Pin 5 of the port.
#define SPI_DEFAULT_CLOCK
Clock reset state.
Setup the port for input SPI.
mcu_error SPI_disableRxISR(spi_periph periph)
Disable the peripheral&#39;s receive interrupt.
Pin 14 of the port.
void SPI_repeatWrite(spi_periph periph, gpio_port port, gpio_pin pin, spi_csPol polarity, uint16_t address, uint16_t *data, uint16_t count)
Write multiple data frames to a slave device using standard protocole.
spi_periph
Peripheral SPI ports available.
uint16_t(* spi_u16_fp_v)(void)
Funtion point typedef for void(*fp)(void)
mcu_error SPI_put(spi_periph periph, uint16_t data)
Send one data frame on the data bus. (blocking)
Port A of the MCU.
mcu_error
Error enumerators for the Debug peripheral.