1 /* 2 * Copyright (C) 2019 ETH Zurich, University of Bologna 3 * and GreenWaves Technologies 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #ifndef HAL_INCLUDE_HAL_SPI_PERIPH_H_ 19 #define HAL_INCLUDE_HAL_SPI_PERIPH_H_ 20 21 #include "hal_udma_core_periph.h" 22 23 /* ---------------------------------------------------------------------------- 24 -- SPI Peripheral Access Layer -- 25 ---------------------------------------------------------------------------- */ 26 27 /** SPI_Type Register Layout Typedef */ 28 typedef struct { 29 udma_channel_t rx; /**< UDMA RX channels struct. */ 30 udma_channel_t tx; /**< UDMA RX channels struct. */ 31 udma_channel_t cmd; /**< UDMA RX channels struct. */ 32 } spi_t; 33 34 /* ---------------------------------------------------------------------------- 35 -- SPI Register Bitfield Access -- 36 ---------------------------------------------------------------------------- */ 37 38 /* SPI command fields offset, mask, value definition */ 39 /* SPI commands fields offsets */ 40 #define SPI_CMD_ID_OFFSET 28 41 42 /* COMMON definitions */ 43 #define SPI_CMD_QPI_ENA 1 44 #define SPI_CMD_QPI_DIS 0 45 #define SPI_CMD_LSB_FIRST 1 46 #define SPI_CMD_MSB_FIRST 0 47 #define SPI_CMD_4_WORD_PER_TRANSF 2 48 #define SPI_CMD_2_WORD_PER_TRANSF 1 49 #define SPI_CMD_1_WORD_PER_TRANSF 0 50 #define SPI_CMD_DATA_WITDH(val) (val) 51 #define SPI_CMD_CMD_SIZE(val) (val) 52 53 /* CFG */ 54 #define SPI_CMD_CFG_CLK_DIV_OFFSET 0 55 #define SPI_CMD_CFG_CLK_DIV_WIDTH 8 56 #define SPI_CMD_CFG_CPHA_OFFSET 8 57 #define SPI_CMD_CFG_CPOL_OFFSET 9 58 59 #define SPI_CMD_CFG_CLKDIV(val) (val) 60 #define SPI_CMD_CFG_CPOL_POS 1 61 #define SPI_CMD_CFG_CPOL_NEG 0 62 #define SPI_CMD_CFG_CPHA_STD 1 63 #define SPI_CMD_CFG_CPHA_OPP 0 64 65 /* SOT */ 66 #define SPI_CMD_SOT_CS_OFFSET 0 67 #define SPI_CMD_SOT_CS_WIDTH 2 68 69 #define SPI_CMD_SOT_CS0 0 70 #define SPI_CMD_SOT_CS1 1 71 #define SPI_CMD_SOT_CS2 2 72 #define SPI_CMD_SOT_CS3 3 73 74 /* SEND_CMD */ 75 #define SPI_CMD_SEND_CMD_CMD_OFFSET 0 76 #define SPI_CMD_SEND_CMD_CMD_WIDTH 16 77 #define SPI_CMD_SEND_CMD_SIZE_OFFSET 16 78 #define SPI_CMD_SEND_CMD_SIZE_WIDTH 4 79 #define SPI_CMD_SEND_CMD_QPI_OFFSET 27 80 81 /* SEND_CMD */ 82 #define SPI_CMD_SEND_BITS_BITS_OFFSET 0 83 #define SPI_CMD_SEND_BITS_BITS_WIDTH 16 84 #define SPI_CMD_SEND_BITS_SIZE_OFFSET 16 85 #define SPI_CMD_SEND_BITS_SIZE_WIDTH 4 86 #define SPI_CMD_SEND_BITS_QPI_OFFSET 27 87 88 /* SEND_ADDR */ 89 #define SPI_CMD_SEND_ADDR_SIZE_OFFSET 16 90 #define SPI_CMD_SEND_ADDR_SIZE_WIDTH 5 91 #define SPI_CMD_SEND_ADDR_QPI_OFFSET 27 92 93 #define SPI_CMD_SEND_ADDR_VALUE(value) (value) 94 95 /* SEND_DUMMY */ 96 #define SPI_CMD_DUMMY_CYCLE_OFFSET 16 97 #define SPI_CMD_DUMMY_CYCLE_WIDTH 5 98 99 /* TX_DATA */ 100 #define SPI_CMD_TX_DATA_SIZE_OFFSET 0 101 #define SPI_CMD_TX_DATA_SIZE_WIDTH 16 102 #define SPI_CMD_TX_DATA_QPI_OFFSET 27 103 #define SPI_CMD_TX_DATA_WORDTRANS_OFFSET 21 104 #define SPI_CMD_TX_DATA_WORDTRANS_WIDTH 2 105 #define SPI_CMD_TX_DATA_LSBFIRST_OFFSET 26 106 #define SPI_CMD_TX_DATA_BITSWORD_OFFSET 16 107 #define SPI_CMD_TX_DATA_BITSWORD_WIDTH 5 108 109 /* RX_DATA */ 110 #define SPI_CMD_RX_DATA_SIZE_OFFSET 0 111 #define SPI_CMD_RX_DATA_SIZE_WIDTH 16 112 #define SPI_CMD_RX_DATA_QPI_OFFSET 27 113 #define SPI_CMD_RX_DATA_WORDTRANS_OFFSET 21 114 #define SPI_CMD_RX_DATA_WORDTRANS_WIDTH 2 115 #define SPI_CMD_RX_DATA_LSBFIRST_OFFSET 26 116 #define SPI_CMD_RX_DATA_BITSWORD_OFFSET 16 117 #define SPI_CMD_RX_DATA_BITSWORD_WIDTH 5 118 119 /* RPT */ 120 #define SPI_CMD_RPT_NB_OFFSET 0 121 #define SPI_CMD_RPT_NB_WIDTH 16 122 123 /* EOT */ 124 #define SPI_CMD_EOT_GEN_EVT_OFFSET 0 125 #define SPI_CMD_EOT_CS_KEEP_OFFSET 1 126 127 #define SPI_CMD_EOT_EVENT_ENA 1 128 #define SPI_CMD_EOT_EVENT_DIS 0 129 130 /* WAIT */ 131 #define SPI_CMD_WAIT_EVENT_OFFSET 0 132 #define SPI_CMD_WAIT_EVENT_WIDTH 2 133 134 /* RX_CHECK */ 135 #define SPI_CMD_RX_CHECK_VALUE_OFFSET 0 136 #define SPI_CMD_RX_CHECK_VALUE_WIDTH 16 137 138 #define SPI_CMD_RX_CHECK_SIZE_OFFSET 16 139 #define SPI_CMD_RX_CHECK_SIZE_WIDTH 4 140 141 #define SPI_CMD_RX_CHECK_MODE_OFFSET 24 142 #define SPI_CMD_RX_CHECK_MODE_WIDTH 2 143 144 #define SPI_CMD_RX_CHECK_BYTE_ALIGN_OFFSET 26 145 146 #define SPI_CMD_RX_CHECK_QPI_OFFSET 27 147 148 #define SPI_CMD_RX_CHECK_MODE_MATCH 0 149 #define SPI_CMD_RX_CHECK_MODE_ONES 1 150 #define SPI_CMD_RX_CHECK_MODE_ZEROS 2 151 #define SPI_CMD_RX_CHECK_MODE_MASK 3 152 153 /* FULL DUPLEX */ 154 #define SPI_CMD_FUL_SIZE_OFFSET 0 155 #define SPI_CMD_FUL_SIZE_WIDTH 16 156 #define SPI_CMD_FUL_WORDTRANS_OFFSET 21 157 #define SPI_CMD_FUL_WORDTRANS_WIDTH 2 158 #define SPI_CMD_FUL_LSBFIRST_OFFSET 26 159 #define SPI_CMD_FUL_BITSWORD_OFFSET 16 160 #define SPI_CMD_FUL_BITSWORD_WIDTH 5 161 162 #define SPI_CMD_SETUP_UC_TXRXEN_OFFSET 27 163 #define SPI_CMD_SETUP_UC_DS_OFFSET 25 164 165 /* ---------------------------------------------------------------------------- 166 -- SPI CMD IDs and macros -- 167 ---------------------------------------------------------------------------- */ 168 169 /*! @name CMD_CFG */ 170 /* Channel continuous mode: 171 - 1'b0: disable 172 - 1'b1: enable 173 At the end of the buffer the uDMA reloads the address and size and starts a new transfer. */ 174 #define UDMA_CORE_CMD_CFG_CONTINOUS_MASK (0x1) 175 #define UDMA_CORE_CMD_CFG_CONTINOUS_SHIFT (0) 176 #define UDMA_CORE_CMD_CFG_CONTINOUS(val) \ 177 (((uint32_t)(((uint32_t)(val)) \ 178 << UDMA_CORE_CMD_CFG_CONTINOUS_SHIFT)) & \ 179 UDMA_CORE_CMD_CFG_CONTINOUS_MASK) 180 181 /* Channel transfer size used to increment uDMA buffer address pointer: 182 - 2'b00: +1 (8 bits) 183 - 2'b01: +2 (16 bits) 184 - 2'b10: +4 (32 bits) 185 - 2'b11: +0 */ 186 #define UDMA_CORE_CMD_CFG_DATASIZE_MASK (0x6) 187 #define UDMA_CORE_CMD_CFG_DATASIZE_SHIFT (1) 188 #define UDMA_CORE_CMD_CFG_DATASIZE(val) \ 189 (((uint32_t)(((uint32_t)(val)) << UDMA_CORE_CMD_CFG_DATASIZE_SHIFT)) & \ 190 UDMA_CORE_CMD_CFG_DATASIZE_MASK) 191 192 /* Reserved/Not used. */ 193 #define UDMA_CORE_CMD_CFG_RESERVED_0_MASK (0x8) 194 #define UDMA_CORE_CMD_CFG_RESERVED_0_SHIFT (3) 195 #define UDMA_CORE_CMD_CFG_RESERVED_0(val) \ 196 (((uint32_t)(((uint32_t)(val)) \ 197 << UDMA_CORE_CMD_CFG_RESERVED_0_SHIFT)) & \ 198 UDMA_CORE_CMD_CFG_RESERVED_0_MASK) 199 200 /* Channel enable and start transfer: 201 - 1'b0: disable 202 - 1'b1: enable 203 This signal is used also to queue a transfer if one is already ongoing. */ 204 #define UDMA_CORE_CMD_CFG_EN_MASK (0x10) 205 #define UDMA_CORE_CMD_CFG_EN_SHIFT (4) 206 #define UDMA_CORE_CMD_CFG_EN(val) \ 207 (((uint32_t)(((uint32_t)(val)) << UDMA_CORE_CMD_CFG_EN_SHIFT)) & \ 208 UDMA_CORE_CMD_CFG_EN_MASK) 209 210 /* Transfer pending in queue status flag: 211 - 1'b0: no pending transfer in the queue 212 - 1'b1: pending transfer in the queue */ 213 #define UDMA_CORE_CMD_CFG_PENDING_MASK (0x20) 214 #define UDMA_CORE_CMD_CFG_PENDING_SHIFT (5) 215 #define UDMA_CORE_CMD_CFG_PENDING(val) \ 216 (((uint32_t)(((uint32_t)(val)) << UDMA_CORE_CMD_CFG_PENDING_SHIFT)) & \ 217 UDMA_CORE_CMD_CFG_PENDING_MASK) 218 219 /* Channel clear and stop transfer: 220 - 1'b0: disable 221 - 1'b1: stop and clear the on-going transfer */ 222 #define UDMA_CORE_CMD_CFG_CLR_MASK (0x20) 223 #define UDMA_CORE_CMD_CFG_CLR_SHIFT (5) 224 #define UDMA_CORE_CMD_CFG_CLR(val) \ 225 (((uint32_t)(((uint32_t)(val)) << UDMA_CORE_CMD_CFG_CLR_SHIFT)) & \ 226 UDMA_CORE_CMD_CFG_CLR_MASK) 227 228 /* Reserved/Not used. */ 229 #define UDMA_CORE_CMD_CFG_RESERVED_1_MASK (0xffffff80) 230 #define UDMA_CORE_CMD_CFG_RESERVED_1_SHIFT (7) 231 #define UDMA_CORE_CMD_CFG_RESERVED_1(val) \ 232 (((uint32_t)(((uint32_t)(val)) \ 233 << UDMA_CORE_CMD_CFG_RESERVED_1_SHIFT)) & \ 234 UDMA_CORE_CMD_CFG_RESERVED_1_MASK) 235 236 /*! @name CMD_INITCFG */ 237 /* Reserved/Not used. */ 238 #define UDMA_CORE_CMD_INITCFG_RESERVED_0_MASK (0xffffffff) 239 #define UDMA_CORE_CMD_INITCFG_RESERVED_0_SHIFT (0) 240 #define UDMA_CORE_CMD_INITCFG_RESERVED_0(val) \ 241 (((uint32_t)(((uint32_t)(val)) \ 242 << UDMA_CORE_CMD_INITCFG_RESERVED_0_SHIFT)) & \ 243 UDMA_CORE_CMD_INITCFG_RESERVED_0_MASK) 244 245 #define SPI_CMD_CFG_ID 0x0 /* Sets the configuration for the SPI Master IP. */ 246 #define SPI_CMD_SOT_ID 0x1 /* Sets the Chip Select (CS). */ 247 #define SPI_CMD_SEND_CMD_ID 0x2 /* Transmits a configurable size command. */ 248 #define SPI_CMD_SEND_BITS_ID 0x2 /* Transmits a configurable size command. */ 249 #define SPI_CMD_SEND_ADDR_ID 0x3 /* Transmits a configurable size address. */ 250 #define SPI_CMD_DUMMY_ID \ 251 0x4 /* Receives a number of dummy bits (not sent to the rx interface). */ 252 #define SPI_CMD_WAIT_ID \ 253 0x5 /* Waits an external event to move to the next instruction. */ 254 #define SPI_CMD_TX_DATA_ID 0x6 /* Sends data (max 64Kbits). */ 255 #define SPI_CMD_RX_DATA_ID 0x7 /* Receives data (max 64Kbits). */ 256 #define SPI_CMD_RPT_ID 0x8 /* Repeat the next transfer N times. */ 257 #define SPI_CMD_EOT_ID 0x9 /* Clears the Chip Select (CS). */ 258 #define SPI_CMD_RPT_END_ID 0xA /* End of the repeat loop command. */ 259 #define SPI_CMD_RX_CHECK_ID \ 260 0xB /* Check up ot 16 bits of data against an expected value. */ 261 #define SPI_CMD_FULL_DUPL_ID 0xC /* Activate full duplex mode. */ 262 263 #define SPI_CMD_CFG(clockDiv, cpol, cpha) \ 264 ((SPI_CMD_CFG_ID << SPI_CMD_ID_OFFSET) | \ 265 ((cpol) << SPI_CMD_CFG_CPOL_OFFSET) | \ 266 ((cpha) << SPI_CMD_CFG_CPHA_OFFSET) | \ 267 ((clockDiv) << SPI_CMD_CFG_CLK_DIV_OFFSET)) 268 #define SPI_CMD_SOT(cs) \ 269 ((SPI_CMD_SOT_ID << SPI_CMD_ID_OFFSET) | \ 270 ((cs) << SPI_CMD_SOT_CS_OFFSET)) 271 #define SPI_CMD_SEND_CMD(cmd, bits, qpi) \ 272 ((SPI_CMD_SEND_CMD_ID << SPI_CMD_ID_OFFSET) | \ 273 ((qpi) << SPI_CMD_SEND_CMD_QPI_OFFSET) | \ 274 (((bits)-1) << SPI_CMD_SEND_CMD_SIZE_OFFSET) | (cmd & 0xFFFF)) 275 #define SPI_CMD_SEND_BITS(data, bits, qpi) \ 276 ((SPI_CMD_SEND_CMD_ID << SPI_CMD_ID_OFFSET) | \ 277 ((qpi) << SPI_CMD_SEND_CMD_QPI_OFFSET) | \ 278 (((bits)-1) << SPI_CMD_SEND_CMD_SIZE_OFFSET) | (data & 0xFFFF)) 279 #define SPI_CMD_DUMMY(cycles) \ 280 ((SPI_CMD_DUMMY_ID << SPI_CMD_ID_OFFSET) | \ 281 (((cycles)-1) << SPI_CMD_DUMMY_CYCLE_OFFSET)) 282 283 #define SPI_CMD_SETUP_UCA(txrxen, ds, addr) \ 284 ((SPI_CMD_SETUP_UCA_ID << SPI_CMD_ID_OFFSET) | \ 285 ((txrxen) << SPI_CMD_SETUP_UC_TXRXEN_OFFSET) | ((int)addr & 0xFFFFF)) 286 #define SPI_CMD_SETUP_UCS(txrxen, ds, size) \ 287 ((SPI_CMD_SETUP_UCS_ID << SPI_CMD_ID_OFFSET) | \ 288 ((txrxen) << SPI_CMD_SETUP_UC_TXRXEN_OFFSET) | \ 289 ((ds) << SPI_CMD_SETUP_UC_DS_OFFSET) | (size & 0xFFFF)) 290 291 #define SPI_CMD_TX_DATA(words, wordstrans, bitsword, qpi, lsbfirst) \ 292 ((SPI_CMD_TX_DATA_ID << SPI_CMD_ID_OFFSET) | \ 293 ((qpi) << SPI_CMD_TX_DATA_QPI_OFFSET) | \ 294 ((wordstrans) << SPI_CMD_TX_DATA_WORDTRANS_OFFSET) | \ 295 ((bitsword - 1) << SPI_CMD_TX_DATA_BITSWORD_OFFSET) | \ 296 (((words)-1) << SPI_CMD_TX_DATA_SIZE_OFFSET) | \ 297 ((lsbfirst) << SPI_CMD_TX_DATA_LSBFIRST_OFFSET)) 298 #define SPI_CMD_RX_DATA(words, wordstrans, bitsword, qpi, lsbfirst) \ 299 ((SPI_CMD_RX_DATA_ID << SPI_CMD_ID_OFFSET) | \ 300 ((qpi) << SPI_CMD_RX_DATA_QPI_OFFSET) | \ 301 ((wordstrans) << SPI_CMD_RX_DATA_WORDTRANS_OFFSET) | \ 302 ((bitsword - 1) << SPI_CMD_RX_DATA_BITSWORD_OFFSET) | \ 303 (((words)-1) << SPI_CMD_RX_DATA_SIZE_OFFSET) | \ 304 ((lsbfirst) << SPI_CMD_RX_DATA_LSBFIRST_OFFSET)) 305 #define SPI_CMD_RPT(iter) \ 306 ((SPI_CMD_RPT_ID << SPI_CMD_ID_OFFSET) | \ 307 ((iter) << SPI_CMD_RPT_NB_OFFSET)) 308 #define SPI_CMD_EOT(evt, cs_keep) \ 309 ((SPI_CMD_EOT_ID << SPI_CMD_ID_OFFSET) | \ 310 ((evt) << SPI_CMD_EOT_GEN_EVT_OFFSET) | \ 311 ((cs_keep) << SPI_CMD_EOT_CS_KEEP_OFFSET)) 312 313 #define SPI_CMD_RX_CHECK(mode, bits, value, qpi, byte_align) \ 314 ((SPI_CMD_RX_CHECK_ID << SPI_CMD_ID_OFFSET) | \ 315 ((value) << SPI_CMD_RX_CHECK_VALUE_OFFSET) | \ 316 ((mode) << SPI_CMD_RX_CHECK_MODE_OFFSET) | \ 317 (((bits)-1) << SPI_CMD_RX_CHECK_SIZE_OFFSET) | \ 318 ((byte_align) << SPI_CMD_RX_CHECK_BYTE_ALIGN_OFFSET) | \ 319 ((qpi) << SPI_CMD_RX_CHECK_QPI_OFFSET)) 320 321 #define SPI_CMD_WAIT(event) \ 322 ((SPI_CMD_WAIT_ID << SPI_CMD_ID_OFFSET) | \ 323 ((event) << SPI_CMD_WAIT_EVENT_OFFSET)) 324 #define SPI_CMD_RPT_END() ((SPI_CMD_RPT_END_ID << SPI_CMD_ID_OFFSET)) 325 #define SPI_CMD_FUL(words, wordstrans, bitsword, lsbfirst) \ 326 ((SPI_CMD_FUL_ID << SPI_CMD_ID_OFFSET) | \ 327 ((wordstrans) << SPI_CMD_FUL_WORDTRANS_OFFSET) | \ 328 ((bitsword - 1) << SPI_CMD_FUL_BITSWORD_OFFSET) | \ 329 (((words)-1) << SPI_CMD_FUL_SIZE_OFFSET) | \ 330 ((lsbfirst) << SPI_CMD_FUL_LSBFIRST_OFFSET)) 331 332 333 #endif /* HAL_INCLUDE_HAL_SPI_PERIPH_H_ */ 334