瀏覽代碼

Add beginTransaction to HAL SPI (#9019)

revilor 7 年之前
父節點
當前提交
959a2d2527

+ 77
- 3
Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp 查看文件

@@ -1,4 +1,4 @@
1
-/**
1
+/*
2 2
  * Marlin 3D Printer Firmware
3 3
  * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4 4
  *
@@ -94,7 +94,9 @@ void spiBegin (void) {
94 94
     SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
95 95
     SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
96 96
   }
97
-  //------------------------------------------------------------------------------
97
+
98
+ 
99
+    //------------------------------------------------------------------------------
98 100
   /** SPI receive a byte */
99 101
   uint8_t spiRec(void) {
100 102
     SPDR = 0xFF;
@@ -132,6 +134,72 @@ void spiBegin (void) {
132 134
     }
133 135
     while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
134 136
   }
137
+
138
+
139
+  /** begin spi transaction */
140
+  void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
141
+    // Based on Arduino SPI library
142
+    // Clock settings are defined as follows. Note that this shows SPI2X
143
+    // inverted, so the bits form increasing numbers. Also note that
144
+    // fosc/64 appears twice
145
+    // SPR1 SPR0 ~SPI2X Freq
146
+    //   0    0     0   fosc/2
147
+    //   0    0     1   fosc/4
148
+    //   0    1     0   fosc/8
149
+    //   0    1     1   fosc/16
150
+    //   1    0     0   fosc/32
151
+    //   1    0     1   fosc/64
152
+    //   1    1     0   fosc/64
153
+    //   1    1     1   fosc/128
154
+
155
+    // We find the fastest clock that is less than or equal to the
156
+    // given clock rate. The clock divider that results in clock_setting
157
+    // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the
158
+    // slowest (128 == 2 ^^ 7, so clock_div = 6).
159
+    uint8_t clockDiv;
160
+    
161
+    // When the clock is known at compiletime, use this if-then-else
162
+    // cascade, which the compiler knows how to completely optimize
163
+    // away. When clock is not known, use a loop instead, which generates
164
+    // shorter code.
165
+    if (__builtin_constant_p(spiClock)) {
166
+      if (spiClock >= F_CPU / 2) {
167
+        clockDiv = 0;
168
+      } else if (spiClock >= F_CPU / 4) {
169
+        clockDiv = 1;
170
+      } else if (spiClock >= F_CPU / 8) {
171
+        clockDiv = 2;
172
+      } else if (spiClock >= F_CPU / 16) {
173
+        clockDiv = 3;
174
+      } else if (spiClock >= F_CPU / 32) {
175
+        clockDiv = 4;
176
+      } else if (spiClock >= F_CPU / 64) {
177
+        clockDiv = 5;
178
+      } else {
179
+        clockDiv = 6;
180
+      }
181
+    } else {
182
+      uint32_t clockSetting = F_CPU / 2;
183
+      clockDiv = 0;
184
+      while (clockDiv < 6 && spiClock < clockSetting) {
185
+        clockSetting /= 2;
186
+        clockDiv++;
187
+      }
188
+    }
189
+
190
+    // Compensate for the duplicate fosc/64
191
+    if (clockDiv == 6)
192
+      clockDiv = 7;
193
+
194
+    // Invert the SPI2X bit
195
+    clockDiv ^= 0x1;
196
+
197
+    SPCR = _BV(SPE) | _BV(MSTR) | ((bitOrder == SPI_LSBFIRST) ? _BV(DORD) : 0) |
198
+      (dataMode << CPHA) | ((clockDiv >> 1) << SPR0);
199
+    SPSR = clockDiv | 0x01;          
200
+  }
201
+
202
+  
135 203
        //------------------------------------------------------------------------------
136 204
 #else  // SOFTWARE_SPI
137 205
        //------------------------------------------------------------------------------
@@ -144,6 +212,12 @@ void spiBegin (void) {
144 212
     UNUSED(spiRate);
145 213
   }
146 214
 
215
+  /** Begin SPI transaction, set clock, bit order, data mode */
216
+  void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
217
+    // nothing to do
218
+    UNUSED(spiBeginTransaction);
219
+  }    
220
+
147 221
   //------------------------------------------------------------------------------
148 222
   /** Soft SPI receive byte */
149 223
   uint8_t spiRec() {
@@ -206,7 +280,7 @@ void spiBegin (void) {
206 280
     spiSend(token);
207 281
     for (uint16_t i = 0; i < 512; i++)
208 282
       spiSend(buf[i]);
209
-  }
283
+  } 
210 284
 #endif  // SOFTWARE_SPI
211 285
 
212 286
 

+ 13
- 0
Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp 查看文件

@@ -571,6 +571,12 @@
571 571
     WRITE(SCK_PIN, LOW);
572 572
   }
573 573
 
574
+  /** Begin SPI transaction, set clock, bit order, data mode */
575
+  void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
576
+    // TODO: to be implemented
577
+    
578
+  }    
579
+  
574 580
   #pragma GCC reset_options
575 581
 
576 582
 #else
@@ -767,6 +773,13 @@
767 773
     }
768 774
     spiSend(buf[511]);
769 775
   }
776
+
777
+  /** Begin SPI transaction, set clock, bit order, data mode */
778
+  void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
779
+    // TODO: to be implemented
780
+    
781
+  }    
782
+  
770 783
 #endif // ENABLED(SOFTWARE_SPI)
771 784
 
772 785
 #endif // ARDUINO_ARCH_SAM

+ 7
- 0
Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp 查看文件

@@ -299,6 +299,13 @@ PinCfg.Portnum = LPC1768_PIN_PORT(MISO_PIN);
299 299
   // Write from buffer to SPI
300 300
   void spiSendBlock(uint8_t token, const uint8_t* buf) {
301 301
   }
302
+
303
+  /** Begin SPI transaction, set clock, bit order, data mode */
304
+  void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
305
+    // TODO: to be implemented
306
+    
307
+  }    
308
+  
302 309
 #endif // ENABLED(LPC_SOFTWARE_SPI)
303 310
 
304 311
 #endif // TARGET_LPC1768

+ 7
- 0
Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp 查看文件

@@ -164,6 +164,13 @@ void spiSendBlock(uint8_t token, const uint8_t* buf) {
164 164
   SPI.endTransaction();
165 165
 }
166 166
 
167
+/** Begin SPI transaction, set clock, bit order, data mode */
168
+void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
169
+  spiConfig = SPISettings(spiClock, bitOrder, dataMode);
170
+  
171
+  SPI.beginTransaction(spiConfig);
172
+}    
173
+
167 174
 #endif // SOFTWARE_SPI
168 175
 
169 176
 #endif // __STM32F1__

+ 8
- 0
Marlin/src/HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp 查看文件

@@ -101,4 +101,12 @@ void spiSendBlock(uint8_t token, const uint8_t* buf) {
101 101
 }
102 102
 
103 103
 
104
+/** Begin SPI transaction, set clock, bit order, data mode */
105
+void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
106
+  spiConfig = SPISettings(spiClock, bitOrder, dataMode);
107
+
108
+  SPI.beginTransaction(spiConfig);    
109
+}    
110
+
111
+
104 112
 #endif

+ 10
- 0
Marlin/src/HAL/SPI.h 查看文件

@@ -55,6 +55,14 @@
55 55
 #define SPI_SPEED_5         5   // Set SCK rate to 1/32 of max rate
56 56
 #define SPI_SPEED_6         6   // Set SCK rate to 1/64 of max rate
57 57
 
58
+#define SPI_LSBFIRST 0
59
+#define SPI_MSBFIRST 1
60
+
61
+#define SPI_DATAMODE_0 0x00
62
+#define SPI_DATAMODE_1 0x04
63
+#define SPI_DATAMODE_2 0x08
64
+#define SPI_DATAMODE_3 0x0C
65
+
58 66
 // Standard SPI functions
59 67
 /** Initialise SPI bus */
60 68
 void spiBegin(void);
@@ -68,5 +76,7 @@ uint8_t spiRec(void);
68 76
 void spiRead(uint8_t* buf, uint16_t nbyte);
69 77
 /** Write token and then write from 512 byte buffer to SPI (for SD card) */
70 78
 void spiSendBlock(uint8_t token, const uint8_t* buf);
79
+/** Begin SPI transaction, set clock, bit order, data mode */
80
+void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode);
71 81
 
72 82
 #endif // _SPI_H_

Loading…
取消
儲存