STC15W408AS library 0.18.0
Loading...
Searching...
No Matches
spi.h
Go to the documentation of this file.
1#ifndef STC15_SPIH
2#define STC15_SPIH
3
46#include <sys.h>
47#include <bits.h>
48#include <gpio.h>
49
56#define SPI_SSIG_BIT 7
58#define SPI_SPEN_BIT 6
60#define SPI_DORD_BIT 5
62#define SPI_MSTR_BIT 4
64#define SPI_CPOL_BIT 3
66#define SPI_CPHA_BIT 2
68#define SPI_SPR1_BIT 1
70#define SPI_SPR0_BIT 0
71
73#define SPI_SSIG_MSK 0x80
75#define SPI_SPEN_MSK 0x40
77#define SPI_DORD_MSK 0x20
79#define SPI_MSTR_MSK 0x10
81#define SPI_CPOL_MSK 0x08
83#define SPI_CPHA_MSK 0x04
85#define SPI_SPR_MSK 0x03
86
88#define SPI_SPIF_BIT 7
90#define SPI_WCOL_BIT 6
91
93#define SPI_SPIF_MSK 0x80
95#define SPI_WCOL_MSK 0x40
97#define SPI_SPSTAT_CLEAR_MSK (SPI_SPIF_MSK | SPI_WCOL_MSK)
98
100#define SPI_S0_BIT 2
102#define SPI_S0_MASK 0x04
104#define SPI_S1_MASK 0x08
106#define SPI_SW_MASK (SPI_S0_MASK | SPI_S1_MASK)
107
117typedef enum
118{
120 SPI_CLOCK_DIV_4 = 0b00000000,
122 SPI_CLOCK_DIV_16 = 0b00000001,
124 SPI_CLOCK_DIV_64 = 0b00000010,
126 SPI_CLOCK_DIV_128 = 0b00000011
128
142typedef enum
143{
145 SPI_MODE_0 = 0b00000000,
147 SPI_MODE_1 = 0b00000100,
149 SPI_MODE_2 = 0b00001000,
151 SPI_MODE_3 = 0b00001100
153
175
188#define spi_init_master_pins_SPI_PIN_GROUP_1() \
189do { \
190 /* SS on P1.2 as push-pull output, kept high */ \
191 pin_push_pull_init(P1, 2); \
192 bit_set(P1, SBIT2); \
193 /* MOSI on P1.3 as push-pull output */ \
194 pin_push_pull_init(P1, 3); \
195 /* MISO on P1.4 as input only */ \
196 pin_input_only_init(P1, 4); \
197 /* SCLK on P1.5 as push-pull output */ \
198 pin_push_pull_init(P1, 5); \
199} while(0)
200
213#define spi_init_master_pins_SPI_PIN_GROUP_2() \
214do { \
215 /* SS_2 on P2.4 as push-pull output, kept high */ \
216 pin_push_pull_init(P2, 4); \
217 bit_set(P2, SBIT4); \
218 /* MOSI_2 on P2.3 as push-pull output */ \
219 pin_push_pull_init(P2, 3); \
220 /* MISO_2 on P2.2 as input only */ \
221 pin_input_only_init(P2, 2); \
222 /* SCLK_2 on P2.1 as push-pull output */ \
223 pin_push_pull_init(P2, 1); \
224} while(0)
225
241#define spi_init_master_pins_SPI_PIN_GROUP_3() \
242do { \
243 /* SS_3 on P5.4 as push-pull output, kept high */ \
244 pin_push_pull_init(P5, 4); \
245 bit_set(P5, SBIT4); \
246 /* MOSI_3 on P4.0 as push-pull output */ \
247 pin_push_pull_init(P4, 0); \
248 /* MISO_3 on P4.1 as input only */ \
249 pin_input_only_init(P4, 1); \
250 /* SCLK_3 on P4.3 as push-pull output */ \
251 pin_push_pull_init(P4, 3); \
252} while(0)
253
265#define spi_init_slave_pins_SPI_PIN_GROUP_1() \
266do { \
267 /* SS on P1.2 as input only */ \
268 pin_input_only_init(P1, 2); \
269 /* MOSI on P1.3 as input only */ \
270 pin_input_only_init(P1, 3); \
271 /* MISO on P1.4 as push-pull output */ \
272 pin_push_pull_init(P1, 4); \
273 /* SCLK on P1.5 as input only */ \
274 pin_input_only_init(P1, 5); \
275} while(0)
276
288#define spi_init_slave_pins_SPI_PIN_GROUP_2() \
289do { \
290 /* SS_2 on P2.4 as input only */ \
291 pin_input_only_init(P2, 4); \
292 /* MOSI_2 on P2.3 as input only */ \
293 pin_input_only_init(P2, 3); \
294 /* MISO_2 on P2.2 as push-pull output */ \
295 pin_push_pull_init(P2, 2); \
296 /* SCLK_2 on P2.1 as input only */ \
297 pin_input_only_init(P2, 1); \
298} while(0)
299
314#define spi_init_slave_pins_SPI_PIN_GROUP_3() \
315do { \
316 /* SS_3 on P5.4 as input only */ \
317 pin_input_only_init(P5, 4); \
318 /* MOSI_3 on P4.0 as input only */ \
319 pin_input_only_init(P4, 0); \
320 /* MISO_3 on P4.1 as push-pull output */ \
321 pin_push_pull_init(P4, 1); \
322 /* SCLK_3 on P4.3 as input only */ \
323 pin_input_only_init(P4, 3); \
324} while(0)
325
334#define spi_ss_clr_SPI_PIN_GROUP_1() (bit_clr(P1, SBIT2))
335
341#define spi_ss_set_SPI_PIN_GROUP_1() (bit_set(P1, SBIT2))
342
351#define spi_ss_clr_SPI_PIN_GROUP_2() (bit_clr(P2, SBIT4))
352
358#define spi_ss_set_SPI_PIN_GROUP_2() (bit_set(P2, SBIT4))
359
370#define spi_ss_clr_SPI_PIN_GROUP_3() (bit_clr(P5, SBIT4))
371
377#define spi_ss_set_SPI_PIN_GROUP_3() (bit_set(P5, SBIT4))
378
383
397#define spi_init_master_pins(group) spi_init_master_pins_##group()
398
410#define spi_init_slave_pins(group) spi_init_slave_pins_##group()
411
433#define spi_init_master(group, mode, clock, lsb_first) \
434do { \
435 /* Select the SS/MOSI/MISO/SCLK pin group */ \
436 spi_set_pin_group(group); \
437 /* Configure the SS/MOSI/MISO/SCLK pins */ \
438 spi_init_master_pins(group); \
439 /* Enable SPI as a master with the given mode, clock and data order */ \
440 SPCTL = SPI_SPEN_MSK | SPI_MSTR_MSK | (mode) | (clock) | \
441 ((lsb_first) ? SPI_DORD_MSK : 0) | \
442 (((mode) & SPI_CPHA_MSK) ? SPI_SSIG_MSK : 0); \
443} while(0)
444
461#define spi_init_slave(group, mode, lsb_first) \
462do { \
463 /* Select the SS/MOSI/MISO/SCLK pin group */ \
464 spi_set_pin_group(group); \
465 /* Configure the SS/MOSI/MISO/SCLK pins */ \
466 spi_init_slave_pins(group); \
467 /* Enable SPI as a slave with the given mode and data order */ \
468 SPCTL = SPI_SPEN_MSK | (mode) | ((lsb_first) ? SPI_DORD_MSK : 0); \
469} while(0)
470
481#define spi_destroy(void) \
482do { \
483 /* Disable the SPI interface */ \
484 SPCTL = 0; \
485 /* Clear the SPIF and WCOL flags */ \
486 bit_set(SPSTAT, SPI_SPSTAT_CLEAR_MSK); \
487} while(0)
488
490
495
507#define spi_set_pin_group(group) \
508do { \
509 bit_clr(P_SW1, SPI_SW_MASK); \
510 bit_set(P_SW1, (uint8_t)((group) << SPI_S0_BIT)); \
511} while(0)
512
520#define spi_get_pin_group() ((spi_pin_group_t)(bit_shift_right(get_reg(P_SW1, (SPI_S0_MASK | SPI_S1_MASK)), SPI_S0_BIT)))
521
523
528
542#define spi_ss_clr(group) spi_ss_clr_##group()
543
557#define spi_ss_set(group) spi_ss_set_##group()
558
560
565
577#define spi_write_sync(data) \
578do { \
579 /* Clear the SPIF and WCOL flags */ \
580 bit_set(SPSTAT, SPI_SPSTAT_CLEAR_MSK); \
581 /* Writing the data register starts the transfer */ \
582 SPDAT = (data); \
583 /* Wait until the transfer is finished */ \
584 while (test_if_bit_cleared(SPSTAT, SPI_SPIF_MSK)); \
585 /* Clear the SPIF and WCOL flags */ \
586 bit_set(SPSTAT, SPI_SPSTAT_CLEAR_MSK); \
587} while(0)
588
601#define spi_transfer_sync(value, data) \
602do { \
603 spi_write_sync(data); \
604 /* Store the received byte */ \
605 *(value) = SPDAT; \
606} while(0)
607
609
614
629#define spi_async_transfer_start(data) \
630do { \
631 /* Clear the SPIF and WCOL flags */ \
632 bit_set(SPSTAT, SPI_SPSTAT_CLEAR_MSK); \
633 /* Writing the data register starts the transfer */ \
634 SPDAT = (data); \
635} while(0)
636
644#define is_spi_async_transfer_complete() (test_if_bit_set(SPSTAT, SPI_SPIF_MSK))
645
654#define spi_async_transfer_finish() (bit_set(SPSTAT, SPI_SPSTAT_CLEAR_MSK))
655
670#define spi_async_get_result() (SPDAT)
671
673
678
686#define is_spi_enabled() (test_if_bit_set(SPCTL, SPI_SPEN_MSK))
687
695#define is_spi_master() (test_if_bit_set(SPCTL, SPI_MSTR_MSK))
696
708#define is_spi_write_collision() (test_if_bit_set(SPSTAT, SPI_WCOL_MSK))
709
717#define spi_get_mode() ((spi_mode_t)get_reg(SPCTL, (SPI_CPOL_MSK | SPI_CPHA_MSK)))
718
726#define spi_get_clock() ((spi_clock_t)get_reg(SPCTL, SPI_SPR_MSK))
727
729
730#endif
spi_clock_t
SPI clock rate.
Definition spi.h:118
spi_pin_group_t
SPI pin group.
Definition spi.h:167
spi_mode_t
SPI mode.
Definition spi.h:143
@ SPI_CLOCK_DIV_4
Definition spi.h:120
@ SPI_CLOCK_DIV_64
Definition spi.h:124
@ SPI_CLOCK_DIV_128
Definition spi.h:126
@ SPI_CLOCK_DIV_16
Definition spi.h:122
@ SPI_PIN_GROUP_3
Definition spi.h:173
@ SPI_PIN_GROUP_2
Definition spi.h:171
@ SPI_PIN_GROUP_1
Definition spi.h:169
@ SPI_MODE_0
Definition spi.h:145
@ SPI_MODE_2
Definition spi.h:149
@ SPI_MODE_1
Definition spi.h:147
@ SPI_MODE_3
Definition spi.h:151