]> granicus.if.org Git - esp-idf/blob - components/driver/spi_master.c
e070ba9c6603061816a626f7d736b319145df8e1
[esp-idf] / components / driver / spi_master.c
1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 /*
16 Architecture:
17
18 We can initialize a SPI driver, but we don't talk to the SPI driver itself, we address a device. A device essentially
19 is a combination of SPI port and CS pin, plus some information about the specifics of communication to the device
20 (timing, command/address length etc)
21
22 The essence of the interface to a device is a set of queues; one per device. The idea is that to send something to a SPI
23 device, you allocate a transaction descriptor. It contains some information about the transfer like the lenghth, address,
24 command etc, plus pointers to transmit and receive buffer. The address of this block gets pushed into the transmit queue.
25 The SPI driver does its magic, and sends and retrieves the data eventually. The data gets written to the receive buffers,
26 if needed the transaction descriptor is modified to indicate returned parameters and the entire thing goes into the return
27 queue, where whatever software initiated the transaction can retrieve it.
28
29 The entire thing is run from the SPI interrupt handler. If SPI is done transmitting/receiving but nothing is in the queue,
30 it will not clear the SPI interrupt but just disable it. This way, when a new thing is sent, pushing the packet into the send
31 queue and re-enabling the interrupt will trigger the interrupt again, which can then take care of the sending.
32 */
33
34
35
36 #include <string.h>
37 #include "driver/spi_common.h"
38 #include "driver/spi_master.h"
39 #include "soc/gpio_sig_map.h"
40 #include "soc/spi_reg.h"
41 #include "soc/dport_reg.h"
42 #include "soc/spi_struct.h"
43 #include "rom/ets_sys.h"
44 #include "esp_types.h"
45 #include "esp_attr.h"
46 #include "esp_intr.h"
47 #include "esp_intr_alloc.h"
48 #include "esp_log.h"
49 #include "esp_err.h"
50 #include "esp_pm.h"
51 #include "freertos/FreeRTOS.h"
52 #include "freertos/semphr.h"
53 #include "freertos/xtensa_api.h"
54 #include "freertos/task.h"
55 #include "freertos/ringbuf.h"
56 #include "soc/soc.h"
57 #include "soc/soc_memory_layout.h"
58 #include "soc/dport_reg.h"
59 #include "rom/lldesc.h"
60 #include "driver/gpio.h"
61 #include "driver/periph_ctrl.h"
62 #include "esp_heap_caps.h"
63
64 typedef struct spi_device_t spi_device_t;
65 typedef typeof(SPI1.clock) spi_clock_reg_t;
66
67 #define NO_CS 3     //Number of CS pins per SPI host
68
69
70 /// struct to hold private transaction data (like tx and rx buffer for DMA).
71 typedef struct {
72     spi_transaction_t   *trans;
73     uint32_t *buffer_to_send;   //equals to tx_data, if SPI_TRANS_USE_RXDATA is applied; otherwise if original buffer wasn't in DMA-capable memory, this gets the address of a temporary buffer that is;
74                                 //otherwise sets to the original buffer or NULL if no buffer is assigned.
75     uint32_t *buffer_to_rcv;    // similar to buffer_to_send
76 } spi_trans_priv;
77
78 typedef struct {
79     spi_device_t *device[NO_CS];
80     intr_handle_t intr;
81     spi_dev_t *hw;
82     spi_trans_priv cur_trans_buf;
83     int cur_cs;
84     int prev_cs;
85     lldesc_t *dmadesc_tx;
86     lldesc_t *dmadesc_rx;
87     uint32_t flags;
88     int dma_chan;
89     int max_transfer_sz;
90 #ifdef CONFIG_PM_ENABLE
91     esp_pm_lock_handle_t pm_lock;
92 #endif
93 } spi_host_t;
94
95 typedef struct {
96     spi_clock_reg_t reg;
97     int eff_clk;
98     int dummy_num;
99     int miso_delay;
100 } clock_config_t;
101
102 struct spi_device_t {
103     QueueHandle_t trans_queue;
104     QueueHandle_t ret_queue;
105     spi_device_interface_config_t cfg;
106     clock_config_t clk_cfg;
107     spi_host_t *host;
108 };
109
110 static spi_host_t *spihost[3];
111
112
113 static const char *SPI_TAG = "spi_master";
114 #define SPI_CHECK(a, str, ret_val, ...) \
115     if (!(a)) { \
116         ESP_LOGE(SPI_TAG,"%s(%d): "str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
117         return (ret_val); \
118     }
119
120
121 static void spi_intr(void *arg);
122
123 esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus_config, int dma_chan)
124 {
125     bool spi_chan_claimed, dma_chan_claimed;
126     esp_err_t ret = ESP_OK;
127     esp_err_t err;
128     /* ToDo: remove this when we have flash operations cooperating with this */
129     SPI_CHECK(host!=SPI_HOST, "SPI1 is not supported", ESP_ERR_NOT_SUPPORTED);
130
131     SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
132     SPI_CHECK( dma_chan >= 0 && dma_chan <= 2, "invalid dma channel", ESP_ERR_INVALID_ARG );
133
134     spi_chan_claimed=spicommon_periph_claim(host);
135     SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
136
137     if ( dma_chan != 0 ) {
138         dma_chan_claimed=spicommon_dma_chan_claim(dma_chan);
139         if ( !dma_chan_claimed ) {
140             spicommon_periph_free( host );
141             SPI_CHECK(dma_chan_claimed, "dma channel already in use", ESP_ERR_INVALID_STATE);
142         }
143     }
144
145     spihost[host]=malloc(sizeof(spi_host_t));
146     if (spihost[host]==NULL) {
147         ret = ESP_ERR_NO_MEM;
148         goto cleanup;
149     }
150     memset(spihost[host], 0, sizeof(spi_host_t));
151 #ifdef CONFIG_PM_ENABLE
152     err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_master",
153             &spihost[host]->pm_lock);
154     if (err != ESP_OK) {
155         ret = err;
156         goto cleanup;
157     }
158 #endif //CONFIG_PM_ENABLE
159
160     err = spicommon_bus_initialize_io(host, bus_config, dma_chan, SPICOMMON_BUSFLAG_MASTER|bus_config->flags, &spihost[host]->flags);
161     if (err != ESP_OK) {
162         ret = err;
163         goto cleanup;
164     }
165
166     spihost[host]->dma_chan=dma_chan;
167     if (dma_chan == 0) {
168         spihost[host]->max_transfer_sz = 32;
169     } else {
170         //See how many dma descriptors we need and allocate them
171         int dma_desc_ct=(bus_config->max_transfer_sz+SPI_MAX_DMA_LEN-1)/SPI_MAX_DMA_LEN;
172         if (dma_desc_ct==0) dma_desc_ct=1; //default to 4k when max is not given
173         spihost[host]->max_transfer_sz = dma_desc_ct*SPI_MAX_DMA_LEN;
174         spihost[host]->dmadesc_tx=heap_caps_malloc(sizeof(lldesc_t)*dma_desc_ct, MALLOC_CAP_DMA);
175         spihost[host]->dmadesc_rx=heap_caps_malloc(sizeof(lldesc_t)*dma_desc_ct, MALLOC_CAP_DMA);
176         if (!spihost[host]->dmadesc_tx || !spihost[host]->dmadesc_rx) {
177             ret = ESP_ERR_NO_MEM;
178             goto cleanup;
179         }
180     }
181
182     err = esp_intr_alloc(spicommon_irqsource_for_host(host), ESP_INTR_FLAG_INTRDISABLED, spi_intr, (void*)spihost[host], &spihost[host]->intr);
183     if (err != ESP_OK) {
184         ret = err;
185         goto cleanup;
186     }
187     spihost[host]->hw=spicommon_hw_for_host(host);
188
189     spihost[host]->cur_cs = NO_CS;
190     spihost[host]->prev_cs = NO_CS;
191
192     //Reset DMA
193     spihost[host]->hw->dma_conf.val|=SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST;
194     spihost[host]->hw->dma_out_link.start=0;
195     spihost[host]->hw->dma_in_link.start=0;
196     spihost[host]->hw->dma_conf.val&=~(SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST);
197     //Reset timing
198     spihost[host]->hw->ctrl2.val=0;
199
200     //Disable unneeded ints
201     spihost[host]->hw->slave.rd_buf_done=0;
202     spihost[host]->hw->slave.wr_buf_done=0;
203     spihost[host]->hw->slave.rd_sta_done=0;
204     spihost[host]->hw->slave.wr_sta_done=0;
205     spihost[host]->hw->slave.rd_buf_inten=0;
206     spihost[host]->hw->slave.wr_buf_inten=0;
207     spihost[host]->hw->slave.rd_sta_inten=0;
208     spihost[host]->hw->slave.wr_sta_inten=0;
209
210     //Force a transaction done interrupt. This interrupt won't fire yet because we initialized the SPI interrupt as
211     //disabled.  This way, we can just enable the SPI interrupt and the interrupt handler will kick in, handling
212     //any transactions that are queued.
213     spihost[host]->hw->slave.trans_inten=1;
214     spihost[host]->hw->slave.trans_done=1;
215
216     return ESP_OK;
217
218 cleanup:
219     if (spihost[host]) {
220         free(spihost[host]->dmadesc_tx);
221         free(spihost[host]->dmadesc_rx);
222 #ifdef CONFIG_PM_ENABLE
223         if (spihost[host]->pm_lock) {
224             esp_pm_lock_delete(spihost[host]->pm_lock);
225         }
226 #endif
227     }
228     free(spihost[host]);
229     spicommon_periph_free(host);
230     spicommon_dma_chan_free(dma_chan);
231     return ret;
232 }
233
234 esp_err_t spi_bus_free(spi_host_device_t host)
235 {
236     int x;
237     SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
238     SPI_CHECK(spihost[host]!=NULL, "host not in use", ESP_ERR_INVALID_STATE);
239     for (x=0; x<NO_CS; x++) {
240         SPI_CHECK(spihost[host]->device[x]==NULL, "not all CSses freed", ESP_ERR_INVALID_STATE);
241     }
242
243     if ( spihost[host]->dma_chan > 0 ) {
244         spicommon_dma_chan_free ( spihost[host]->dma_chan );
245     }
246 #ifdef CONFIG_PM_ENABLE
247     esp_pm_lock_delete(spihost[host]->pm_lock);
248 #endif
249     spihost[host]->hw->slave.trans_inten=0;
250     spihost[host]->hw->slave.trans_done=0;
251     esp_intr_free(spihost[host]->intr);
252     spicommon_periph_free(host);
253     free(spihost[host]->dmadesc_tx);
254     free(spihost[host]->dmadesc_rx);
255     free(spihost[host]);
256     spihost[host]=NULL;
257     return ESP_OK;
258 }
259
260 void spi_get_timing(bool gpio_is_used, int input_delay_ns, int eff_clk, int* dummy_o, int* cycles_remain_o)
261 {
262     const int apbclk_kHz = APB_CLK_FREQ/1000;
263     const int apbclk_n = APB_CLK_FREQ/eff_clk;
264     const int gpio_delay_ns=(gpio_is_used?25:0);
265
266     //calculate how many apb clocks a period has, the 1 is to compensate in case ``input_delay_ns`` is rounded off.
267     int apb_period_n = (1 + input_delay_ns + gpio_delay_ns)*apbclk_kHz/1000/1000;
268     int dummy_required = apb_period_n/apbclk_n;
269
270     int miso_delay = 0;
271     if (dummy_required > 0) {
272         //due to the clock delay between master and slave, there's a range in which data is random
273         //give MISO a delay if needed to make sure we sample at the time MISO is stable
274         miso_delay = (dummy_required+1)*apbclk_n-apb_period_n-1;
275     } else {
276         //if the dummy is not required, maybe we should also delay half a SPI clock if the data comes too early
277         if (apb_period_n*4 <= apbclk_n) miso_delay = -1;
278     }
279     if (dummy_o!=NULL) *dummy_o = dummy_required;
280     if (cycles_remain_o!=NULL) *cycles_remain_o = miso_delay;
281     ESP_LOGD(SPI_TAG,"eff: %d, limit: %dk(/%d), %d dummy, %d delay", eff_clk/1000, apbclk_kHz/(apb_period_n+1), apb_period_n, dummy_required, miso_delay);
282 }
283
284 int spi_get_freq_limit(bool gpio_is_used, int input_delay_ns)
285 {
286     const int apbclk_kHz = APB_CLK_FREQ/1000;
287     const int gpio_delay_ns=(gpio_is_used?25:0);
288
289     //calculate how many apb clocks a period has, the 1 is to compensate in case ``input_delay_ns`` is rounded off.
290     int apb_period_n = (1 + input_delay_ns + gpio_delay_ns)*apbclk_kHz/1000/1000;
291     return APB_CLK_FREQ/(apb_period_n+1);
292 }
293
294 /*
295  Add a device. This allocates a CS line for the device, allocates memory for the device structure and hooks
296  up the CS pin to whatever is specified.
297 */
298 esp_err_t spi_bus_add_device(spi_host_device_t host, const spi_device_interface_config_t *dev_config, spi_device_handle_t *handle)
299 {
300     int freecs;
301     int apbclk=APB_CLK_FREQ;
302     int eff_clk;
303     int duty_cycle;
304     int dummy_required;
305     int miso_delay;
306
307     spi_clock_reg_t clk_reg;
308     SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
309     SPI_CHECK(spihost[host]!=NULL, "host not initialized", ESP_ERR_INVALID_STATE);
310     SPI_CHECK(dev_config->spics_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(dev_config->spics_io_num), "spics pin invalid", ESP_ERR_INVALID_ARG);
311     SPI_CHECK(dev_config->clock_speed_hz > 0, "invalid sclk speed", ESP_ERR_INVALID_ARG);
312     for (freecs=0; freecs<NO_CS; freecs++) {
313         //See if this slot is free; reserve if it is by putting a dummy pointer in the slot. We use an atomic compare&swap to make this thread-safe.
314         if (__sync_bool_compare_and_swap(&spihost[host]->device[freecs], NULL, (spi_device_t *)1)) break;
315     }
316     SPI_CHECK(freecs!=NO_CS, "no free cs pins for host", ESP_ERR_NOT_FOUND);
317     //The hardware looks like it would support this, but actually setting cs_ena_pretrans when transferring in full
318     //duplex mode does absolutely nothing on the ESP32.
319     SPI_CHECK(dev_config->cs_ena_pretrans <= 1 || (dev_config->flags & SPI_DEVICE_HALFDUPLEX), "cs pretrans delay > 1 incompatible with full-duplex", ESP_ERR_INVALID_ARG);
320     SPI_CHECK( dev_config->cs_ena_pretrans != 1 || (dev_config->address_bits == 0 && dev_config->command_bits == 0) ||
321         (dev_config->flags & SPI_DEVICE_HALFDUPLEX), "In full-duplex mode, only support cs pretrans delay = 1 and without address_bits and command_bits", ESP_ERR_INVALID_ARG);
322
323     duty_cycle = (dev_config->duty_cycle_pos==0? 128: dev_config->duty_cycle_pos);
324     eff_clk = spi_cal_clock(apbclk, dev_config->clock_speed_hz, duty_cycle, (uint32_t*)&clk_reg);
325     int freq_limit = spi_get_freq_limit(!(spihost[host]->flags&SPICOMMON_BUSFLAG_NATIVE_PINS), dev_config->input_delay_ns);
326     //GPIO matrix can only change data at 80Mhz rate, which only allows 40MHz SPI clock.
327     SPI_CHECK(eff_clk <= 40*1000*1000 || spihost[host]->flags&SPICOMMON_BUSFLAG_NATIVE_PINS, "80MHz only supported on native pins", ESP_ERR_INVALID_ARG);
328     //Speed >=40MHz over GPIO matrix needs a dummy cycle, but these don't work for full-duplex connections.
329     spi_get_timing(!(spihost[host]->flags&SPICOMMON_BUSFLAG_NATIVE_PINS), dev_config->input_delay_ns, eff_clk, &dummy_required, &miso_delay);
330     SPI_CHECK( dev_config->flags & SPI_DEVICE_HALFDUPLEX || dummy_required == 0 ||
331             dev_config->flags & SPI_DEVICE_NO_DUMMY,
332 "When GPIO matrix is used in full-duplex mode at frequency > %.1fMHz, device cannot read correct data.\n\
333 Please note the SPI can only work at divisors of 80MHz, and the driver always tries to find the closest frequency to your configuration.\n\
334 Specify ``SPI_DEVICE_NO_DUMMY`` to ignore this checking. Then you can output data at higher speed, or read data at your own risk.",
335             ESP_ERR_INVALID_ARG, freq_limit/1000./1000 );
336
337     //Allocate memory for device
338     spi_device_t *dev=malloc(sizeof(spi_device_t));
339     if (dev==NULL) goto nomem;
340     memset(dev, 0, sizeof(spi_device_t));
341     spihost[host]->device[freecs]=dev;
342
343     //Allocate queues, set defaults
344     dev->trans_queue=xQueueCreate(dev_config->queue_size, sizeof(spi_trans_priv));
345     dev->ret_queue=xQueueCreate(dev_config->queue_size, sizeof(spi_trans_priv));
346     if (!dev->trans_queue || !dev->ret_queue) goto nomem;
347     dev->host=spihost[host];
348
349     //We want to save a copy of the dev config in the dev struct.
350     memcpy(&dev->cfg, dev_config, sizeof(spi_device_interface_config_t));
351     dev->cfg.duty_cycle_pos = duty_cycle;
352     // TODO: if we have to change the apb clock among transactions, re-calculate this each time the apb clock lock is acquired.
353     dev->clk_cfg= (clock_config_t) {
354         .eff_clk = eff_clk,
355         .dummy_num = dummy_required,
356         .reg = clk_reg,
357         .miso_delay = miso_delay,
358     };
359
360     //Set CS pin, CS options
361     if (dev_config->spics_io_num >= 0) {
362         gpio_set_direction(dev_config->spics_io_num, GPIO_MODE_OUTPUT);
363         spicommon_cs_initialize(host, dev_config->spics_io_num, freecs, !(spihost[host]->flags&SPICOMMON_BUSFLAG_NATIVE_PINS));
364     }
365     if (dev_config->flags&SPI_DEVICE_CLK_AS_CS) {
366         spihost[host]->hw->pin.master_ck_sel |= (1<<freecs);
367     } else {
368         spihost[host]->hw->pin.master_ck_sel &= (1<<freecs);
369     }
370     if (dev_config->flags&SPI_DEVICE_POSITIVE_CS) {
371         spihost[host]->hw->pin.master_cs_pol |= (1<<freecs);
372     } else {
373         spihost[host]->hw->pin.master_cs_pol &= (1<<freecs);
374     }
375     spihost[host]->hw->ctrl2.mosi_delay_mode = 0;
376     spihost[host]->hw->ctrl2.mosi_delay_num = 0;
377     *handle=dev;
378     ESP_LOGD(SPI_TAG, "SPI%d: New device added to CS%d, effective clock: %dkHz", host, freecs, dev->clk_cfg.eff_clk/1000);
379     return ESP_OK;
380
381 nomem:
382     if (dev) {
383         if (dev->trans_queue) vQueueDelete(dev->trans_queue);
384         if (dev->ret_queue) vQueueDelete(dev->ret_queue);
385     }
386     free(dev);
387     return ESP_ERR_NO_MEM;
388 }
389
390 esp_err_t spi_bus_remove_device(spi_device_handle_t handle)
391 {
392     int x;
393     SPI_CHECK(handle!=NULL, "invalid handle", ESP_ERR_INVALID_ARG);
394     //These checks aren't exhaustive; another thread could sneak in a transaction inbetween. These are only here to
395     //catch design errors and aren't meant to be triggered during normal operation.
396     SPI_CHECK(uxQueueMessagesWaiting(handle->trans_queue)==0, "Have unfinished transactions", ESP_ERR_INVALID_STATE);
397     SPI_CHECK(handle->host->cur_cs == NO_CS || handle->host->device[handle->host->cur_cs]!=handle, "Have unfinished transactions", ESP_ERR_INVALID_STATE);
398     SPI_CHECK(uxQueueMessagesWaiting(handle->ret_queue)==0, "Have unfinished transactions", ESP_ERR_INVALID_STATE);
399
400     //Kill queues
401     vQueueDelete(handle->trans_queue);
402     vQueueDelete(handle->ret_queue);
403     //Remove device from list of csses and free memory
404     for (x=0; x<NO_CS; x++) {
405         if (handle->host->device[x] == handle){
406             handle->host->device[x]=NULL;
407             if ( x == handle->host->prev_cs ) handle->host->prev_cs = NO_CS;
408         }
409     }
410     free(handle);
411     return ESP_OK;
412 }
413
414 static int spi_freq_for_pre_n(int fapb, int pre, int n) {
415     return (fapb / (pre * n));
416 }
417
418 int spi_cal_clock(int fapb, int hz, int duty_cycle, uint32_t *reg_o)
419 {
420     spi_clock_reg_t reg;
421     int eff_clk;
422
423     //In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
424     if (hz>((fapb/4)*3)) {
425         //Using Fapb directly will give us the best result here.
426         reg.clkcnt_l=0;
427         reg.clkcnt_h=0;
428         reg.clkcnt_n=0;
429         reg.clkdiv_pre=0;
430         reg.clk_equ_sysclk=1;
431         eff_clk=fapb;
432     } else {
433         //For best duty cycle resolution, we want n to be as close to 32 as possible, but
434         //we also need a pre/n combo that gets us as close as possible to the intended freq.
435         //To do this, we bruteforce n and calculate the best pre to go along with that.
436         //If there's a choice between pre/n combos that give the same result, use the one
437         //with the higher n.
438         int pre, n, h, l;
439         int bestn=-1;
440         int bestpre=-1;
441         int besterr=0;
442         int errval;
443         for (n=2; n<=64; n++) { //Start at 2: we need to be able to set h/l so we have at least one high and one low pulse.
444             //Effectively, this does pre=round((fapb/n)/hz).
445             pre=((fapb/n)+(hz/2))/hz;
446             if (pre<=0) pre=1;
447             if (pre>8192) pre=8192;
448             errval=abs(spi_freq_for_pre_n(fapb, pre, n)-hz);
449             if (bestn==-1 || errval<=besterr) {
450                 besterr=errval;
451                 bestn=n;
452                 bestpre=pre;
453             }
454         }
455
456         n=bestn;
457         pre=bestpre;
458         l=n;
459         //This effectively does round((duty_cycle*n)/256)
460         h=(duty_cycle*n+127)/256;
461         if (h<=0) h=1;
462
463         reg.clk_equ_sysclk=0;
464         reg.clkcnt_n=n-1;
465         reg.clkdiv_pre=pre-1;
466         reg.clkcnt_h=h-1;
467         reg.clkcnt_l=l-1;
468         eff_clk=spi_freq_for_pre_n(fapb, pre, n);
469     }
470     if ( reg_o != NULL ) *reg_o = reg.val;
471     return eff_clk;
472 }
473
474 /*
475  * Set the spi clock according to pre-calculated register value.
476  */
477 static inline void spi_set_clock(spi_dev_t *hw, spi_clock_reg_t reg) {
478     hw->clock.val = reg.val;
479 }
480
481 //This is run in interrupt context and apart from initialization and destruction, this is the only code
482 //touching the host (=spihost[x]) variable. The rest of the data arrives in queues. That is why there are
483 //no muxes in this code.
484 static void IRAM_ATTR spi_intr(void *arg)
485 {
486     int i;
487     BaseType_t r;
488     BaseType_t do_yield=pdFALSE;
489     spi_trans_priv *trans_buf=NULL;
490     spi_transaction_t *trans=NULL;
491     spi_host_t *host=(spi_host_t*)arg;
492
493     //Ignore all but the trans_done int.
494     if (!host->hw->slave.trans_done) return;
495
496     /*------------ deal with the in-flight transaction -----------------*/
497     if (host->cur_cs != NO_CS) {
498         spi_transaction_t *cur_trans = host->cur_trans_buf.trans;
499         //Okay, transaction is done.
500         if (host->cur_trans_buf.buffer_to_rcv && host->dma_chan == 0 ) {
501             //Need to copy from SPI regs to result buffer.
502             for (int x=0; x < cur_trans->rxlength; x+=32) {
503                 //Do a memcpy to get around possible alignment issues in rx_buffer
504                 uint32_t word=host->hw->data_buf[x/32];
505                 int len=cur_trans->rxlength-x;
506                 if (len>32) len=32;
507                 memcpy(&host->cur_trans_buf.buffer_to_rcv[x/32], &word, (len+7)/8);
508             }
509         }
510         //Call post-transaction callback, if any
511         if (host->device[host->cur_cs]->cfg.post_cb) host->device[host->cur_cs]->cfg.post_cb(cur_trans);
512         //Return transaction descriptor.
513         xQueueSendFromISR(host->device[host->cur_cs]->ret_queue, &host->cur_trans_buf, &do_yield);
514         host->cur_cs = NO_CS;
515     }
516     //Tell common code DMA workaround that our DMA channel is idle. If needed, the code will do a DMA reset.
517     if (host->dma_chan) spicommon_dmaworkaround_idle(host->dma_chan);
518
519     /*------------ new transaction starts here ------------------*/
520     //ToDo: This is a stupidly simple low-cs-first priority scheme. Make this configurable somehow. - JD
521     for (i=0; i<NO_CS; i++) {
522         if (host->device[i]) {
523             r=xQueueReceiveFromISR(host->device[i]->trans_queue, &host->cur_trans_buf, &do_yield);
524             trans_buf = &host->cur_trans_buf;
525             //Stop looking if we have a transaction to send.
526             if (r) break;
527         }
528     }
529     if (i==NO_CS) {
530         //No packet waiting. Disable interrupt.
531         esp_intr_disable(host->intr);
532 #ifdef CONFIG_PM_ENABLE
533         //Release APB frequency lock
534         esp_pm_lock_release(host->pm_lock);
535 #endif
536     } else {
537         host->hw->slave.trans_done=0; //clear int bit
538         //We have a transaction. Send it.
539         spi_device_t *dev=host->device[i];
540         trans = trans_buf->trans;
541         host->cur_cs=i;
542         //We should be done with the transmission.
543         assert(host->hw->cmd.usr == 0);
544
545         //Reconfigure according to device settings, but only if we change CSses.
546         if (i!=host->prev_cs) {
547             spi_set_clock(host->hw, dev->clk_cfg.reg);
548             //Configure bit order
549             host->hw->ctrl.rd_bit_order=(dev->cfg.flags & SPI_DEVICE_RXBIT_LSBFIRST)?1:0;
550             host->hw->ctrl.wr_bit_order=(dev->cfg.flags & SPI_DEVICE_TXBIT_LSBFIRST)?1:0;
551
552             //Configure polarity
553             if (dev->cfg.mode==0) {
554                 host->hw->pin.ck_idle_edge=0;
555                 host->hw->user.ck_out_edge=0;
556             } else if (dev->cfg.mode==1) {
557                 host->hw->pin.ck_idle_edge=0;
558                 host->hw->user.ck_out_edge=1;
559             } else if (dev->cfg.mode==2) {
560                 host->hw->pin.ck_idle_edge=1;
561                 host->hw->user.ck_out_edge=1;
562             } else if (dev->cfg.mode==3) {
563                 host->hw->pin.ck_idle_edge=1;
564                 host->hw->user.ck_out_edge=0;
565             }
566             //Configure misc stuff
567             host->hw->user.doutdin=(dev->cfg.flags & SPI_DEVICE_HALFDUPLEX)?0:1;
568             host->hw->user.sio=(dev->cfg.flags & SPI_DEVICE_3WIRE)?1:0;
569
570             host->hw->ctrl2.setup_time=dev->cfg.cs_ena_pretrans-1;
571             host->hw->user.cs_setup=dev->cfg.cs_ena_pretrans?1:0;
572             //set hold_time to 0 will not actually append delay to CS
573             //set it to 1 since we do need at least one clock of hold time in most cases
574             host->hw->ctrl2.hold_time=dev->cfg.cs_ena_posttrans;
575             if ( host->hw->ctrl2.hold_time == 0 ) host->hw->ctrl2.hold_time = 1;
576             host->hw->user.cs_hold=1;
577
578             //Configure CS pin
579             host->hw->pin.cs0_dis=(i==0)?0:1;
580             host->hw->pin.cs1_dis=(i==1)?0:1;
581             host->hw->pin.cs2_dis=(i==2)?0:1;
582         }
583         host->prev_cs = i;
584         //Reset SPI peripheral
585         host->hw->dma_conf.val |= SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST;
586         host->hw->dma_out_link.start=0;
587         host->hw->dma_in_link.start=0;
588         host->hw->dma_conf.val &= ~(SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST);
589         host->hw->dma_conf.out_data_burst_en=1;
590         //Set up QIO/DIO if needed
591         host->hw->ctrl.val &= ~(SPI_FREAD_DUAL|SPI_FREAD_QUAD|SPI_FREAD_DIO|SPI_FREAD_QIO);
592         host->hw->user.val &= ~(SPI_FWRITE_DUAL|SPI_FWRITE_QUAD|SPI_FWRITE_DIO|SPI_FWRITE_QIO);
593         if (trans->flags & SPI_TRANS_MODE_DIO) {
594             if (trans->flags & SPI_TRANS_MODE_DIOQIO_ADDR) {
595                 host->hw->ctrl.fread_dio=1;
596                 host->hw->user.fwrite_dio=1;
597             } else {
598                 host->hw->ctrl.fread_dual=1;
599                 host->hw->user.fwrite_dual=1;
600             }
601             host->hw->ctrl.fastrd_mode=1;
602         } else if (trans->flags & SPI_TRANS_MODE_QIO) {
603             if (trans->flags & SPI_TRANS_MODE_DIOQIO_ADDR) {
604                 host->hw->ctrl.fread_qio=1;
605                 host->hw->user.fwrite_qio=1;
606             } else {
607                 host->hw->ctrl.fread_quad=1;
608                 host->hw->user.fwrite_quad=1;
609             }
610             host->hw->ctrl.fastrd_mode=1;
611         }
612
613         //Fill DMA descriptors
614         int extra_dummy=0;
615         if (trans_buf->buffer_to_rcv) {
616             host->hw->user.usr_miso_highpart=0;
617             if (host->dma_chan == 0) {
618                 //No need to setup anything; we'll copy the result out of the work registers directly later.
619             } else {
620                 spicommon_dmaworkaround_transfer_active(host->dma_chan); //mark channel as active
621                 spicommon_setup_dma_desc_links(host->dmadesc_rx, ((trans->rxlength+7)/8), (uint8_t*)trans_buf->buffer_to_rcv, true);
622                 host->hw->dma_in_link.addr=(int)(&host->dmadesc_rx[0]) & 0xFFFFF;
623                 host->hw->dma_in_link.start=1;
624             }
625             //when no_dummy is not set and in half-duplex mode, sets the dummy bit if RX phase exist
626             if (((dev->cfg.flags&SPI_DEVICE_NO_DUMMY)==0) && (dev->cfg.flags&SPI_DEVICE_HALFDUPLEX)) {
627                 extra_dummy=dev->clk_cfg.dummy_num;
628             }
629         } else {
630             //DMA temporary workaround: let RX DMA work somehow to avoid the issue in ESP32 v0/v1 silicon
631             if (host->dma_chan != 0 ) {
632                 host->hw->dma_in_link.addr=0;
633                 host->hw->dma_in_link.start=1;
634             }
635         }
636
637
638         if (trans_buf->buffer_to_send) {
639             if (host->dma_chan == 0) {
640                 //Need to copy data to registers manually
641                 for (int x=0; x < trans->length; x+=32) {
642                     //Use memcpy to get around alignment issues for txdata
643                     uint32_t word;
644                     memcpy(&word, &trans_buf->buffer_to_send[x/32], 4);
645                     host->hw->data_buf[(x/32)+8]=word;
646                 }
647                 host->hw->user.usr_mosi_highpart=1;
648             } else {
649                 spicommon_dmaworkaround_transfer_active(host->dma_chan); //mark channel as active
650                 spicommon_setup_dma_desc_links(host->dmadesc_tx, (trans->length+7)/8, (uint8_t*)trans_buf->buffer_to_send, false);
651                 host->hw->user.usr_mosi_highpart=0;
652                 host->hw->dma_out_link.addr=(int)(&host->dmadesc_tx[0]) & 0xFFFFF;
653                 host->hw->dma_out_link.start=1;
654                 host->hw->user.usr_mosi_highpart=0;
655             }
656         }
657
658         //SPI iface needs to be configured for a delay in some cases.
659         //configure dummy bits
660         host->hw->user.usr_dummy=(dev->cfg.dummy_bits+extra_dummy)?1:0;
661         host->hw->user1.usr_dummy_cyclelen=dev->cfg.dummy_bits+extra_dummy-1;
662
663         int miso_long_delay = 0;
664         if (dev->clk_cfg.miso_delay<0) {
665             //if the data comes too late, delay half a SPI clock to improve reading
666             miso_long_delay = 1;
667             host->hw->ctrl2.miso_delay_num = 0;
668         } else {
669             //if the data is so fast that dummy_bit is used, delay some apb clocks to meet the timing
670             host->hw->ctrl2.miso_delay_num = (extra_dummy? dev->clk_cfg.miso_delay: 0);
671         }
672
673         if (dev->cfg.mode==0) {
674             host->hw->ctrl2.miso_delay_mode=miso_long_delay?2:0;
675         } else if (dev->cfg.mode==1) {
676             host->hw->ctrl2.miso_delay_mode=miso_long_delay?1:0;
677         } else if (dev->cfg.mode==2) {
678             host->hw->ctrl2.miso_delay_mode=miso_long_delay?1:0;
679         } else if (dev->cfg.mode==3) {
680             host->hw->ctrl2.miso_delay_mode=miso_long_delay?2:0;
681         }
682
683         host->hw->mosi_dlen.usr_mosi_dbitlen=trans->length-1;
684         if ( dev->cfg.flags & SPI_DEVICE_HALFDUPLEX ) {
685             host->hw->miso_dlen.usr_miso_dbitlen=trans->rxlength-1;
686         } else {
687             //rxlength is not used in full-duplex mode
688             host->hw->miso_dlen.usr_miso_dbitlen=trans->length-1;
689         }
690
691         //Configure bit sizes, load addr and command
692         int cmdlen;
693         if ( trans->flags & SPI_TRANS_VARIABLE_CMD ) {
694             cmdlen = ((spi_transaction_ext_t*)trans)->command_bits;
695         } else {
696             cmdlen = dev->cfg.command_bits;
697         }
698         int addrlen;
699         if ( trans->flags & SPI_TRANS_VARIABLE_ADDR ) {
700             addrlen = ((spi_transaction_ext_t*)trans)->address_bits;
701         } else {
702             addrlen = dev->cfg.address_bits;
703         }
704         host->hw->user1.usr_addr_bitlen=addrlen-1;
705         host->hw->user2.usr_command_bitlen=cmdlen-1;
706         host->hw->user.usr_addr=addrlen?1:0;
707         host->hw->user.usr_command=cmdlen?1:0;
708
709         // output command will be sent from bit 7 to 0 of command_value, and then bit 15 to 8 of the same register field.
710         uint16_t command = trans->cmd << (16-cmdlen);    //shift to MSB
711         host->hw->user2.usr_command_value = (command>>8)|(command<<8);  //swap the first and second byte
712         // shift the address to MSB of addr (and maybe slv_wr_status) register.
713         // output address will be sent from MSB to LSB of addr register, then comes the MSB to LSB of slv_wr_status register.
714         if (addrlen>32) {
715             host->hw->addr = trans->addr >> (addrlen- 32);
716             host->hw->slv_wr_status = trans->addr << (64 - addrlen);
717         } else {
718             host->hw->addr = trans->addr << (32 - addrlen);
719         }
720
721         host->hw->user.usr_mosi=( (!(dev->cfg.flags & SPI_DEVICE_HALFDUPLEX) && trans_buf->buffer_to_rcv) || trans_buf->buffer_to_send)?1:0;
722         host->hw->user.usr_miso=(trans_buf->buffer_to_rcv)?1:0;
723
724         //Call pre-transmission callback, if any
725         if (dev->cfg.pre_cb) dev->cfg.pre_cb(trans);
726         //Kick off transfer
727         host->hw->cmd.usr=1;
728     }
729     if (do_yield) portYIELD_FROM_ISR();
730 }
731
732
733 esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *trans_desc,  TickType_t ticks_to_wait)
734 {
735     esp_err_t ret = ESP_OK;
736     BaseType_t r;
737     SPI_CHECK(handle!=NULL, "invalid dev handle", ESP_ERR_INVALID_ARG);
738     //check transmission length
739     SPI_CHECK((trans_desc->flags & SPI_TRANS_USE_RXDATA)==0 ||trans_desc->rxlength <= 32, "rxdata transfer > 32 bits without configured DMA", ESP_ERR_INVALID_ARG);
740     SPI_CHECK((trans_desc->flags & SPI_TRANS_USE_TXDATA)==0 ||trans_desc->length <= 32, "txdata transfer > 32 bits without configured DMA", ESP_ERR_INVALID_ARG);
741     SPI_CHECK(trans_desc->length <= handle->host->max_transfer_sz*8, "txdata transfer > host maximum", ESP_ERR_INVALID_ARG);
742     SPI_CHECK(trans_desc->rxlength <= handle->host->max_transfer_sz*8, "rxdata transfer > host maximum", ESP_ERR_INVALID_ARG);
743     SPI_CHECK((handle->cfg.flags & SPI_DEVICE_HALFDUPLEX) || trans_desc->rxlength <= trans_desc->length, "rx length > tx length in full duplex mode", ESP_ERR_INVALID_ARG);
744     //check working mode
745     SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && (handle->cfg.flags & SPI_DEVICE_3WIRE)), "incompatible iface params", ESP_ERR_INVALID_ARG);
746     SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && (!(handle->cfg.flags & SPI_DEVICE_HALFDUPLEX))), "incompatible iface params", ESP_ERR_INVALID_ARG);
747     SPI_CHECK( !(handle->cfg.flags & SPI_DEVICE_HALFDUPLEX) || handle->host->dma_chan == 0 || !(trans_desc->flags & SPI_TRANS_USE_RXDATA || trans_desc->rx_buffer != NULL)
748         || !(trans_desc->flags & SPI_TRANS_USE_TXDATA || trans_desc->tx_buffer!=NULL), "SPI half duplex mode does not support using DMA with both MOSI and MISO phases.", ESP_ERR_INVALID_ARG );
749     //In Full duplex mode, default rxlength to be the same as length, if not filled in.
750     // set rxlength to length is ok, even when rx buffer=NULL
751     if (trans_desc->rxlength==0 && !(handle->cfg.flags & SPI_DEVICE_HALFDUPLEX)) {
752         trans_desc->rxlength=trans_desc->length;
753     }
754
755     spi_trans_priv trans_buf;
756     memset( &trans_buf, 0, sizeof(spi_trans_priv) );
757     trans_buf.trans = trans_desc;
758
759     // rx memory assign
760     if ( trans_desc->flags & SPI_TRANS_USE_RXDATA ) {
761         trans_buf.buffer_to_rcv = (uint32_t*)&trans_desc->rx_data[0];
762     } else {
763         //if not use RXDATA neither rx_buffer, buffer_to_rcv assigned to NULL
764         trans_buf.buffer_to_rcv = trans_desc->rx_buffer;
765     }
766     if ( trans_buf.buffer_to_rcv && handle->host->dma_chan && (!esp_ptr_dma_capable( trans_buf.buffer_to_rcv ) || ((int)trans_buf.buffer_to_rcv%4!=0)) ) {
767         //if rxbuf in the desc not DMA-capable, malloc a new one. The rx buffer need to be length of multiples of 32 bits to avoid heap corruption.
768         ESP_LOGV( SPI_TAG, "Allocate RX buffer for DMA" );
769         trans_buf.buffer_to_rcv = heap_caps_malloc((trans_desc->rxlength+31)/8, MALLOC_CAP_DMA);
770         if ( trans_buf.buffer_to_rcv==NULL ) {
771             ret = ESP_ERR_NO_MEM;
772             goto clean_up;
773         }
774     }
775
776     const uint32_t *txdata;
777     // tx memory assign
778     if ( trans_desc->flags & SPI_TRANS_USE_TXDATA ) {
779         txdata = (uint32_t*)&trans_desc->tx_data[0];
780     } else {
781         //if not use TXDATA neither tx_buffer, tx data assigned to NULL
782         txdata = trans_desc->tx_buffer ;
783     }
784     if ( txdata && handle->host->dma_chan && !esp_ptr_dma_capable( txdata )) {
785         //if txbuf in the desc not DMA-capable, malloc a new one
786         ESP_LOGV( SPI_TAG, "Allocate TX buffer for DMA" );
787         trans_buf.buffer_to_send = heap_caps_malloc((trans_desc->length+7)/8, MALLOC_CAP_DMA);
788         if ( trans_buf.buffer_to_send==NULL ) {
789             ret = ESP_ERR_NO_MEM;
790             goto clean_up;
791         }
792         memcpy( trans_buf.buffer_to_send, txdata, (trans_desc->length+7)/8 );
793     } else {
794         // else use the original buffer (forced-conversion) or assign to NULL
795         trans_buf.buffer_to_send = (uint32_t*)txdata;
796     }
797
798 #ifdef CONFIG_PM_ENABLE
799     esp_pm_lock_acquire(handle->host->pm_lock);
800 #endif
801     r=xQueueSend(handle->trans_queue, (void*)&trans_buf, ticks_to_wait);
802     if (!r) {
803         ret = ESP_ERR_TIMEOUT;
804 #ifdef CONFIG_PM_ENABLE
805         //Release APB frequency lock
806         esp_pm_lock_release(handle->host->pm_lock);
807 #endif
808         goto clean_up;
809     }
810     esp_intr_enable(handle->host->intr);
811     return ESP_OK;
812
813 clean_up:
814     // free malloc-ed buffer (if needed) before return.
815     if ( (void*)trans_buf.buffer_to_rcv != trans_desc->rx_buffer && (void*)trans_buf.buffer_to_rcv != &trans_desc->rx_data[0] ) {
816         free( trans_buf.buffer_to_rcv );
817     }
818     if ( (void*)trans_buf.buffer_to_send!= trans_desc->tx_buffer && (void*)trans_buf.buffer_to_send != &trans_desc->tx_data[0] ) {
819         free( trans_buf.buffer_to_send );
820     }
821     assert( ret != ESP_OK );
822     return ret;
823 }
824
825 esp_err_t spi_device_get_trans_result(spi_device_handle_t handle, spi_transaction_t **trans_desc, TickType_t ticks_to_wait)
826 {
827     BaseType_t r;
828     spi_trans_priv trans_buf;
829
830     SPI_CHECK(handle!=NULL, "invalid dev handle", ESP_ERR_INVALID_ARG);
831     r=xQueueReceive(handle->ret_queue, (void*)&trans_buf, ticks_to_wait);
832     if (!r) {
833         // The memory occupied by rx and tx DMA buffer destroyed only when receiving from the queue (transaction finished).
834         // If timeout, wait and retry.
835         // Every on-flight transaction request occupies internal memory as DMA buffer if needed.
836         return ESP_ERR_TIMEOUT;
837     }
838
839     (*trans_desc) = trans_buf.trans;
840
841     if ( (void*)trans_buf.buffer_to_send != &(*trans_desc)->tx_data[0] && trans_buf.buffer_to_send != (*trans_desc)->tx_buffer ) {
842         free( trans_buf.buffer_to_send );
843     }
844
845     //copy data from temporary DMA-capable buffer back to IRAM buffer and free the temporary one.
846     if ( (void*)trans_buf.buffer_to_rcv != &(*trans_desc)->rx_data[0] && trans_buf.buffer_to_rcv != (*trans_desc)->rx_buffer ) {
847         if ( (*trans_desc)->flags & SPI_TRANS_USE_RXDATA ) {
848             memcpy( (uint8_t*)&(*trans_desc)->rx_data[0], trans_buf.buffer_to_rcv, ((*trans_desc)->rxlength+7)/8 );
849         } else {
850             memcpy( (*trans_desc)->rx_buffer, trans_buf.buffer_to_rcv, ((*trans_desc)->rxlength+7)/8 );
851         }
852         free( trans_buf.buffer_to_rcv );
853     }
854
855     return ESP_OK;
856 }
857
858 //Porcelain to do one blocking transmission.
859 esp_err_t spi_device_transmit(spi_device_handle_t handle, spi_transaction_t *trans_desc)
860 {
861     esp_err_t ret;
862     spi_transaction_t *ret_trans;
863     //ToDo: check if any spi transfers in flight
864     ret=spi_device_queue_trans(handle, trans_desc, portMAX_DELAY);
865     if (ret!=ESP_OK) return ret;
866     ret=spi_device_get_trans_result(handle, &ret_trans, portMAX_DELAY);
867     if (ret!=ESP_OK) return ret;
868     assert(ret_trans==trans_desc);
869     return ESP_OK;
870 }
871