1+ #include " SPI.h"
2+ #include < gd32vf103.h>
3+ #include " Common.h"
4+
5+ SPIClass::SPIClass (uint8_t mosi, uint8_t miso, uint8_t sclk, uint8_t ssel)
6+ : _dev(0 )
7+ , _dev_clk(RCU_SPI0)
8+ , _mosi_bank(0 )
9+ , _miso_bank(0 )
10+ , _sclk_bank(0 )
11+ , _ssel_bank(0 )
12+ , _mosi_bit(0 )
13+ , _miso_bit(0 )
14+ , _sclk_bit(0 )
15+ , _ssel_bit(0 )
16+ , _mosi_bank_clk(RCU_GPIOA)
17+ , _miso_bank_clk(RCU_GPIOA)
18+ , _sclk_bank_clk(RCU_GPIOA)
19+ , _ssel_bank_clk(RCU_GPIOA) {
20+ if (mosi < VARIANT_GPIO_NUM && digitalPinSPIAvailiable (mosi)) {
21+ _dev = digitalPinToSPIDevice (mosi);
22+ _dev_clk = digitalPinToSPIClockId (mosi);
23+ _mosi_bank = digitalPinToPort (mosi);
24+ _mosi_bit = digitalPinToBitMask (mosi);
25+ _mosi_bank_clk = digitalPinToClkid (mosi);
26+ }
27+ if (miso < VARIANT_GPIO_NUM && digitalPinSPIAvailiable (miso)) {
28+ _dev = digitalPinToSPIDevice (miso);
29+ _dev_clk = digitalPinToSPIClockId (miso);
30+ _miso_bank = digitalPinToPort (miso);
31+ _miso_bit = digitalPinToBitMask (miso);
32+ _miso_bank_clk = digitalPinToClkid (miso);
33+ }
34+ if (sclk < VARIANT_GPIO_NUM && digitalPinSPIAvailiable (sclk)) {
35+ _sclk_bank = digitalPinToPort (sclk);
36+ _sclk_bit = digitalPinToBitMask (sclk);
37+ _sclk_bank_clk = digitalPinToClkid (sclk);
38+ }
39+ if (ssel < VARIANT_GPIO_NUM) {}
40+ _ssel_bank = digitalPinToPort (ssel);
41+ _ssel_bit = digitalPinToBitMask (ssel);
42+ _ssel_bank_clk = digitalPinToClkid (ssel);
43+ if (digitalPinSPIAvailiable (ssel)) {
44+ _ssel_hard = 1 ;
45+ }
46+ }
47+
48+ void SPIClass::begin () {
49+ if (_dev == 0 ) {
50+ return ;
51+ }
52+ if (_mosi_bank != 0 ) {
53+ rcu_periph_clock_enable ((rcu_periph_enum)_mosi_bank_clk);
54+ gpio_init (_mosi_bank, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, _mosi_bit);
55+ }
56+ if (_miso_bank != 0 ) {
57+ rcu_periph_clock_enable ((rcu_periph_enum)_miso_bank_clk);
58+ gpio_init (
59+ _miso_bank, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, _miso_bit);
60+ }
61+ if (_sclk_bank != 0 ) {
62+ rcu_periph_clock_enable ((rcu_periph_enum)_sclk_bank_clk);
63+ gpio_init (_sclk_bank, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, _sclk_bit);
64+ }
65+ if (_ssel_bank != 0 ) {
66+ rcu_periph_clock_enable ((rcu_periph_enum)_ssel_bank_clk);
67+ gpio_init (_ssel_bank, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, _ssel_bit);
68+ if (_ssel_hard == 0 ) {
69+ gpio_bit_set (_ssel_bank, _ssel_bit);
70+ }
71+ }
72+ rcu_periph_clock_enable ((rcu_periph_enum)_dev_clk);
73+ spi_i2s_deinit ((uint32_t )_dev);
74+ }
75+
76+ void SPIClass::end () {
77+ if (_dev == 0 ) {
78+ return ;
79+ }
80+ if (_mosi_bank != 0 ) {
81+ gpio_init (_mosi_bank, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, _mosi_bit);
82+ }
83+ if (_miso_bank != 0 ) {
84+ gpio_init (_miso_bank, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, _miso_bit);
85+ }
86+ if (_sclk_bank != 0 ) {
87+ gpio_init (_sclk_bank, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, _sclk_bit);
88+ }
89+ if (_ssel_bank != 0 ) {
90+ gpio_init (_ssel_bank, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, _ssel_bit);
91+ }
92+ spi_i2s_deinit ((uint32_t )_dev);
93+ rcu_periph_clock_disable ((rcu_periph_enum)_dev_clk);
94+ }
95+
96+ void SPIClass::beginTransaction (SPISettings settings) {
97+ if (_dev == 0 ) {
98+ return ;
99+ }
100+ if (settings._freq == 0 ) {
101+ return ;
102+ }
103+ if (_dev == SPI0 && settings._freq > rcu_clock_freq_get (CK_APB2)) {
104+ return ;
105+ }
106+ else if (settings._freq > rcu_clock_freq_get (CK_APB1)) {
107+ return ;
108+ }
109+ _dataMode = settings._dataMode ;
110+ _bitOrder = settings._bitOrder ;
111+ _freq = settings._freq ;
112+ beginTransaction ();
113+ }
114+
115+ void SPIClass::endTransaction () {
116+ if (_dev == 0 ) {
117+ return ;
118+ }
119+ spi_disable (_dev);
120+ }
121+
122+ void SPIClass::transfer (uint8_t * data, uint32_t size, uint32_t timeout) {
123+ if (_dev == 0 || data == nullptr ) {
124+ return ;
125+ }
126+ uint64_t startT = millis ();
127+
128+ if (_ssel_hard == 0 && _ssel_bank != 0 ) {
129+ gpio_bit_reset (_ssel_bank, _ssel_bit);
130+ }
131+
132+ for (size_t i = 0 ; i < size; i++) {
133+ while (!spi_i2s_flag_get (_dev, SPI_FLAG_TBE)) {
134+ if (millis () > startT + timeout) {
135+ if (_ssel_hard == 0 && _ssel_bank != 0 ) {
136+ gpio_bit_set (_ssel_bank, _ssel_bit);
137+ }
138+ return ;
139+ }
140+ }
141+ spi_i2s_data_transmit (_dev, *data);
142+ data++;
143+ }
144+
145+ if (_ssel_hard == 0 && _ssel_bank != 0 ) {
146+ gpio_bit_set (_ssel_bank, _ssel_bit);
147+ }
148+ }
149+
150+ void SPIClass::transfer (
151+ uint8_t * txdata, uint8_t * rxdata, uint32_t size, uint32_t timeout) {
152+ if (_dev == 0 || txdata == nullptr || rxdata == nullptr ) {
153+ return ;
154+ }
155+ uint64_t startT = millis ();
156+
157+ if (_ssel_hard == 0 && _ssel_bank != 0 ) {
158+ gpio_bit_reset (_ssel_bank, _ssel_bit);
159+ }
160+
161+ for (size_t i = 0 ; i < size; i++) {
162+ while (!spi_i2s_flag_get (_dev, SPI_FLAG_TBE)) {
163+ if (millis () > startT + timeout) {
164+ if (_ssel_hard == 0 && _ssel_bank != 0 ) {
165+ gpio_bit_set (_ssel_bank, _ssel_bit);
166+ }
167+ return ;
168+ }
169+ }
170+ spi_i2s_data_transmit (_dev, *txdata);
171+ txdata++;
172+ while (!spi_i2s_flag_get (_dev, SPI_FLAG_RBNE)) {
173+ if (millis () > startT + timeout) {
174+ if (_ssel_hard == 0 && _ssel_bank != 0 ) {
175+ gpio_bit_set (_ssel_bank, _ssel_bit);
176+ }
177+ return ;
178+ }
179+ }
180+ *rxdata = spi_i2s_data_receive (_dev);
181+ rxdata++;
182+ }
183+
184+ if (_ssel_hard == 0 && _ssel_bank != 0 ) {
185+ gpio_bit_set (_ssel_bank, _ssel_bit);
186+ }
187+ }
188+
189+ void SPIClass::setBitOrder (uint8_t bitOrder) {
190+ _bitOrder = bitOrder;
191+ beginTransaction ();
192+ }
193+
194+ void SPIClass::setDataMode (uint8_t dataMode) {
195+ _dataMode = dataMode;
196+ beginTransaction ();
197+ }
198+
199+ void SPIClass::setFrequency (uint32_t freq) {
200+ if (_dev == 0 ) {
201+ return ;
202+ }
203+ if (freq == 0 ) {
204+ return ;
205+ }
206+ if (_dev == SPI0 && freq > rcu_clock_freq_get (CK_APB2)) {
207+ return ;
208+ }
209+ else if (freq > rcu_clock_freq_get (CK_APB1)) {
210+ return ;
211+ }
212+ _freq = freq;
213+ beginTransaction ();
214+ }
215+
216+ void SPIClass::beginTransaction () {
217+ if (_dev == 0 ) {
218+ return ;
219+ }
220+ spi_parameter_struct param;
221+ switch (_dataMode) {
222+ case SPI_MODE0:
223+ param.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
224+ break ;
225+ case SPI_MODE1:
226+ param.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
227+ break ;
228+ case SPI_MODE2:
229+ param.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
230+ break ;
231+ case SPI_MODE3:
232+ param.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
233+ break ;
234+ default :
235+ return ;
236+ }
237+ param.device_mode = SPI_MASTER;
238+ param.endian = _bitOrder == MSBFIRST ? SPI_ENDIAN_MSB : SPI_ENDIAN_LSB;
239+ param.frame_size = SPI_FRAMESIZE_8BIT;
240+ param.nss = _ssel_hard ? SPI_NSS_HARD : SPI_NSS_SOFT;
241+ uint32_t prescale = 0 ;
242+ if (_dev == SPI0) {
243+ prescale = rcu_clock_freq_get (CK_APB2) / _freq - 1 ;
244+ }
245+ else {
246+ prescale = rcu_clock_freq_get (CK_APB1) / _freq - 1 ;
247+ }
248+ param.prescale = prescale;
249+ param.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
250+ spi_init (_dev, ¶m);
251+ spi_enable (_dev);
252+ }
0 commit comments