components/spidriver/spi_master_lobo.c

Sat, 29 Jun 2024 16:09:03 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 29 Jun 2024 16:09:03 +0200
branch
idf 5.1
changeset 140
ac6ad7bd55c3
parent 129
31f9d3e4a85f
permissions
-rw-r--r--

Version 0.4.1 Fixed deprecation message. Ignore WiFi channel change event

0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
2 //
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
3 // Licensed under the Apache License, Version 2.0 (the "License");
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
4 // you may not use this file except in compliance with the License.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
5 // You may obtain a copy of the License at
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
6
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
7 // http://www.apache.org/licenses/LICENSE-2.0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
8 //
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
9 // Unless required by applicable law or agreed to in writing, software
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
10 // distributed under the License is distributed on an "AS IS" BASIS,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
12 // See the License for the specific language governing permissions and
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
13 // limitations under the License.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
14
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
15
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
16 /*
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
17 ----------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
18 Non DMA version of the spi_master driver
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
19 ----------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
20 ------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
21 Based on esp-idf 'spi_master', modified by LoBo (https://github.com/loboris) 03/2017
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
22 ------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
23
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
24 * Transfers data to SPI device in direct mode, not using DMA
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
25 * All configuration options (bus, device, transaction) are the same as in spi_master driver
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
26 * Transfers uses the semaphore (taken in select function & given in deselect function) to protect the transfer
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
27 * Number of the devices attached to the bus which uses hardware CS can be 3 ('NO_CS')
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
28 * Additional devices which uses software CS can be attached to the bus, up to 'NO_DEV'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
29 * 'spi_bus_initialize' & 'spi_bus_remove' functions are removed, spi bus is initiated/removed in spi_lobo_bus_add_device/spi_lobo_bus_remove_device when needed
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
30 * 'spi_lobo_bus_add_device' function has added parameter 'bus_config' and automatically initializes spi bus device if not already initialized
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
31 * 'spi_lobo_bus_remove_device' automatically removes spi bus device if no other devices are attached to it.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
32 * Devices can have individual bus_configs, so different mosi, miso, sck pins can be configured for each device
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
33 Reconfiguring the bus is done automaticaly in 'spi_lobo_device_select' function
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
34 * 'spi_lobo_device_select' & 'spi_lobo_device_deselect' functions handles devices configuration changes and software CS
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
35 * Some helper functions are added ('spi_lobo_get_speed', 'spi_lobo_set_speed', ...)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
36 * All structures are available in header file for easy creation of user low level spi functions. See **tftfunc.c** source for examples.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
37 * Transimt and receive lenghts are limited only by available memory
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
38
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
39
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
40 Main driver's function is 'spi_lobo_transfer_data()'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
41
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
42 * TRANSMIT 8-bit data to spi device from 'trans->tx_buffer' or 'trans->tx_data' (trans->lenght/8 bytes)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
43 * and RECEIVE data to 'trans->rx_buffer' or 'trans->rx_data' (trans->rx_length/8 bytes)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
44 * Lengths must be 8-bit multiples!
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
45 * If trans->rx_buffer is NULL or trans->rx_length is 0, only transmits data
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
46 * If trans->tx_buffer is NULL or trans->length is 0, only receives data
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
47 * If the device is in duplex mode (LB_SPI_DEVICE_HALFDUPLEX flag NOT set), data are transmitted and received simultaneously.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
48 * If the device is in half duplex mode (LB_SPI_DEVICE_HALFDUPLEX flag IS set), data are received after transmission
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
49 * 'address', 'command' and 'dummy bits' are transmitted before data phase IF set in device's configuration
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
50 * and IF 'trans->length' and 'trans->rx_length' are NOT both 0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
51 * If configured, devices 'pre_cb' callback is called before and 'post_cb' after the transmission
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
52 * If device was not previously selected, it will be selected before transmission and deselected after transmission.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
53
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
54 */
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
55
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
56 /*
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
57 Replace this include with
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
58 #include "driver/spi_master_lobo.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
59 if the driver is located in esp-isf/components
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
60 */
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
61 #include "freertos/FreeRTOS.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
62 #include <string.h>
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
63 #include <stdio.h>
39
e5900c9b9a7b Use PROJECT_VER for version number. Updated README and info screen.
Michiel Broek <mbroek@mbse.eu>
parents: 1
diff changeset
64 #include "esp32/rom/ets_sys.h"
0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
65 #include "esp_types.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
66 #include "esp_attr.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
67 #include "esp_log.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
68 #include "esp_err.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
69 #include "freertos/semphr.h"
140
ac6ad7bd55c3 Version 0.4.1 Fixed deprecation message. Ignore WiFi channel change event
Michiel Broek <mbroek@mbse.eu>
parents: 129
diff changeset
70 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2, 0)
0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
71 #include "freertos/xtensa_api.h"
140
ac6ad7bd55c3 Version 0.4.1 Fixed deprecation message. Ignore WiFi channel change event
Michiel Broek <mbroek@mbse.eu>
parents: 129
diff changeset
72 #else
ac6ad7bd55c3 Version 0.4.1 Fixed deprecation message. Ignore WiFi channel change event
Michiel Broek <mbroek@mbse.eu>
parents: 129
diff changeset
73 #include <xtensa_api.h>
ac6ad7bd55c3 Version 0.4.1 Fixed deprecation message. Ignore WiFi channel change event
Michiel Broek <mbroek@mbse.eu>
parents: 129
diff changeset
74 #endif
0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
75 #include "freertos/task.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
76 #include "driver/uart.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
77 #include "driver/gpio.h"
129
31f9d3e4a85f Start migration to IDF 5.1
Michiel Broek <mbroek@mbse.eu>
parents: 39
diff changeset
78 #include "esp_private/periph_ctrl.h"
0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
79 #include "esp_heap_caps.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
80 #include "spi_master_lobo.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
81
129
31f9d3e4a85f Start migration to IDF 5.1
Michiel Broek <mbroek@mbse.eu>
parents: 39
diff changeset
82 #include "rom/gpio.h"
31f9d3e4a85f Start migration to IDF 5.1
Michiel Broek <mbroek@mbse.eu>
parents: 39
diff changeset
83 #include "soc/soc.h"
31f9d3e4a85f Start migration to IDF 5.1
Michiel Broek <mbroek@mbse.eu>
parents: 39
diff changeset
84 #include "soc/io_mux_reg.h"
31f9d3e4a85f Start migration to IDF 5.1
Michiel Broek <mbroek@mbse.eu>
parents: 39
diff changeset
85 #include "soc/gpio_periph.h"
31f9d3e4a85f Start migration to IDF 5.1
Michiel Broek <mbroek@mbse.eu>
parents: 39
diff changeset
86 #include "soc/periph_defs.h"
31f9d3e4a85f Start migration to IDF 5.1
Michiel Broek <mbroek@mbse.eu>
parents: 39
diff changeset
87 #include "soc/dport_reg.h"
31f9d3e4a85f Start migration to IDF 5.1
Michiel Broek <mbroek@mbse.eu>
parents: 39
diff changeset
88 #include "soc/spi_reg.h"
31f9d3e4a85f Start migration to IDF 5.1
Michiel Broek <mbroek@mbse.eu>
parents: 39
diff changeset
89
0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
90
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
91 static spi_lobo_host_t *spihost[3] = {NULL};
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
92
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
93
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
94 static const char *SPI_TAG = "spi_lobo_master";
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
95 #define SPI_CHECK(a, str, ret_val) \
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
96 if (!(a)) { \
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
97 ESP_LOGE(SPI_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
98 return (ret_val); \
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
99 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
100
1
ad2c8b13eb88 Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents: 0
diff changeset
101 /**
ad2c8b13eb88 Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents: 0
diff changeset
102 * @brief Stores a bunch of per-spi-peripheral data.
ad2c8b13eb88 Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents: 0
diff changeset
103 */
0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
104 typedef struct {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
105 const uint8_t spiclk_out; //GPIO mux output signals
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
106 const uint8_t spid_out;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
107 const uint8_t spiq_out;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
108 const uint8_t spiwp_out;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
109 const uint8_t spihd_out;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
110 const uint8_t spid_in; //GPIO mux input signals
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
111 const uint8_t spiq_in;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
112 const uint8_t spiwp_in;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
113 const uint8_t spihd_in;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
114 const uint8_t spics_out[3]; // /CS GPIO output mux signals
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
115 const uint8_t spiclk_native; //IO pins of IO_MUX muxed signals
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
116 const uint8_t spid_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
117 const uint8_t spiq_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
118 const uint8_t spiwp_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
119 const uint8_t spihd_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
120 const uint8_t spics0_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
121 const uint8_t irq; //irq source for interrupt mux
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
122 const uint8_t irq_dma; //dma irq source for interrupt mux
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
123 const periph_module_t module; //peripheral module, for enabling clock etc
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
124 spi_dev_t *hw; //Pointer to the hardware registers
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
125 } spi_signal_conn_t;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
126
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
127 /*
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
128 Bunch of constants for every SPI peripheral: GPIO signals, irqs, hw addr of registers etc
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
129 */
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
130 static const spi_signal_conn_t io_signal[3]={
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
131 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
132 .spiclk_out=SPICLK_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
133 .spid_out=SPID_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
134 .spiq_out=SPIQ_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
135 .spiwp_out=SPIWP_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
136 .spihd_out=SPIHD_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
137 .spid_in=SPID_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
138 .spiq_in=SPIQ_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
139 .spiwp_in=SPIWP_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
140 .spihd_in=SPIHD_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
141 .spics_out={SPICS0_OUT_IDX, SPICS1_OUT_IDX, SPICS2_OUT_IDX},
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
142 .spiclk_native=6,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
143 .spid_native=8,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
144 .spiq_native=7,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
145 .spiwp_native=10,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
146 .spihd_native=9,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
147 .spics0_native=11,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
148 .irq=ETS_SPI1_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
149 .irq_dma=ETS_SPI1_DMA_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
150 .module=PERIPH_SPI_MODULE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
151 .hw=&SPI1
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
152 }, {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
153 .spiclk_out=HSPICLK_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
154 .spid_out=HSPID_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
155 .spiq_out=HSPIQ_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
156 .spiwp_out=HSPIWP_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
157 .spihd_out=HSPIHD_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
158 .spid_in=HSPID_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
159 .spiq_in=HSPIQ_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
160 .spiwp_in=HSPIWP_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
161 .spihd_in=HSPIHD_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
162 .spics_out={HSPICS0_OUT_IDX, HSPICS1_OUT_IDX, HSPICS2_OUT_IDX},
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
163 .spiclk_native=14,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
164 .spid_native=13,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
165 .spiq_native=12,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
166 .spiwp_native=2,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
167 .spihd_native=4,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
168 .spics0_native=15,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
169 .irq=ETS_SPI2_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
170 .irq_dma=ETS_SPI2_DMA_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
171 .module=PERIPH_HSPI_MODULE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
172 .hw=&SPI2
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
173 }, {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
174 .spiclk_out=VSPICLK_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
175 .spid_out=VSPID_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
176 .spiq_out=VSPIQ_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
177 .spiwp_out=VSPIWP_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
178 .spihd_out=VSPIHD_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
179 .spid_in=VSPID_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
180 .spiq_in=VSPIQ_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
181 .spiwp_in=VSPIWP_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
182 .spihd_in=VSPIHD_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
183 .spics_out={VSPICS0_OUT_IDX, VSPICS1_OUT_IDX, VSPICS2_OUT_IDX},
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
184 .spiclk_native=18,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
185 .spid_native=23,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
186 .spiq_native=19,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
187 .spiwp_native=22,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
188 .spihd_native=21,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
189 .spics0_native=5,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
190 .irq=ETS_SPI3_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
191 .irq_dma=ETS_SPI3_DMA_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
192 .module=PERIPH_VSPI_MODULE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
193 .hw=&SPI3
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
194 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
195 };
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
196
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
197
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
198 //======================================================================================================
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
199
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
200 #define DMA_CHANNEL_ENABLED(dma_chan) (BIT(dma_chan-1))
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
201
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
202 typedef void(*dmaworkaround_cb_t)(void *arg);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
203
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
204 //Set up a list of dma descriptors. dmadesc is an array of descriptors. Data is the buffer to point to.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
205 //--------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
206 void spi_lobo_setup_dma_desc_links(lldesc_t *dmadesc, int len, const uint8_t *data, bool isrx)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
207 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
208 int n = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
209 while (len) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
210 int dmachunklen = len;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
211 if (dmachunklen > SPI_MAX_DMA_LEN) dmachunklen = SPI_MAX_DMA_LEN;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
212 if (isrx) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
213 //Receive needs DMA length rounded to next 32-bit boundary
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
214 dmadesc[n].size = (dmachunklen + 3) & (~3);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
215 dmadesc[n].length = (dmachunklen + 3) & (~3);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
216 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
217 dmadesc[n].size = dmachunklen;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
218 dmadesc[n].length = dmachunklen;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
219 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
220 dmadesc[n].buf = (uint8_t *)data;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
221 dmadesc[n].eof = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
222 dmadesc[n].sosf = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
223 dmadesc[n].owner = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
224 dmadesc[n].qe.stqe_next = &dmadesc[n + 1];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
225 len -= dmachunklen;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
226 data += dmachunklen;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
227 n++;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
228 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
229 dmadesc[n - 1].eof = 1; //Mark last DMA desc as end of stream.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
230 dmadesc[n - 1].qe.stqe_next = NULL;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
231 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
232
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
233
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
234 /*
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
235 Code for workaround for DMA issue in ESP32 v0/v1 silicon
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
236 */
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
237
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
238
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
239 static volatile int dmaworkaround_channels_busy[2] = {0, 0};
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
240 static dmaworkaround_cb_t dmaworkaround_cb;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
241 static void *dmaworkaround_cb_arg;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
242 static portMUX_TYPE dmaworkaround_mux = portMUX_INITIALIZER_UNLOCKED;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
243 static int dmaworkaround_waiting_for_chan = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
244 static bool spi_periph_claimed[3] = {true, false, false};
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
245 static uint8_t spi_dma_chan_enabled = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
246 static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
247
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
248 //--------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
249 bool IRAM_ATTR spi_lobo_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t cb, void *arg)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
250 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
251 int otherchan = (dmachan == 1) ? 2 : 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
252 bool ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
253 portENTER_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
254 if (dmaworkaround_channels_busy[otherchan-1]) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
255 //Other channel is busy. Call back when it's done.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
256 dmaworkaround_cb = cb;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
257 dmaworkaround_cb_arg = arg;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
258 dmaworkaround_waiting_for_chan = otherchan;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
259 ret = false;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
260 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
261 //Reset DMA
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
262 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_DMA_RST);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
263 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_DMA_RST);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
264 ret = true;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
265 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
266 portEXIT_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
267 return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
268 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
269
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
270 //-------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
271 bool IRAM_ATTR spi_lobo_dmaworkaround_reset_in_progress()
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
272 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
273 return (dmaworkaround_waiting_for_chan != 0);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
274 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
275
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
276 //-----------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
277 void IRAM_ATTR spi_lobo_dmaworkaround_idle(int dmachan)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
278 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
279 portENTER_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
280 dmaworkaround_channels_busy[dmachan-1] = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
281 if (dmaworkaround_waiting_for_chan == dmachan) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
282 //Reset DMA
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
283 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_DMA_RST);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
284 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_DMA_RST);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
285 dmaworkaround_waiting_for_chan = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
286 //Call callback
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
287 dmaworkaround_cb(dmaworkaround_cb_arg);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
288
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
289 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
290 portEXIT_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
291 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
292
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
293 //----------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
294 void IRAM_ATTR spi_lobo_dmaworkaround_transfer_active(int dmachan)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
295 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
296 portENTER_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
297 dmaworkaround_channels_busy[dmachan-1] = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
298 portEXIT_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
299 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
300
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
301 //Returns true if this peripheral is successfully claimed, false if otherwise.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
302 //-----------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
303 bool spi_lobo_periph_claim(spi_lobo_host_device_t host)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
304 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
305 bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], false, true);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
306 if (ret) periph_module_enable(io_signal[host].module);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
307 return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
308 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
309
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
310 //Returns true if this peripheral is successfully freed, false if otherwise.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
311 //-----------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
312 bool spi_lobo_periph_free(spi_lobo_host_device_t host)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
313 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
314 bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], true, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
315 if (ret) periph_module_disable(io_signal[host].module);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
316 return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
317 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
318
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
319 //-----------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
320 bool spi_lobo_dma_chan_claim (int dma_chan)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
321 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
322 bool ret = false;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
323 assert( dma_chan == 1 || dma_chan == 2 );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
324
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
325 portENTER_CRITICAL(&spi_dma_spinlock);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
326 if ( !(spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan)) ) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
327 // get the channel only when it's not claimed yet.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
328 spi_dma_chan_enabled |= DMA_CHANNEL_ENABLED(dma_chan);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
329 ret = true;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
330 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
331 periph_module_enable( PERIPH_SPI_DMA_MODULE );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
332 portEXIT_CRITICAL(&spi_dma_spinlock);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
333
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
334 return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
335 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
336
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
337 //---------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
338 bool spi_lobo_dma_chan_free(int dma_chan)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
339 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
340 assert( dma_chan == 1 || dma_chan == 2 );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
341 assert( spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan) );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
342
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
343 portENTER_CRITICAL(&spi_dma_spinlock);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
344 spi_dma_chan_enabled &= ~DMA_CHANNEL_ENABLED(dma_chan);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
345 if ( spi_dma_chan_enabled == 0 ) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
346 //disable the DMA only when all the channels are freed.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
347 periph_module_disable( PERIPH_SPI_DMA_MODULE );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
348 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
349 portEXIT_CRITICAL(&spi_dma_spinlock);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
350
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
351 return true;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
352 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
353
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
354
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
355 //======================================================================================================
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
356
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
357
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
358 //----------------------------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
359 static esp_err_t spi_lobo_bus_initialize(spi_lobo_host_device_t host, spi_lobo_bus_config_t *bus_config, int init)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
360 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
361 bool native=true, spi_chan_claimed, dma_chan_claimed;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
362
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
363 if (init > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
364 /* ToDo: remove this when we have flash operations cooperating with this */
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
365 SPI_CHECK(host!=TFT_SPI_HOST, "SPI1 is not supported", ESP_ERR_NOT_SUPPORTED);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
366
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
367 SPI_CHECK(host>=TFT_SPI_HOST && host<=TFT_VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
368 SPI_CHECK(spihost[host]==NULL, "host already in use", ESP_ERR_INVALID_STATE);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
369 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
370 else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
371 SPI_CHECK(spihost[host]!=NULL, "host not in use", ESP_ERR_INVALID_STATE);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
372 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
373
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
374 SPI_CHECK(bus_config->mosi_io_num<0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->mosi_io_num), "spid pin invalid", ESP_ERR_INVALID_ARG);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
375 SPI_CHECK(bus_config->sclk_io_num<0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->sclk_io_num), "spiclk pin invalid", ESP_ERR_INVALID_ARG);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
376 SPI_CHECK(bus_config->miso_io_num<0 || GPIO_IS_VALID_GPIO(bus_config->miso_io_num), "spiq pin invalid", ESP_ERR_INVALID_ARG);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
377 SPI_CHECK(bus_config->quadwp_io_num<0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->quadwp_io_num), "spiwp pin invalid", ESP_ERR_INVALID_ARG);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
378 SPI_CHECK(bus_config->quadhd_io_num<0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->quadhd_io_num), "spihd pin invalid", ESP_ERR_INVALID_ARG);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
379
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
380 if (init > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
381 spi_chan_claimed=spi_lobo_periph_claim(host);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
382 SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
383
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
384 //spihost[host]=malloc(sizeof(spi_lobo_host_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
385 spihost[host]=heap_caps_malloc(sizeof(spi_lobo_host_t), MALLOC_CAP_DMA);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
386 if (spihost[host]==NULL) return ESP_ERR_NO_MEM;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
387 memset(spihost[host], 0, sizeof(spi_lobo_host_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
388 // Create semaphore
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
389 spihost[host]->spi_lobo_bus_mutex = xSemaphoreCreateMutex();
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
390 if (!spihost[host]->spi_lobo_bus_mutex) return ESP_ERR_NO_MEM;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
391 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
392
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
393 spihost[host]->cur_device = -1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
394 memcpy(&spihost[host]->cur_bus_config, bus_config, sizeof(spi_lobo_bus_config_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
395
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
396 //Check if the selected pins correspond to the native pins of the peripheral
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
397 if (bus_config->mosi_io_num >= 0 && bus_config->mosi_io_num!=io_signal[host].spid_native) native=false;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
398 if (bus_config->miso_io_num >= 0 && bus_config->miso_io_num!=io_signal[host].spiq_native) native=false;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
399 if (bus_config->sclk_io_num >= 0 && bus_config->sclk_io_num!=io_signal[host].spiclk_native) native=false;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
400 if (bus_config->quadwp_io_num >= 0 && bus_config->quadwp_io_num!=io_signal[host].spiwp_native) native=false;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
401 if (bus_config->quadhd_io_num >= 0 && bus_config->quadhd_io_num!=io_signal[host].spihd_native) native=false;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
402
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
403 spihost[host]->no_gpio_matrix=native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
404 if (native) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
405 //All SPI native pin selections resolve to 1, so we put that here instead of trying to figure
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
406 //out which FUNC_GPIOx_xSPIxx to grab; they all are defined to 1 anyway.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
407 if (bus_config->mosi_io_num > 0) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
408 if (bus_config->miso_io_num > 0) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
409 if (bus_config->quadwp_io_num > 0) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
410 if (bus_config->quadhd_io_num > 0) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
411 if (bus_config->sclk_io_num > 0) PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
412 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
413 //Use GPIO
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
414 if (bus_config->mosi_io_num>0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
415 PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->mosi_io_num], PIN_FUNC_GPIO);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
416 gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
417 gpio_matrix_out(bus_config->mosi_io_num, io_signal[host].spid_out, false, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
418 gpio_matrix_in(bus_config->mosi_io_num, io_signal[host].spid_in, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
419 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
420 if (bus_config->miso_io_num>0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
421 PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->miso_io_num], PIN_FUNC_GPIO);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
422 gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
423 gpio_matrix_out(bus_config->miso_io_num, io_signal[host].spiq_out, false, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
424 gpio_matrix_in(bus_config->miso_io_num, io_signal[host].spiq_in, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
425 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
426 if (bus_config->quadwp_io_num>0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
427 PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num], PIN_FUNC_GPIO);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
428 gpio_set_direction(bus_config->quadwp_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
429 gpio_matrix_out(bus_config->quadwp_io_num, io_signal[host].spiwp_out, false, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
430 gpio_matrix_in(bus_config->quadwp_io_num, io_signal[host].spiwp_in, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
431 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
432 if (bus_config->quadhd_io_num>0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
433 PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num], PIN_FUNC_GPIO);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
434 gpio_set_direction(bus_config->quadhd_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
435 gpio_matrix_out(bus_config->quadhd_io_num, io_signal[host].spihd_out, false, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
436 gpio_matrix_in(bus_config->quadhd_io_num, io_signal[host].spihd_in, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
437 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
438 if (bus_config->sclk_io_num>0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
439 PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[bus_config->sclk_io_num], PIN_FUNC_GPIO);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
440 gpio_set_direction(bus_config->sclk_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
441 gpio_matrix_out(bus_config->sclk_io_num, io_signal[host].spiclk_out, false, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
442 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
443 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
444 periph_module_enable(io_signal[host].module);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
445 spihost[host]->hw=io_signal[host].hw;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
446
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
447 if (init > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
448 dma_chan_claimed=spi_lobo_dma_chan_claim(init);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
449 if ( !dma_chan_claimed ) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
450 spi_lobo_periph_free( host );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
451 SPI_CHECK(dma_chan_claimed, "dma channel already in use", ESP_ERR_INVALID_STATE);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
452 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
453 spihost[host]->dma_chan = init;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
454 //See how many dma descriptors we need and allocate them
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
455 int dma_desc_ct=(bus_config->max_transfer_sz+SPI_MAX_DMA_LEN-1)/SPI_MAX_DMA_LEN;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
456 if (dma_desc_ct==0) dma_desc_ct=1; //default to 4k when max is not given
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
457 spihost[host]->max_transfer_sz = dma_desc_ct*SPI_MAX_DMA_LEN;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
458
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
459 spihost[host]->dmadesc_tx=heap_caps_malloc(sizeof(lldesc_t)*dma_desc_ct, MALLOC_CAP_DMA);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
460 spihost[host]->dmadesc_rx=heap_caps_malloc(sizeof(lldesc_t)*dma_desc_ct, MALLOC_CAP_DMA);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
461 if (!spihost[host]->dmadesc_tx || !spihost[host]->dmadesc_rx) goto nomem;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
462
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
463 //Tell common code DMA workaround that our DMA channel is idle. If needed, the code will do a DMA reset.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
464 spi_lobo_dmaworkaround_idle(spihost[host]->dma_chan);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
465
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
466 // Reset DMA
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
467 spihost[host]->hw->dma_conf.val |= SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
468 spihost[host]->hw->dma_out_link.start=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
469 spihost[host]->hw->dma_in_link.start=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
470 spihost[host]->hw->dma_conf.val &= ~(SPI_OUT_RST|SPI_IN_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
471 spihost[host]->hw->dma_conf.out_data_burst_en=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
472
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
473 //Reset timing
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
474 spihost[host]->hw->ctrl2.val=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
475
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
476 //Disable unneeded ints
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
477 spihost[host]->hw->slave.rd_buf_done=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
478 spihost[host]->hw->slave.wr_buf_done=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
479 spihost[host]->hw->slave.rd_sta_done=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
480 spihost[host]->hw->slave.wr_sta_done=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
481 spihost[host]->hw->slave.rd_buf_inten=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
482 spihost[host]->hw->slave.wr_buf_inten=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
483 spihost[host]->hw->slave.rd_sta_inten=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
484 spihost[host]->hw->slave.wr_sta_inten=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
485
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
486 //Force a transaction done interrupt. This interrupt won't fire yet because we initialized the SPI interrupt as
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
487 //disabled. This way, we can just enable the SPI interrupt and the interrupt handler will kick in, handling
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
488 //any transactions that are queued.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
489 spihost[host]->hw->slave.trans_inten=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
490 spihost[host]->hw->slave.trans_done=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
491
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
492 //Select DMA channel.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
493 DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, init, (host * 2));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
494 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
495 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
496
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
497 nomem:
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
498 if (spihost[host]) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
499 free(spihost[host]->dmadesc_tx);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
500 free(spihost[host]->dmadesc_rx);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
501 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
502 free(spihost[host]);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
503 spi_lobo_periph_free(host);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
504 return ESP_ERR_NO_MEM;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
505 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
506
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
507 //---------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
508 static esp_err_t spi_lobo_bus_free(spi_lobo_host_device_t host, int dofree)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
509 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
510 if ((host == TFT_SPI_HOST) || (host > TFT_VSPI_HOST)) return ESP_ERR_NOT_SUPPORTED; // invalid host
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
511
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
512 if (spihost[host] == NULL) return ESP_ERR_INVALID_STATE; // host not in use
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
513
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
514 if (dofree) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
515 for (int x=0; x<NO_DEV; x++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
516 if (spihost[host]->device[x] != NULL) return ESP_ERR_INVALID_STATE; // not all devices freed
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
517 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
518 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
519 if ( spihost[host]->dma_chan > 0 ) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
520 spi_lobo_dma_chan_free ( spihost[host]->dma_chan );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
521 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
522 spihost[host]->hw->slave.trans_inten=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
523 spihost[host]->hw->slave.trans_done=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
524 spi_lobo_periph_free(host);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
525
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
526 if (dofree) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
527 vSemaphoreDelete(spihost[host]->spi_lobo_bus_mutex);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
528 free(spihost[host]->dmadesc_tx);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
529 free(spihost[host]->dmadesc_rx);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
530 free(spihost[host]);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
531 spihost[host] = NULL;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
532 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
533 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
534 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
535
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
536 //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
537 esp_err_t spi_lobo_bus_add_device(spi_lobo_host_device_t host, spi_lobo_bus_config_t *bus_config, spi_lobo_device_interface_config_t *dev_config, spi_lobo_device_handle_t *handle)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
538 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
539 if ((host == TFT_SPI_HOST) || (host > TFT_VSPI_HOST)) return ESP_ERR_NOT_SUPPORTED; // invalid host
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
540
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
541 if (spihost[host] == NULL) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
542 esp_err_t ret = spi_lobo_bus_initialize(host, bus_config, 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
543 if (ret) return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
544 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
545
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
546 int freecs, maxdev;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
547 int apbclk=APB_CLK_FREQ;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
548
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
549 if (spihost[host] == NULL) return ESP_ERR_INVALID_STATE;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
550
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
551 if (dev_config->spics_io_num >= 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
552 if (!GPIO_IS_VALID_OUTPUT_GPIO(dev_config->spics_io_num)) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
553 if (dev_config->spics_ext_io_num > 0) dev_config->spics_ext_io_num = -1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
554 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
555 else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
556 //if ((dev_config->spics_ext_io_num <= 0) || (!GPIO_IS_VALID_OUTPUT_GPIO(dev_config->spics_ext_io_num))) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
557 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
558
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
559 //ToDo: Check if some other device uses the same 'spics_ext_io_num'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
560
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
561 if (dev_config->clock_speed_hz == 0) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
562 if (dev_config->spics_io_num > 0) maxdev = NO_CS;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
563 else maxdev = NO_DEV;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
564
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
565 for (freecs=0; freecs<maxdev; freecs++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
566 //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.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
567 if (__sync_bool_compare_and_swap(&spihost[host]->device[freecs], NULL, (spi_lobo_device_t *)1)) break;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
568 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
569 if (freecs == maxdev) return ESP_ERR_NOT_FOUND;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
570
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
571 // The hardware looks like it would support this, but actually setting cs_ena_pretrans when transferring in full
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
572 // duplex mode does absolutely nothing on the ESP32.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
573 if ((dev_config->cs_ena_pretrans != 0) && (dev_config->flags & LB_SPI_DEVICE_HALFDUPLEX)) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
574
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
575 // Speeds >=40MHz over GPIO matrix needs a dummy cycle, but these don't work for full-duplex connections.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
576 if (((dev_config->flags & LB_SPI_DEVICE_HALFDUPLEX)==0) && (dev_config->clock_speed_hz > ((apbclk*2)/5)) && (!spihost[host]->no_gpio_matrix)) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
577
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
578 //Allocate memory for device
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
579 spi_lobo_device_t *dev=malloc(sizeof(spi_lobo_device_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
580 if (dev==NULL) return ESP_ERR_NO_MEM;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
581
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
582 memset(dev, 0, sizeof(spi_lobo_device_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
583 spihost[host]->device[freecs]=dev;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
584
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
585 if (dev_config->duty_cycle_pos==0) dev_config->duty_cycle_pos=128;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
586 dev->host=spihost[host];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
587 dev->host_dev = host;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
588
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
589 //We want to save a copy of the dev config in the dev struct.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
590 memcpy(&dev->cfg, dev_config, sizeof(spi_lobo_device_interface_config_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
591 //We want to save a copy of the bus config in the dev struct.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
592 memcpy(&dev->bus_config, bus_config, sizeof(spi_lobo_bus_config_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
593
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
594 //Set CS pin, CS options
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
595 if (dev_config->spics_io_num > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
596 if (spihost[host]->no_gpio_matrix &&dev_config->spics_io_num == io_signal[host].spics0_native && freecs==0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
597 //Again, the cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
598 PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[dev_config->spics_io_num], 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
599 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
600 //Use GPIO matrix
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
601 PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[dev_config->spics_io_num], PIN_FUNC_GPIO);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
602 gpio_set_direction(dev_config->spics_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
603 gpio_matrix_out(dev_config->spics_io_num, io_signal[host].spics_out[freecs], false, false);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
604 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
605 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
606 else if (dev_config->spics_ext_io_num >= 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
607 gpio_set_direction(dev_config->spics_ext_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
608 gpio_set_level(dev_config->spics_ext_io_num, 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
609 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
610 if (dev_config->flags & LB_SPI_DEVICE_CLK_AS_CS) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
611 spihost[host]->hw->pin.master_ck_sel |= (1<<freecs);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
612 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
613 spihost[host]->hw->pin.master_ck_sel &= (1<<freecs);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
614 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
615 if (dev_config->flags & LB_SPI_DEVICE_POSITIVE_CS) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
616 spihost[host]->hw->pin.master_cs_pol |= (1<<freecs);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
617 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
618 spihost[host]->hw->pin.master_cs_pol &= (1<<freecs);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
619 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
620
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
621 *handle = dev;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
622 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
623 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
624
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
625 //-------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
626 esp_err_t spi_lobo_bus_remove_device(spi_lobo_device_handle_t handle)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
627 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
628 int x;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
629 if (handle == NULL) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
630
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
631 //Remove device from list of csses and free memory
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
632 for (x=0; x<NO_DEV; x++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
633 if (handle->host->device[x] == handle) handle->host->device[x]=NULL;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
634 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
635
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
636 // Check if all devices are removed from this host and free the bus if yes
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
637 for (x=0; x<NO_DEV; x++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
638 if (spihost[handle->host_dev]->device[x] !=NULL) break;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
639 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
640 if (x == NO_DEV) {
129
31f9d3e4a85f Start migration to IDF 5.1
Michiel Broek <mbroek@mbse.eu>
parents: 39
diff changeset
641 spi_lobo_bus_free(handle->host_dev, 1);
0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
642 free(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
643 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
644 else free(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
645
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
646 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
647 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
648
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
649 //-----------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
650 static int IRAM_ATTR spi_freq_for_pre_n(int fapb, int pre, int n) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
651 return (fapb / (pre * n));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
652 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
653
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
654 /*
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
655 * Set the SPI clock to a certain frequency. Returns the effective frequency set, which may be slightly
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
656 * different from the requested frequency.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
657 */
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
658 //-----------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
659 static int IRAM_ATTR spi_set_clock(spi_dev_t *hw, int fapb, int hz, int duty_cycle) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
660 int pre, n, h, l, eff_clk;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
661
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
662 //In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
663 if (hz>((fapb/4)*3)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
664 //Using Fapb directly will give us the best result here.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
665 hw->clock.clkcnt_l=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
666 hw->clock.clkcnt_h=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
667 hw->clock.clkcnt_n=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
668 hw->clock.clkdiv_pre=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
669 hw->clock.clk_equ_sysclk=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
670 eff_clk=fapb;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
671 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
672 //For best duty cycle resolution, we want n to be as close to 32 as possible, but
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
673 //we also need a pre/n combo that gets us as close as possible to the intended freq.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
674 //To do this, we bruteforce n and calculate the best pre to go along with that.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
675 //If there's a choice between pre/n combos that give the same result, use the one
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
676 //with the higher n.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
677 int bestn=-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
678 int bestpre=-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
679 int besterr=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
680 int errval;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
681 for (n=1; n<=64; n++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
682 //Effectively, this does pre=round((fapb/n)/hz).
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
683 pre=((fapb/n)+(hz/2))/hz;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
684 if (pre<=0) pre=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
685 if (pre>8192) pre=8192;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
686 errval=abs(spi_freq_for_pre_n(fapb, pre, n)-hz);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
687 if (bestn==-1 || errval<=besterr) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
688 besterr=errval;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
689 bestn=n;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
690 bestpre=pre;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
691 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
692 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
693
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
694 n=bestn;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
695 pre=bestpre;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
696 l=n;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
697 //This effectively does round((duty_cycle*n)/256)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
698 h=(duty_cycle*n+127)/256;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
699 if (h<=0) h=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
700
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
701 hw->clock.clk_equ_sysclk=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
702 hw->clock.clkcnt_n=n-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
703 hw->clock.clkdiv_pre=pre-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
704 hw->clock.clkcnt_h=h-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
705 hw->clock.clkcnt_l=l-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
706 eff_clk=spi_freq_for_pre_n(fapb, pre, n);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
707 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
708 return eff_clk;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
709 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
710
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
711
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
712
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
713 //------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
714 esp_err_t IRAM_ATTR spi_lobo_device_select(spi_lobo_device_handle_t handle, int force)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
715 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
716 if (handle == NULL) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
717
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
718 if ((handle->cfg.selected == 1) && (!force)) return ESP_OK; // already selected
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
719
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
720 int i;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
721 spi_lobo_host_t *host=(spi_lobo_host_t*)handle->host;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
722
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
723 // find device's host bus
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
724 for (i=0; i<NO_DEV; i++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
725 if (host->device[i] == handle) break;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
726 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
727 if (i == NO_DEV) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
728
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
729 if (!(xSemaphoreTake(host->spi_lobo_bus_mutex, SPI_SEMAPHORE_WAIT))) return ESP_ERR_INVALID_STATE;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
730
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
731 // Check if previously used device's bus device is the same
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
732 if (memcmp(&host->cur_bus_config, &handle->bus_config, sizeof(spi_lobo_bus_config_t)) != 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
733 // device has different bus configuration, we need to reconfigure the bus
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
734 esp_err_t err = spi_lobo_bus_free(1, 0);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
735 if (err) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
736 xSemaphoreGive(host->spi_lobo_bus_mutex);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
737 return err;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
738 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
739 err = spi_lobo_bus_initialize(i, &handle->bus_config, -1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
740 if (err) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
741 xSemaphoreGive(host->spi_lobo_bus_mutex);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
742 return err;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
743 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
744 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
745
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
746 //Reconfigure according to device settings, but only if the device changed or forced.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
747 if ((force) || (host->device[host->cur_device] != handle)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
748 //Assumes a hardcoded 80MHz Fapb for now. ToDo: figure out something better once we have clock scaling working.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
749 int apbclk=APB_CLK_FREQ;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
750
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
751 //Speeds >=40MHz over GPIO matrix needs a dummy cycle, but these don't work for full-duplex connections.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
752 if (((handle->cfg.flags & LB_SPI_DEVICE_HALFDUPLEX) == 0) && (handle->cfg.clock_speed_hz > ((apbclk*2)/5)) && (!host->no_gpio_matrix)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
753 // set speed to 32 MHz
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
754 handle->cfg.clock_speed_hz = (apbclk*2)/5;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
755 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
756
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
757 int effclk=spi_set_clock(host->hw, apbclk, handle->cfg.clock_speed_hz, handle->cfg.duty_cycle_pos);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
758 //Configure bit order
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
759 host->hw->ctrl.rd_bit_order=(handle->cfg.flags & LB_SPI_DEVICE_RXBIT_LSBFIRST)?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
760 host->hw->ctrl.wr_bit_order=(handle->cfg.flags & LB_SPI_DEVICE_TXBIT_LSBFIRST)?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
761
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
762 //Configure polarity
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
763 //SPI iface needs to be configured for a delay in some cases.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
764 int nodelay=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
765 int extra_dummy=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
766 if (host->no_gpio_matrix) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
767 if (effclk >= apbclk/2) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
768 nodelay=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
769 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
770 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
771 if (effclk >= apbclk/2) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
772 nodelay=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
773 extra_dummy=1; //Note: This only works on half-duplex connections. spi_lobo_bus_add_device checks for this.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
774 } else if (effclk >= apbclk/4) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
775 nodelay=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
776 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
777 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
778 if (handle->cfg.mode==0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
779 host->hw->pin.ck_idle_edge=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
780 host->hw->user.ck_out_edge=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
781 host->hw->ctrl2.miso_delay_mode=nodelay?0:2;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
782 } else if (handle->cfg.mode==1) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
783 host->hw->pin.ck_idle_edge=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
784 host->hw->user.ck_out_edge=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
785 host->hw->ctrl2.miso_delay_mode=nodelay?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
786 } else if (handle->cfg.mode==2) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
787 host->hw->pin.ck_idle_edge=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
788 host->hw->user.ck_out_edge=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
789 host->hw->ctrl2.miso_delay_mode=nodelay?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
790 } else if (handle->cfg.mode==3) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
791 host->hw->pin.ck_idle_edge=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
792 host->hw->user.ck_out_edge=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
793 host->hw->ctrl2.miso_delay_mode=nodelay?0:2;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
794 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
795
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
796 //Configure bit sizes, load addr and command
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
797 host->hw->user.usr_dummy=(handle->cfg.dummy_bits+extra_dummy)?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
798 host->hw->user.usr_addr=(handle->cfg.address_bits)?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
799 host->hw->user.usr_command=(handle->cfg.command_bits)?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
800 host->hw->user1.usr_addr_bitlen=handle->cfg.address_bits-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
801 host->hw->user1.usr_dummy_cyclelen=handle->cfg.dummy_bits+extra_dummy-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
802 host->hw->user2.usr_command_bitlen=handle->cfg.command_bits-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
803 //Configure misc stuff
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
804 host->hw->user.doutdin=(handle->cfg.flags & LB_SPI_DEVICE_HALFDUPLEX)?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
805 host->hw->user.sio=(handle->cfg.flags & LB_SPI_DEVICE_3WIRE)?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
806
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
807 host->hw->ctrl2.setup_time=handle->cfg.cs_ena_pretrans-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
808 host->hw->user.cs_setup=handle->cfg.cs_ena_pretrans?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
809 host->hw->ctrl2.hold_time=handle->cfg.cs_ena_posttrans-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
810 host->hw->user.cs_hold=(handle->cfg.cs_ena_posttrans)?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
811
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
812 //Configure CS pin
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
813 host->hw->pin.cs0_dis=(i==0)?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
814 host->hw->pin.cs1_dis=(i==1)?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
815 host->hw->pin.cs2_dis=(i==2)?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
816
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
817 host->cur_device = i;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
818 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
819
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
820 if ((handle->cfg.spics_io_num < 0) && (handle->cfg.spics_ext_io_num > 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
821 gpio_set_level(handle->cfg.spics_ext_io_num, 0);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
822 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
823
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
824 handle->cfg.selected = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
825
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
826 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
827 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
828
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
829 //---------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
830 esp_err_t IRAM_ATTR spi_lobo_device_deselect(spi_lobo_device_handle_t handle)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
831 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
832 if (handle == NULL) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
833
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
834 if (handle->cfg.selected == 0) return ESP_OK; // already deselected
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
835
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
836 int i;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
837 spi_lobo_host_t *host=(spi_lobo_host_t*)handle->host;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
838
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
839 for (i=0; i<NO_DEV; i++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
840 if (host->device[i] == handle) break;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
841 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
842 if (i == NO_DEV) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
843
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
844 if (host->device[host->cur_device] == handle) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
845 if ((handle->cfg.spics_io_num < 0) && (handle->cfg.spics_ext_io_num > 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
846 gpio_set_level(handle->cfg.spics_ext_io_num, 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
847 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
848 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
849
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
850 handle->cfg.selected = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
851 xSemaphoreGive(host->spi_lobo_bus_mutex);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
852
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
853 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
854 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
855
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
856 //--------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
857 esp_err_t IRAM_ATTR spi_lobo_device_TakeSemaphore(spi_lobo_device_handle_t handle)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
858 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
859 if (!(xSemaphoreTake(handle->host->spi_lobo_bus_mutex, SPI_SEMAPHORE_WAIT))) return ESP_ERR_INVALID_STATE;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
860 else return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
861 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
862
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
863 //---------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
864 void IRAM_ATTR spi_lobo_device_GiveSemaphore(spi_lobo_device_handle_t handle)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
865 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
866 xSemaphoreTake(handle->host->spi_lobo_bus_mutex, portMAX_DELAY);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
867 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
868
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
869 //----------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
870 uint32_t spi_lobo_get_speed(spi_lobo_device_handle_t handle)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
871 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
872 spi_lobo_host_t *host=(spi_lobo_host_t*)handle->host;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
873 uint32_t speed = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
874 if (spi_lobo_device_select(handle, 0) == ESP_OK) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
875 if (host->hw->clock.clk_equ_sysclk == 1) speed = 80000000;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
876 else speed = 80000000/(host->hw->clock.clkdiv_pre+1)/(host->hw->clock.clkcnt_n+1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
877 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
878 spi_lobo_device_deselect(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
879 return speed;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
880 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
881
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
882 //--------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
883 uint32_t spi_lobo_set_speed(spi_lobo_device_handle_t handle, uint32_t speed)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
884 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
885 spi_lobo_host_t *host=(spi_lobo_host_t*)handle->host;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
886 uint32_t newspeed = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
887 if (spi_lobo_device_select(handle, 0) == ESP_OK) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
888 spi_lobo_device_deselect(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
889 handle->cfg.clock_speed_hz = speed;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
890 if (spi_lobo_device_select(handle, 1) == ESP_OK) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
891 if (host->hw->clock.clk_equ_sysclk == 1) newspeed = 80000000;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
892 else newspeed = 80000000/(host->hw->clock.clkdiv_pre+1)/(host->hw->clock.clkcnt_n+1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
893 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
894 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
895 spi_lobo_device_deselect(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
896
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
897 return newspeed;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
898 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
899
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
900 //-------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
901 bool spi_lobo_uses_native_pins(spi_lobo_device_handle_t handle)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
902 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
903 return handle->host->no_gpio_matrix;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
904 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
905
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
906 //-------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
907 void spi_lobo_get_native_pins(int host, int *sdi, int *sdo, int *sck)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
908 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
909 *sdo = io_signal[host].spid_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
910 *sdi = io_signal[host].spiq_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
911 *sck = io_signal[host].spiclk_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
912 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
913
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
914 /*
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
915 When using 'spi_lobo_transfer_data' function we can have several scenarios:
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
916
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
917 A: Send only (trans->rxlength = 0)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
918 B: Receive only (trans->txlength = 0)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
919 C: Send & receive (trans->txlength > 0 & trans->rxlength > 0)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
920 D: No operation (trans->txlength = 0 & trans->rxlength = 0)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
921
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
922 */
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
923 //----------------------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
924 esp_err_t IRAM_ATTR spi_lobo_transfer_data(spi_lobo_device_handle_t handle, spi_lobo_transaction_t *trans) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
925 if (!handle) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
926
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
927 // *** For now we can only handle 8-bit bytes transmission
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
928 if (((trans->length % 8) != 0) || ((trans->rxlength % 8) != 0)) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
929
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
930 spi_lobo_host_t *host=(spi_lobo_host_t*)handle->host;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
931 esp_err_t ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
932 uint8_t do_deselect = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
933 const uint8_t *txbuffer = NULL;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
934 uint8_t *rxbuffer = NULL;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
935
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
936 if (trans->flags & LB_SPI_TRANS_USE_TXDATA) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
937 // Send data from 'trans->tx_data'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
938 txbuffer=(uint8_t*)&trans->tx_data[0];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
939 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
940 // Send data from 'trans->tx_buffer'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
941 txbuffer=(uint8_t*)trans->tx_buffer;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
942 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
943 if (trans->flags & LB_SPI_TRANS_USE_RXDATA) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
944 // Receive data to 'trans->rx_data'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
945 rxbuffer=(uint8_t*)&trans->rx_data[0];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
946 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
947 // Receive data to 'trans->rx_buffer'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
948 rxbuffer=(uint8_t*)trans->rx_buffer;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
949 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
950
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
951 // ** Set transmit & receive length in bytes
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
952 uint32_t txlen = trans->length / 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
953 uint32_t rxlen = trans->rxlength / 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
954
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
955 if (txbuffer == NULL) txlen = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
956 if (rxbuffer == NULL) rxlen = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
957 if ((rxlen == 0) && (txlen == 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
958 // ** NOTHING TO SEND or RECEIVE, return
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
959 return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
960 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
961
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
962 // If using 'trans->tx_data' and/or 'trans->rx_data', maximum 4 bytes can be sent/received
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
963 if ((txbuffer == &trans->tx_data[0]) && (txlen > 4)) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
964 if ((rxbuffer == &trans->rx_data[0]) && (rxlen > 4)) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
965
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
966 // --- Wait for SPI bus ready ---
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
967 while (host->hw->cmd.usr);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
968
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
969 // ** If the device was not selected, select it
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
970 if (handle->cfg.selected == 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
971 ret = spi_lobo_device_select(handle, 0);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
972 if (ret) return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
973 do_deselect = 1; // We will deselect the device after the operation !
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
974 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
975
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
976 // ** Call pre-transmission callback, if any
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
977 if (handle->cfg.pre_cb) handle->cfg.pre_cb(trans);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
978
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
979 // Test if operating in full duplex mode
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
980 uint8_t duplex = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
981 if (handle->cfg.flags & LB_SPI_DEVICE_HALFDUPLEX) duplex = 0; // Half duplex mode !
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
982
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
983 uint32_t bits, rdbits;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
984 uint32_t wd;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
985 uint8_t bc, rdidx;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
986 uint32_t rdcount = rxlen; // Total number of bytes to read
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
987 uint32_t count = 0; // number of bytes transmitted
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
988 uint32_t rd_read = 0; // Number of bytes read so far
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
989
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
990 host->hw->user.usr_mosi_highpart = 0; // use the whole spi buffer
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
991
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
992 // ** Check if address phase will be used
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
993 host->hw->user2.usr_command_value=trans->command;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
994 if (handle->cfg.address_bits>32) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
995 host->hw->addr=trans->address >> 32;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
996 host->hw->slv_wr_status=trans->address & 0xffffffff;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
997 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
998 host->hw->addr=trans->address & 0xffffffff;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
999 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1000
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1001 // Check if we have to transmit some data
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1002 if (txlen > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1003 host->hw->user.usr_mosi = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1004 uint8_t idx;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1005 bits = 0; // remaining bits to send
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1006 idx = 0; // index to spi hw data_buf (16 32-bit words, 64 bytes, 512 bits)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1007
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1008 // ** Transmit 'txlen' bytes
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1009 while (count < txlen) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1010 wd = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1011 for (bc=0;bc<32;bc+=8) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1012 wd |= (uint32_t)txbuffer[count] << bc;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1013 count++; // Increment sent data count
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1014 bits += 8; // Increment bits count
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1015 if (count == txlen) break; // If all transmit data pushed to hw spi buffer break from the loop
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1016 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1017 host->hw->data_buf[idx] = wd;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1018 idx++;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1019 if (idx == 16) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1020 // hw SPI buffer full (all 64 bytes filled, START THE TRANSSACTION
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1021 host->hw->mosi_dlen.usr_mosi_dbitlen=bits-1; // Set mosi dbitlen
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1022
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1023 if ((duplex) && (rdcount > 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1024 // In full duplex mode we are receiving while sending !
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1025 host->hw->miso_dlen.usr_miso_dbitlen = bits-1; // Set miso dbitlen
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1026 host->hw->user.usr_miso = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1027 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1028 else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1029 host->hw->miso_dlen.usr_miso_dbitlen = 0; // In half duplex mode nothing will be received
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1030 host->hw->user.usr_miso = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1031 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1032
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1033 // ** Start the transaction ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1034 host->hw->cmd.usr=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1035 // Wait the transaction to finish
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1036 while (host->hw->cmd.usr);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1037
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1038 if ((duplex) && (rdcount > 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1039 // *** in full duplex mode transfer received data to input buffer ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1040 rdidx = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1041 while (bits > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1042 wd = host->hw->data_buf[rdidx];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1043 rdidx++;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1044 for (bc=0;bc<32;bc+=8) { // get max 4 bytes
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1045 rxbuffer[rd_read++] = (uint8_t)((wd >> bc) & 0xFF);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1046 rdcount--;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1047 bits -= 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1048 if (rdcount == 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1049 bits = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1050 break; // Finished reading data
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1051 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1052 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1053 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1054 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1055 bits = 0; // nothing in hw spi buffer yet
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1056 idx = 0; // start from the beginning of the hw spi buffer
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1057 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1058 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1059 // *** All transmit data are sent or pushed to hw spi buffer
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1060 // bits > 0 IF THERE ARE SOME DATA STILL WAITING IN THE HW SPI TRANSMIT BUFFER
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1061 if (bits > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1062 // ** WE HAVE SOME DATA IN THE HW SPI TRANSMIT BUFFER
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1063 host->hw->mosi_dlen.usr_mosi_dbitlen = bits-1; // Set mosi dbitlen
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1064
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1065 if ((duplex) && (rdcount > 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1066 // In full duplex mode we are receiving while sending !
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1067 host->hw->miso_dlen.usr_miso_dbitlen = bits-1; // Set miso dbitlen
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1068 host->hw->user.usr_miso = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1069 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1070 else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1071 host->hw->miso_dlen.usr_miso_dbitlen = 0; // In half duplex mode nothing will be received
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1072 host->hw->user.usr_miso = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1073 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1074
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1075 // ** Start the transaction ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1076 host->hw->cmd.usr=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1077 // Wait the transaction to finish
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1078 while (host->hw->cmd.usr);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1079
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1080 if ((duplex) && (rdcount > 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1081 // *** in full duplex mode transfer received data to input buffer ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1082 rdidx = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1083 while (bits > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1084 wd = host->hw->data_buf[rdidx];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1085 rdidx++;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1086 for (bc=0;bc<32;bc+=8) { // get max 4 bytes
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1087 rxbuffer[rd_read++] = (uint8_t)((wd >> bc) & 0xFF);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1088 rdcount--;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1089 bits -= 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1090 if (bits == 0) break;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1091 if (rdcount == 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1092 bits = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1093 break; // Finished reading data
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1094 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1095 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1096 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1097 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1098 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1099 //if (duplex) rdcount = 0; // In duplex mode receive only as many bytes as was transmitted
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1100 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1101
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1102 // ------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1103 // *** If rdcount = 0 we have nothing to receive and we exit the function
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1104 // This is true if no data receive was requested,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1105 // or all the data was received in Full duplex mode during the transmission
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1106 // ------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1107 if (rdcount > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1108 // ----------------------------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1109 // *** rdcount > 0, we have to receive some data
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1110 // This is true if we operate in Half duplex mode when receiving after transmission is done,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1111 // or not all data was received in Full duplex mode during the transmission (trans->rxlength > trans->txlength)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1112 // ----------------------------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1113 host->hw->user.usr_mosi = 0; // do not send
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1114 host->hw->user.usr_miso = 1; // do receive
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1115 while (rdcount > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1116 if (rdcount <= 64) rdbits = rdcount * 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1117 else rdbits = 64 * 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1118
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1119 // Load receive buffer
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1120 host->hw->mosi_dlen.usr_mosi_dbitlen=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1121 host->hw->miso_dlen.usr_miso_dbitlen=rdbits-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1122
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1123 // ** Start the transaction ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1124 host->hw->cmd.usr=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1125 // Wait the transaction to finish
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1126 while (host->hw->cmd.usr);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1127
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1128 // *** transfer received data to input buffer ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1129 rdidx = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1130 while (rdbits > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1131 wd = host->hw->data_buf[rdidx];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1132 rdidx++;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1133 for (bc=0;bc<32;bc+=8) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1134 rxbuffer[rd_read++] = (uint8_t)((wd >> bc) & 0xFF);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1135 rdcount--;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1136 rdbits -= 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1137 if (rdcount == 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1138 rdbits = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1139 break;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1140 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1141 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1142 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1143 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1144 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1145
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1146 // ** Call post-transmission callback, if any
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1147 if (handle->cfg.post_cb) handle->cfg.post_cb(trans);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1148
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1149 if (do_deselect) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1150 // Spi device was selected in this function, we have to deselect it now
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1151 ret = spi_lobo_device_deselect(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1152 if (ret) return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1153 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1154
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1155 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1156 }

mercurial