Browse Source

Add beginTransaction to HAL SPI (#9019)

revilor 7 years ago
parent
commit
959a2d2527

+ 77
- 3
Marlin/src/HAL/HAL_AVR/HAL_spi_AVR.cpp View File

1
-/**
1
+/*
2
  * Marlin 3D Printer Firmware
2
  * Marlin 3D Printer Firmware
3
  * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
3
  * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
  *
4
  *
94
     SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
94
     SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
95
     SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
95
     SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
96
   }
96
   }
97
-  //------------------------------------------------------------------------------
97
+
98
+ 
99
+    //------------------------------------------------------------------------------
98
   /** SPI receive a byte */
100
   /** SPI receive a byte */
99
   uint8_t spiRec(void) {
101
   uint8_t spiRec(void) {
100
     SPDR = 0xFF;
102
     SPDR = 0xFF;
132
     }
134
     }
133
     while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
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
 #else  // SOFTWARE_SPI
204
 #else  // SOFTWARE_SPI
137
        //------------------------------------------------------------------------------
205
        //------------------------------------------------------------------------------
144
     UNUSED(spiRate);
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
   /** Soft SPI receive byte */
222
   /** Soft SPI receive byte */
149
   uint8_t spiRec() {
223
   uint8_t spiRec() {
206
     spiSend(token);
280
     spiSend(token);
207
     for (uint16_t i = 0; i < 512; i++)
281
     for (uint16_t i = 0; i < 512; i++)
208
       spiSend(buf[i]);
282
       spiSend(buf[i]);
209
-  }
283
+  } 
210
 #endif  // SOFTWARE_SPI
284
 #endif  // SOFTWARE_SPI
211
 
285
 
212
 
286
 

+ 13
- 0
Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp View File

571
     WRITE(SCK_PIN, LOW);
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
   #pragma GCC reset_options
580
   #pragma GCC reset_options
575
 
581
 
576
 #else
582
 #else
767
     }
773
     }
768
     spiSend(buf[511]);
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
 #endif // ENABLED(SOFTWARE_SPI)
783
 #endif // ENABLED(SOFTWARE_SPI)
771
 
784
 
772
 #endif // ARDUINO_ARCH_SAM
785
 #endif // ARDUINO_ARCH_SAM

+ 7
- 0
Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp View File

299
   // Write from buffer to SPI
299
   // Write from buffer to SPI
300
   void spiSendBlock(uint8_t token, const uint8_t* buf) {
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
 #endif // ENABLED(LPC_SOFTWARE_SPI)
309
 #endif // ENABLED(LPC_SOFTWARE_SPI)
303
 
310
 
304
 #endif // TARGET_LPC1768
311
 #endif // TARGET_LPC1768

+ 7
- 0
Marlin/src/HAL/HAL_STM32F1/HAL_spi_Stm32f1.cpp View File

164
   SPI.endTransaction();
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
 #endif // SOFTWARE_SPI
174
 #endif // SOFTWARE_SPI
168
 
175
 
169
 #endif // __STM32F1__
176
 #endif // __STM32F1__

+ 8
- 0
Marlin/src/HAL/HAL_TEENSY35_36/HAL_spi_Teensy.cpp View File

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
 #endif
112
 #endif

+ 10
- 0
Marlin/src/HAL/SPI.h View File

55
 #define SPI_SPEED_5         5   // Set SCK rate to 1/32 of max rate
55
 #define SPI_SPEED_5         5   // Set SCK rate to 1/32 of max rate
56
 #define SPI_SPEED_6         6   // Set SCK rate to 1/64 of max rate
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
 // Standard SPI functions
66
 // Standard SPI functions
59
 /** Initialise SPI bus */
67
 /** Initialise SPI bus */
60
 void spiBegin(void);
68
 void spiBegin(void);
68
 void spiRead(uint8_t* buf, uint16_t nbyte);
76
 void spiRead(uint8_t* buf, uint16_t nbyte);
69
 /** Write token and then write from 512 byte buffer to SPI (for SD card) */
77
 /** Write token and then write from 512 byte buffer to SPI (for SD card) */
70
 void spiSendBlock(uint8_t token, const uint8_t* buf);
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
 #endif // _SPI_H_
82
 #endif // _SPI_H_

Loading…
Cancel
Save