components/spidriver/spi_master_lobo.c

Mon, 21 Jun 2021 19:04:10 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Mon, 21 Jun 2021 19:04:10 +0200
changeset 102
96e30a3a3980
parent 39
e5900c9b9a7b
permissions
-rw-r--r--

Finished experimental code to drive the German HendiControl board. Added BoilPower and RampPower buttons during the while boil process. RampPower (going to boil power) is now adjustable. Added PWM driver code to the driver task.

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>
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
64 #include "soc/gpio_sig_map.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
65 #include "soc/spi_reg.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
66 #include "soc/dport_reg.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
67 #include "soc/rtc_cntl_reg.h"
39
e5900c9b9a7b Use PROJECT_VER for version number. Updated README and info screen.
Michiel Broek <mbroek@mbse.eu>
parents: 1
diff changeset
68 #include "esp32/rom/ets_sys.h"
0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
69 #include "esp_types.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
70 #include "esp_attr.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
71 #include "esp_log.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
72 #include "esp_err.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
73 #include "freertos/semphr.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
74 #include "freertos/xtensa_api.h"
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 "freertos/ringbuf.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
77 #include "soc/soc.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
78 #include "soc/dport_reg.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
79 #include "soc/uart_struct.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
80 #include "driver/uart.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
81 #include "driver/gpio.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
82 #include "driver/periph_ctrl.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
83 #include "esp_heap_caps.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
84 #include "driver/periph_ctrl.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
85 #include "spi_master_lobo.h"
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
86
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
87
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
88 static spi_lobo_host_t *spihost[3] = {NULL};
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
89
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 const char *SPI_TAG = "spi_lobo_master";
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
92 #define SPI_CHECK(a, str, ret_val) \
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
93 if (!(a)) { \
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
94 ESP_LOGE(SPI_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
95 return (ret_val); \
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
96 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
97
1
ad2c8b13eb88 Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents: 0
diff changeset
98 /**
ad2c8b13eb88 Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents: 0
diff changeset
99 * @brief Stores a bunch of per-spi-peripheral data.
ad2c8b13eb88 Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents: 0
diff changeset
100 */
0
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
101 typedef struct {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
102 const uint8_t spiclk_out; //GPIO mux output signals
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
103 const uint8_t spid_out;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
104 const uint8_t spiq_out;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
105 const uint8_t spiwp_out;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
106 const uint8_t spihd_out;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
107 const uint8_t spid_in; //GPIO mux input signals
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
108 const uint8_t spiq_in;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
109 const uint8_t spiwp_in;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
110 const uint8_t spihd_in;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
111 const uint8_t spics_out[3]; // /CS GPIO output mux signals
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
112 const uint8_t spiclk_native; //IO pins of IO_MUX muxed signals
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
113 const uint8_t spid_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
114 const uint8_t spiq_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
115 const uint8_t spiwp_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
116 const uint8_t spihd_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
117 const uint8_t spics0_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
118 const uint8_t irq; //irq source for interrupt mux
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
119 const uint8_t irq_dma; //dma irq source for interrupt mux
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
120 const periph_module_t module; //peripheral module, for enabling clock etc
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
121 spi_dev_t *hw; //Pointer to the hardware registers
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
122 } spi_signal_conn_t;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
123
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
124 /*
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
125 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
126 */
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
127 static const spi_signal_conn_t io_signal[3]={
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
128 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
129 .spiclk_out=SPICLK_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
130 .spid_out=SPID_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
131 .spiq_out=SPIQ_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
132 .spiwp_out=SPIWP_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
133 .spihd_out=SPIHD_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
134 .spid_in=SPID_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
135 .spiq_in=SPIQ_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
136 .spiwp_in=SPIWP_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
137 .spihd_in=SPIHD_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
138 .spics_out={SPICS0_OUT_IDX, SPICS1_OUT_IDX, SPICS2_OUT_IDX},
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
139 .spiclk_native=6,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
140 .spid_native=8,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
141 .spiq_native=7,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
142 .spiwp_native=10,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
143 .spihd_native=9,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
144 .spics0_native=11,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
145 .irq=ETS_SPI1_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
146 .irq_dma=ETS_SPI1_DMA_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
147 .module=PERIPH_SPI_MODULE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
148 .hw=&SPI1
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
149 }, {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
150 .spiclk_out=HSPICLK_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
151 .spid_out=HSPID_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
152 .spiq_out=HSPIQ_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
153 .spiwp_out=HSPIWP_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
154 .spihd_out=HSPIHD_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
155 .spid_in=HSPID_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
156 .spiq_in=HSPIQ_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
157 .spiwp_in=HSPIWP_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
158 .spihd_in=HSPIHD_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
159 .spics_out={HSPICS0_OUT_IDX, HSPICS1_OUT_IDX, HSPICS2_OUT_IDX},
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
160 .spiclk_native=14,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
161 .spid_native=13,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
162 .spiq_native=12,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
163 .spiwp_native=2,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
164 .spihd_native=4,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
165 .spics0_native=15,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
166 .irq=ETS_SPI2_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
167 .irq_dma=ETS_SPI2_DMA_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
168 .module=PERIPH_HSPI_MODULE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
169 .hw=&SPI2
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
170 }, {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
171 .spiclk_out=VSPICLK_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
172 .spid_out=VSPID_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
173 .spiq_out=VSPIQ_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
174 .spiwp_out=VSPIWP_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
175 .spihd_out=VSPIHD_OUT_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
176 .spid_in=VSPID_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
177 .spiq_in=VSPIQ_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
178 .spiwp_in=VSPIWP_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
179 .spihd_in=VSPIHD_IN_IDX,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
180 .spics_out={VSPICS0_OUT_IDX, VSPICS1_OUT_IDX, VSPICS2_OUT_IDX},
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
181 .spiclk_native=18,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
182 .spid_native=23,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
183 .spiq_native=19,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
184 .spiwp_native=22,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
185 .spihd_native=21,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
186 .spics0_native=5,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
187 .irq=ETS_SPI3_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
188 .irq_dma=ETS_SPI3_DMA_INTR_SOURCE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
189 .module=PERIPH_VSPI_MODULE,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
190 .hw=&SPI3
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
191 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
192 };
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
193
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 #define DMA_CHANNEL_ENABLED(dma_chan) (BIT(dma_chan-1))
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 typedef void(*dmaworkaround_cb_t)(void *arg);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
200
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
201 //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
202 //--------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
203 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
204 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
205 int n = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
206 while (len) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
207 int dmachunklen = len;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
208 if (dmachunklen > SPI_MAX_DMA_LEN) dmachunklen = SPI_MAX_DMA_LEN;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
209 if (isrx) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
210 //Receive needs DMA length rounded to next 32-bit boundary
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
211 dmadesc[n].size = (dmachunklen + 3) & (~3);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
212 dmadesc[n].length = (dmachunklen + 3) & (~3);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
213 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
214 dmadesc[n].size = dmachunklen;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
215 dmadesc[n].length = dmachunklen;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
216 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
217 dmadesc[n].buf = (uint8_t *)data;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
218 dmadesc[n].eof = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
219 dmadesc[n].sosf = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
220 dmadesc[n].owner = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
221 dmadesc[n].qe.stqe_next = &dmadesc[n + 1];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
222 len -= dmachunklen;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
223 data += dmachunklen;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
224 n++;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
225 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
226 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
227 dmadesc[n - 1].qe.stqe_next = NULL;
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
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
230
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 Code for workaround for DMA issue in ESP32 v0/v1 silicon
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
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
236 static volatile int dmaworkaround_channels_busy[2] = {0, 0};
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
237 static dmaworkaround_cb_t dmaworkaround_cb;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
238 static void *dmaworkaround_cb_arg;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
239 static portMUX_TYPE dmaworkaround_mux = portMUX_INITIALIZER_UNLOCKED;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
240 static int dmaworkaround_waiting_for_chan = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
241 static bool spi_periph_claimed[3] = {true, false, false};
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
242 static uint8_t spi_dma_chan_enabled = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
243 static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
244
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
245 //--------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
246 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
247 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
248 int otherchan = (dmachan == 1) ? 2 : 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
249 bool ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
250 portENTER_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
251 if (dmaworkaround_channels_busy[otherchan-1]) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
252 //Other channel is busy. Call back when it's done.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
253 dmaworkaround_cb = cb;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
254 dmaworkaround_cb_arg = arg;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
255 dmaworkaround_waiting_for_chan = otherchan;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
256 ret = false;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
257 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
258 //Reset DMA
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
259 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
260 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
261 ret = true;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
262 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
263 portEXIT_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
264 return ret;
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
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
267 //-------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
268 bool IRAM_ATTR spi_lobo_dmaworkaround_reset_in_progress()
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 return (dmaworkaround_waiting_for_chan != 0);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
271 }
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 //-----------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
274 void IRAM_ATTR spi_lobo_dmaworkaround_idle(int dmachan)
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 portENTER_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
277 dmaworkaround_channels_busy[dmachan-1] = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
278 if (dmaworkaround_waiting_for_chan == dmachan) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
279 //Reset DMA
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
280 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
281 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
282 dmaworkaround_waiting_for_chan = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
283 //Call callback
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
284 dmaworkaround_cb(dmaworkaround_cb_arg);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
285
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
286 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
287 portEXIT_CRITICAL(&dmaworkaround_mux);
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 //----------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
291 void IRAM_ATTR spi_lobo_dmaworkaround_transfer_active(int dmachan)
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 portENTER_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
294 dmaworkaround_channels_busy[dmachan-1] = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
295 portEXIT_CRITICAL(&dmaworkaround_mux);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
296 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
297
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
298 //Returns true if this peripheral is successfully claimed, false if otherwise.
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 bool spi_lobo_periph_claim(spi_lobo_host_device_t host)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
301 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
302 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
303 if (ret) periph_module_enable(io_signal[host].module);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
304 return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
305 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
306
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
307 //Returns true if this peripheral is successfully freed, false if otherwise.
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 bool spi_lobo_periph_free(spi_lobo_host_device_t host)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
310 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
311 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
312 if (ret) periph_module_disable(io_signal[host].module);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
313 return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
314 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
315
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
316 //-----------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
317 bool spi_lobo_dma_chan_claim (int dma_chan)
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 bool ret = false;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
320 assert( dma_chan == 1 || dma_chan == 2 );
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 portENTER_CRITICAL(&spi_dma_spinlock);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
323 if ( !(spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan)) ) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
324 // get the channel only when it's not claimed yet.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
325 spi_dma_chan_enabled |= DMA_CHANNEL_ENABLED(dma_chan);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
326 ret = true;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
327 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
328 periph_module_enable( PERIPH_SPI_DMA_MODULE );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
329 portEXIT_CRITICAL(&spi_dma_spinlock);
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 return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
332 }
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 //---------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
335 bool spi_lobo_dma_chan_free(int dma_chan)
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 assert( dma_chan == 1 || dma_chan == 2 );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
338 assert( spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(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 portENTER_CRITICAL(&spi_dma_spinlock);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
341 spi_dma_chan_enabled &= ~DMA_CHANNEL_ENABLED(dma_chan);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
342 if ( spi_dma_chan_enabled == 0 ) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
343 //disable the DMA only when all the channels are freed.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
344 periph_module_disable( PERIPH_SPI_DMA_MODULE );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
345 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
346 portEXIT_CRITICAL(&spi_dma_spinlock);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
347
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
348 return true;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
349 }
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
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 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
357 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
358 bool native=true, spi_chan_claimed, dma_chan_claimed;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
359
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
360 if (init > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
361 /* ToDo: remove this when we have flash operations cooperating with this */
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
362 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
363
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
364 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
365 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
366 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
367 else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
368 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
369 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
370
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
371 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
372 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
373 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
374 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
375 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
376
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
377 if (init > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
378 spi_chan_claimed=spi_lobo_periph_claim(host);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
379 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
380
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
381 //spihost[host]=malloc(sizeof(spi_lobo_host_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
382 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
383 if (spihost[host]==NULL) return ESP_ERR_NO_MEM;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
384 memset(spihost[host], 0, sizeof(spi_lobo_host_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
385 // Create semaphore
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
386 spihost[host]->spi_lobo_bus_mutex = xSemaphoreCreateMutex();
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
387 if (!spihost[host]->spi_lobo_bus_mutex) return ESP_ERR_NO_MEM;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
388 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
389
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
390 spihost[host]->cur_device = -1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
391 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
392
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
393 //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
394 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
395 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
396 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
397 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
398 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
399
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
400 spihost[host]->no_gpio_matrix=native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
401 if (native) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
402 //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
403 //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
404 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
405 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
406 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
407 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
408 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
409 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
410 //Use GPIO
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
411 if (bus_config->mosi_io_num>0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
412 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
413 gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
414 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
415 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
416 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
417 if (bus_config->miso_io_num>0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
418 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
419 gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
420 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
421 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
422 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
423 if (bus_config->quadwp_io_num>0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
424 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
425 gpio_set_direction(bus_config->quadwp_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
426 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
427 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
428 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
429 if (bus_config->quadhd_io_num>0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
430 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
431 gpio_set_direction(bus_config->quadhd_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
432 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
433 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
434 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
435 if (bus_config->sclk_io_num>0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
436 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
437 gpio_set_direction(bus_config->sclk_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
438 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
439 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
440 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
441 periph_module_enable(io_signal[host].module);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
442 spihost[host]->hw=io_signal[host].hw;
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 if (init > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
445 dma_chan_claimed=spi_lobo_dma_chan_claim(init);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
446 if ( !dma_chan_claimed ) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
447 spi_lobo_periph_free( host );
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
448 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
449 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
450 spihost[host]->dma_chan = init;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
451 //See how many dma descriptors we need and allocate them
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
452 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
453 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
454 spihost[host]->max_transfer_sz = dma_desc_ct*SPI_MAX_DMA_LEN;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
455
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
456 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
457 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
458 if (!spihost[host]->dmadesc_tx || !spihost[host]->dmadesc_rx) goto nomem;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
459
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
460 //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
461 spi_lobo_dmaworkaround_idle(spihost[host]->dma_chan);
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 // Reset DMA
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
464 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
465 spihost[host]->hw->dma_out_link.start=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
466 spihost[host]->hw->dma_in_link.start=0;
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_conf.out_data_burst_en=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
469
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
470 //Reset timing
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
471 spihost[host]->hw->ctrl2.val=0;
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 //Disable unneeded ints
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
474 spihost[host]->hw->slave.rd_buf_done=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
475 spihost[host]->hw->slave.wr_buf_done=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
476 spihost[host]->hw->slave.rd_sta_done=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
477 spihost[host]->hw->slave.wr_sta_done=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
478 spihost[host]->hw->slave.rd_buf_inten=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
479 spihost[host]->hw->slave.wr_buf_inten=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
480 spihost[host]->hw->slave.rd_sta_inten=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
481 spihost[host]->hw->slave.wr_sta_inten=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
482
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
483 //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
484 //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
485 //any transactions that are queued.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
486 spihost[host]->hw->slave.trans_inten=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
487 spihost[host]->hw->slave.trans_done=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
488
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
489 //Select DMA channel.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
490 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
491 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
492 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
493
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
494 nomem:
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
495 if (spihost[host]) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
496 free(spihost[host]->dmadesc_tx);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
497 free(spihost[host]->dmadesc_rx);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
498 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
499 free(spihost[host]);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
500 spi_lobo_periph_free(host);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
501 return ESP_ERR_NO_MEM;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
502 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
503
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
504 //---------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
505 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
506 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
507 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
508
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
509 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
510
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
511 if (dofree) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
512 for (int x=0; x<NO_DEV; x++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
513 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
514 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
515 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
516 if ( spihost[host]->dma_chan > 0 ) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
517 spi_lobo_dma_chan_free ( spihost[host]->dma_chan );
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 spihost[host]->hw->slave.trans_inten=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
520 spihost[host]->hw->slave.trans_done=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
521 spi_lobo_periph_free(host);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
522
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
523 if (dofree) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
524 vSemaphoreDelete(spihost[host]->spi_lobo_bus_mutex);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
525 free(spihost[host]->dmadesc_tx);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
526 free(spihost[host]->dmadesc_rx);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
527 free(spihost[host]);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
528 spihost[host] = NULL;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
529 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
530 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
531 }
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 //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
534 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
535 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
536 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
537
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
538 if (spihost[host] == NULL) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
539 esp_err_t ret = spi_lobo_bus_initialize(host, bus_config, 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
540 if (ret) return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
541 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
542
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
543 int freecs, maxdev;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
544 int apbclk=APB_CLK_FREQ;
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 if (spihost[host] == NULL) return ESP_ERR_INVALID_STATE;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
547
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
548 if (dev_config->spics_io_num >= 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
549 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
550 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
551 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
552 else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
553 //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
554 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
555
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
556 //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
557
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
558 if (dev_config->clock_speed_hz == 0) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
559 if (dev_config->spics_io_num > 0) maxdev = NO_CS;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
560 else maxdev = NO_DEV;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
561
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
562 for (freecs=0; freecs<maxdev; freecs++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
563 //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
564 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
565 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
566 if (freecs == maxdev) return ESP_ERR_NOT_FOUND;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
567
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
568 // 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
569 // duplex mode does absolutely nothing on the ESP32.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
570 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
571
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
572 // 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
573 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
574
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
575 //Allocate memory for device
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
576 spi_lobo_device_t *dev=malloc(sizeof(spi_lobo_device_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
577 if (dev==NULL) return ESP_ERR_NO_MEM;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
578
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
579 memset(dev, 0, sizeof(spi_lobo_device_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
580 spihost[host]->device[freecs]=dev;
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 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
583 dev->host=spihost[host];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
584 dev->host_dev = host;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
585
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
586 //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
587 memcpy(&dev->cfg, dev_config, sizeof(spi_lobo_device_interface_config_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
588 //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
589 memcpy(&dev->bus_config, bus_config, sizeof(spi_lobo_bus_config_t));
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
590
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
591 //Set CS pin, CS options
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
592 if (dev_config->spics_io_num > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
593 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
594 //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
595 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
596 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
597 //Use GPIO matrix
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], PIN_FUNC_GPIO);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
599 gpio_set_direction(dev_config->spics_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
600 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
601 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
602 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
603 else if (dev_config->spics_ext_io_num >= 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
604 gpio_set_direction(dev_config->spics_ext_io_num, GPIO_MODE_OUTPUT);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
605 gpio_set_level(dev_config->spics_ext_io_num, 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
606 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
607 if (dev_config->flags & LB_SPI_DEVICE_CLK_AS_CS) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
608 spihost[host]->hw->pin.master_ck_sel |= (1<<freecs);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
609 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
610 spihost[host]->hw->pin.master_ck_sel &= (1<<freecs);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
611 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
612 if (dev_config->flags & LB_SPI_DEVICE_POSITIVE_CS) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
613 spihost[host]->hw->pin.master_cs_pol |= (1<<freecs);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
614 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
615 spihost[host]->hw->pin.master_cs_pol &= (1<<freecs);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
616 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
617
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
618 *handle = dev;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
619 return ESP_OK;
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
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
622 //-------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
623 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
624 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
625 int x;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
626 if (handle == NULL) return ESP_ERR_INVALID_ARG;
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 //Remove device from list of csses and free memory
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
629 for (x=0; x<NO_DEV; x++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
630 if (handle->host->device[x] == handle) handle->host->device[x]=NULL;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
631 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
632
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
633 // 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
634 for (x=0; x<NO_DEV; x++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
635 if (spihost[handle->host_dev]->device[x] !=NULL) break;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
636 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
637 if (x == NO_DEV) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
638 free(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
639 spi_lobo_bus_free(handle->host_dev, 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
640 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
641 else free(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
642
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
643 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
644 }
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 //-----------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
647 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
648 return (fapb / (pre * n));
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
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
651 /*
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
652 * 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
653 * different from the requested frequency.
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 //-----------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
656 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
657 int pre, n, h, l, eff_clk;
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 //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
660 if (hz>((fapb/4)*3)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
661 //Using Fapb directly will give us the best result here.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
662 hw->clock.clkcnt_l=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
663 hw->clock.clkcnt_h=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
664 hw->clock.clkcnt_n=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
665 hw->clock.clkdiv_pre=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
666 hw->clock.clk_equ_sysclk=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
667 eff_clk=fapb;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
668 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
669 //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
670 //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
671 //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
672 //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
673 //with the higher n.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
674 int bestn=-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
675 int bestpre=-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
676 int besterr=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
677 int errval;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
678 for (n=1; n<=64; n++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
679 //Effectively, this does pre=round((fapb/n)/hz).
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
680 pre=((fapb/n)+(hz/2))/hz;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
681 if (pre<=0) pre=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
682 if (pre>8192) pre=8192;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
683 errval=abs(spi_freq_for_pre_n(fapb, pre, n)-hz);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
684 if (bestn==-1 || errval<=besterr) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
685 besterr=errval;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
686 bestn=n;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
687 bestpre=pre;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
688 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
689 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
690
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
691 n=bestn;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
692 pre=bestpre;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
693 l=n;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
694 //This effectively does round((duty_cycle*n)/256)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
695 h=(duty_cycle*n+127)/256;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
696 if (h<=0) h=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
697
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
698 hw->clock.clk_equ_sysclk=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
699 hw->clock.clkcnt_n=n-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
700 hw->clock.clkdiv_pre=pre-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
701 hw->clock.clkcnt_h=h-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
702 hw->clock.clkcnt_l=l-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
703 eff_clk=spi_freq_for_pre_n(fapb, pre, n);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
704 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
705 return eff_clk;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
706 }
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
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 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
712 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
713 if (handle == NULL) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
714
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
715 if ((handle->cfg.selected == 1) && (!force)) return ESP_OK; // already selected
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
716
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
717 int i;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
718 spi_lobo_host_t *host=(spi_lobo_host_t*)handle->host;
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 // find device's host bus
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
721 for (i=0; i<NO_DEV; i++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
722 if (host->device[i] == handle) break;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
723 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
724 if (i == NO_DEV) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
725
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
726 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
727
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
728 // Check if previously used device's bus device is the same
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
729 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
730 // device has different bus configuration, we need to reconfigure the bus
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
731 esp_err_t err = spi_lobo_bus_free(1, 0);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
732 if (err) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
733 xSemaphoreGive(host->spi_lobo_bus_mutex);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
734 return err;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
735 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
736 err = spi_lobo_bus_initialize(i, &handle->bus_config, -1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
737 if (err) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
738 xSemaphoreGive(host->spi_lobo_bus_mutex);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
739 return err;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
740 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
741 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
742
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
743 //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
744 if ((force) || (host->device[host->cur_device] != handle)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
745 //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
746 int apbclk=APB_CLK_FREQ;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
747
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
748 //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
749 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
750 // set speed to 32 MHz
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
751 handle->cfg.clock_speed_hz = (apbclk*2)/5;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
752 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
753
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
754 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
755 //Configure bit order
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
756 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
757 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
758
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
759 //Configure polarity
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
760 //SPI iface needs to be configured for a delay in some cases.
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
761 int nodelay=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
762 int extra_dummy=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
763 if (host->no_gpio_matrix) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
764 if (effclk >= apbclk/2) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
765 nodelay=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
766 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
767 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
768 if (effclk >= apbclk/2) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
769 nodelay=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
770 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
771 } else if (effclk >= apbclk/4) {
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 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
774 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
775 if (handle->cfg.mode==0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
776 host->hw->pin.ck_idle_edge=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
777 host->hw->user.ck_out_edge=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
778 host->hw->ctrl2.miso_delay_mode=nodelay?0:2;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
779 } else if (handle->cfg.mode==1) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
780 host->hw->pin.ck_idle_edge=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
781 host->hw->user.ck_out_edge=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
782 host->hw->ctrl2.miso_delay_mode=nodelay?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
783 } else if (handle->cfg.mode==2) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
784 host->hw->pin.ck_idle_edge=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
785 host->hw->user.ck_out_edge=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
786 host->hw->ctrl2.miso_delay_mode=nodelay?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
787 } else if (handle->cfg.mode==3) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
788 host->hw->pin.ck_idle_edge=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
789 host->hw->user.ck_out_edge=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
790 host->hw->ctrl2.miso_delay_mode=nodelay?0:2;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
791 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
792
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
793 //Configure bit sizes, load addr and command
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
794 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
795 host->hw->user.usr_addr=(handle->cfg.address_bits)?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
796 host->hw->user.usr_command=(handle->cfg.command_bits)?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
797 host->hw->user1.usr_addr_bitlen=handle->cfg.address_bits-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
798 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
799 host->hw->user2.usr_command_bitlen=handle->cfg.command_bits-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
800 //Configure misc stuff
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
801 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
802 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
803
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
804 host->hw->ctrl2.setup_time=handle->cfg.cs_ena_pretrans-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
805 host->hw->user.cs_setup=handle->cfg.cs_ena_pretrans?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
806 host->hw->ctrl2.hold_time=handle->cfg.cs_ena_posttrans-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
807 host->hw->user.cs_hold=(handle->cfg.cs_ena_posttrans)?1:0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
808
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
809 //Configure CS pin
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
810 host->hw->pin.cs0_dis=(i==0)?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
811 host->hw->pin.cs1_dis=(i==1)?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
812 host->hw->pin.cs2_dis=(i==2)?0:1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
813
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
814 host->cur_device = i;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
815 }
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 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
818 gpio_set_level(handle->cfg.spics_ext_io_num, 0);
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
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
821 handle->cfg.selected = 1;
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 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
824 }
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 //---------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
827 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
828 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
829 if (handle == NULL) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
830
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
831 if (handle->cfg.selected == 0) return ESP_OK; // already deselected
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
832
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
833 int i;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
834 spi_lobo_host_t *host=(spi_lobo_host_t*)handle->host;
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 for (i=0; i<NO_DEV; i++) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
837 if (host->device[i] == handle) break;
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 if (i == NO_DEV) return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
840
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
841 if (host->device[host->cur_device] == handle) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
842 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
843 gpio_set_level(handle->cfg.spics_ext_io_num, 1);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
844 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
845 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
846
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
847 handle->cfg.selected = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
848 xSemaphoreGive(host->spi_lobo_bus_mutex);
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 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
851 }
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 //--------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
854 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
855 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
856 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
857 else return ESP_OK;
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
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
860 //---------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
861 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
862 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
863 xSemaphoreTake(handle->host->spi_lobo_bus_mutex, portMAX_DELAY);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
864 }
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 //----------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
867 uint32_t spi_lobo_get_speed(spi_lobo_device_handle_t handle)
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 spi_lobo_host_t *host=(spi_lobo_host_t*)handle->host;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
870 uint32_t speed = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
871 if (spi_lobo_device_select(handle, 0) == ESP_OK) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
872 if (host->hw->clock.clk_equ_sysclk == 1) speed = 80000000;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
873 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
874 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
875 spi_lobo_device_deselect(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
876 return speed;
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
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
879 //--------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
880 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
881 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
882 spi_lobo_host_t *host=(spi_lobo_host_t*)handle->host;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
883 uint32_t newspeed = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
884 if (spi_lobo_device_select(handle, 0) == ESP_OK) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
885 spi_lobo_device_deselect(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
886 handle->cfg.clock_speed_hz = speed;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
887 if (spi_lobo_device_select(handle, 1) == ESP_OK) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
888 if (host->hw->clock.clk_equ_sysclk == 1) newspeed = 80000000;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
889 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
890 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
891 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
892 spi_lobo_device_deselect(handle);
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 return newspeed;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
895 }
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 //-------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
898 bool spi_lobo_uses_native_pins(spi_lobo_device_handle_t handle)
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 return handle->host->no_gpio_matrix;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
901 }
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 //-------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
904 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
905 {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
906 *sdo = io_signal[host].spid_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
907 *sdi = io_signal[host].spiq_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
908 *sck = io_signal[host].spiclk_native;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
909 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
910
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
911 /*
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
912 When using 'spi_lobo_transfer_data' function we can have several scenarios:
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 A: Send only (trans->rxlength = 0)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
915 B: Receive only (trans->txlength = 0)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
916 C: Send & receive (trans->txlength > 0 & trans->rxlength > 0)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
917 D: No operation (trans->txlength = 0 & trans->rxlength = 0)
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
918
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
919 */
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
920 //----------------------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
921 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
922 if (!handle) return ESP_ERR_INVALID_ARG;
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 // *** For now we can only handle 8-bit bytes transmission
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
925 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
926
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
927 spi_lobo_host_t *host=(spi_lobo_host_t*)handle->host;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
928 esp_err_t ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
929 uint8_t do_deselect = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
930 const uint8_t *txbuffer = NULL;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
931 uint8_t *rxbuffer = NULL;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
932
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
933 if (trans->flags & LB_SPI_TRANS_USE_TXDATA) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
934 // Send data from 'trans->tx_data'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
935 txbuffer=(uint8_t*)&trans->tx_data[0];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
936 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
937 // Send data from 'trans->tx_buffer'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
938 txbuffer=(uint8_t*)trans->tx_buffer;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
939 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
940 if (trans->flags & LB_SPI_TRANS_USE_RXDATA) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
941 // Receive data to 'trans->rx_data'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
942 rxbuffer=(uint8_t*)&trans->rx_data[0];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
943 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
944 // Receive data to 'trans->rx_buffer'
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
945 rxbuffer=(uint8_t*)trans->rx_buffer;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
946 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
947
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
948 // ** Set transmit & receive length in bytes
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
949 uint32_t txlen = trans->length / 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
950 uint32_t rxlen = trans->rxlength / 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
951
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
952 if (txbuffer == NULL) txlen = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
953 if (rxbuffer == NULL) rxlen = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
954 if ((rxlen == 0) && (txlen == 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
955 // ** NOTHING TO SEND or RECEIVE, return
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
956 return ESP_ERR_INVALID_ARG;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
957 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
958
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
959 // 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
960 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
961 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
962
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
963 // --- Wait for SPI bus ready ---
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
964 while (host->hw->cmd.usr);
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 // ** If the device was not selected, select it
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
967 if (handle->cfg.selected == 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
968 ret = spi_lobo_device_select(handle, 0);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
969 if (ret) return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
970 do_deselect = 1; // We will deselect the device after the operation !
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
971 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
972
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
973 // ** Call pre-transmission callback, if any
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
974 if (handle->cfg.pre_cb) handle->cfg.pre_cb(trans);
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 // Test if operating in full duplex mode
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
977 uint8_t duplex = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
978 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
979
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
980 uint32_t bits, rdbits;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
981 uint32_t wd;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
982 uint8_t bc, rdidx;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
983 uint32_t rdcount = rxlen; // Total number of bytes to read
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
984 uint32_t count = 0; // number of bytes transmitted
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
985 uint32_t rd_read = 0; // Number of bytes read so far
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
986
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
987 host->hw->user.usr_mosi_highpart = 0; // use the whole spi buffer
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
988
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
989 // ** Check if address phase will be used
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
990 host->hw->user2.usr_command_value=trans->command;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
991 if (handle->cfg.address_bits>32) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
992 host->hw->addr=trans->address >> 32;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
993 host->hw->slv_wr_status=trans->address & 0xffffffff;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
994 } else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
995 host->hw->addr=trans->address & 0xffffffff;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
996 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
997
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
998 // Check if we have to transmit some data
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
999 if (txlen > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1000 host->hw->user.usr_mosi = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1001 uint8_t idx;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1002 bits = 0; // remaining bits to send
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1003 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
1004
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1005 // ** Transmit 'txlen' bytes
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1006 while (count < txlen) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1007 wd = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1008 for (bc=0;bc<32;bc+=8) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1009 wd |= (uint32_t)txbuffer[count] << bc;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1010 count++; // Increment sent data count
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1011 bits += 8; // Increment bits count
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1012 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
1013 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1014 host->hw->data_buf[idx] = wd;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1015 idx++;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1016 if (idx == 16) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1017 // hw SPI buffer full (all 64 bytes filled, START THE TRANSSACTION
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1018 host->hw->mosi_dlen.usr_mosi_dbitlen=bits-1; // Set mosi dbitlen
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1019
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1020 if ((duplex) && (rdcount > 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1021 // In full duplex mode we are receiving while sending !
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1022 host->hw->miso_dlen.usr_miso_dbitlen = bits-1; // Set miso dbitlen
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1023 host->hw->user.usr_miso = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1024 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1025 else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1026 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
1027 host->hw->user.usr_miso = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1028 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1029
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1030 // ** Start the transaction ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1031 host->hw->cmd.usr=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1032 // Wait the transaction to finish
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1033 while (host->hw->cmd.usr);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1034
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1035 if ((duplex) && (rdcount > 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1036 // *** in full duplex mode transfer received data to input buffer ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1037 rdidx = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1038 while (bits > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1039 wd = host->hw->data_buf[rdidx];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1040 rdidx++;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1041 for (bc=0;bc<32;bc+=8) { // get max 4 bytes
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1042 rxbuffer[rd_read++] = (uint8_t)((wd >> bc) & 0xFF);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1043 rdcount--;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1044 bits -= 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1045 if (rdcount == 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1046 bits = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1047 break; // Finished reading data
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1048 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1049 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1050 }
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 bits = 0; // nothing in hw spi buffer yet
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1053 idx = 0; // start from the beginning of the hw spi buffer
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 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1056 // *** All transmit data are sent or pushed to hw spi buffer
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1057 // 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
1058 if (bits > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1059 // ** WE HAVE SOME DATA IN THE HW SPI TRANSMIT BUFFER
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1060 host->hw->mosi_dlen.usr_mosi_dbitlen = bits-1; // Set mosi dbitlen
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1061
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1062 if ((duplex) && (rdcount > 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1063 // In full duplex mode we are receiving while sending !
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1064 host->hw->miso_dlen.usr_miso_dbitlen = bits-1; // Set miso dbitlen
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1065 host->hw->user.usr_miso = 1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1066 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1067 else {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1068 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
1069 host->hw->user.usr_miso = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1070 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1071
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1072 // ** Start the transaction ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1073 host->hw->cmd.usr=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1074 // Wait the transaction to finish
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1075 while (host->hw->cmd.usr);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1076
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1077 if ((duplex) && (rdcount > 0)) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1078 // *** in full duplex mode transfer received data to input buffer ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1079 rdidx = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1080 while (bits > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1081 wd = host->hw->data_buf[rdidx];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1082 rdidx++;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1083 for (bc=0;bc<32;bc+=8) { // get max 4 bytes
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1084 rxbuffer[rd_read++] = (uint8_t)((wd >> bc) & 0xFF);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1085 rdcount--;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1086 bits -= 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1087 if (bits == 0) break;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1088 if (rdcount == 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1089 bits = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1090 break; // Finished reading data
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1091 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1092 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1093 }
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 //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
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 // ------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1100 // *** 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
1101 // This is true if no data receive was requested,
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1102 // 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
1103 // ------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1104 if (rdcount > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1105 // ----------------------------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1106 // *** rdcount > 0, we have to receive some data
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1107 // 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
1108 // 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
1109 // ----------------------------------------------------------------------------------------------------------------
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1110 host->hw->user.usr_mosi = 0; // do not send
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1111 host->hw->user.usr_miso = 1; // do receive
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1112 while (rdcount > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1113 if (rdcount <= 64) rdbits = rdcount * 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1114 else rdbits = 64 * 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1115
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1116 // Load receive buffer
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1117 host->hw->mosi_dlen.usr_mosi_dbitlen=0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1118 host->hw->miso_dlen.usr_miso_dbitlen=rdbits-1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1119
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1120 // ** Start the transaction ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1121 host->hw->cmd.usr=1;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1122 // Wait the transaction to finish
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1123 while (host->hw->cmd.usr);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1124
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1125 // *** transfer received data to input buffer ***
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1126 rdidx = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1127 while (rdbits > 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1128 wd = host->hw->data_buf[rdidx];
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1129 rdidx++;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1130 for (bc=0;bc<32;bc+=8) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1131 rxbuffer[rd_read++] = (uint8_t)((wd >> bc) & 0xFF);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1132 rdcount--;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1133 rdbits -= 8;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1134 if (rdcount == 0) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1135 rdbits = 0;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1136 break;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1137 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1138 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1139 }
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 // ** Call post-transmission callback, if any
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1144 if (handle->cfg.post_cb) handle->cfg.post_cb(trans);
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 if (do_deselect) {
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1147 // 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
1148 ret = spi_lobo_device_deselect(handle);
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1149 if (ret) return ret;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1150 }
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1151
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1152 return ESP_OK;
b74b0e4902c3 Initial checkin brewboard
Michiel Broek <mbroek@mbse.eu>
parents:
diff changeset
1153 }

mercurial