1 /******************************************************************************* 2 * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions. 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 * 24 * PolarFire SoC Microprocessor Subsystem SPI bare metal software 25 * driver public API. 26 */ 27 /*=========================================================================*//** 28 @mainpage PolarFire SoC MSS SPI Bare Metal Driver. 29 30 @section intro_sec Introduction 31 The PolarFire SoC Microprocessor Subsystem (MSS) includes two serial 32 peripheral interface (SPI) peripherals for serial communication. This driver 33 provides a set of functions for controlling the MSS SPIs as part of a bare 34 metal system where no operating system is available. These drivers can be 35 adapted for use as part of an operating system, but the implementation of the 36 adaptation layer between this driver and the operating system's driver model 37 is outside the scope of this driver. 38 39 @section hw_dependencies Hardware Flow Dependencies 40 The configuration of all features of the MSS SPI peripherals is covered by 41 this driver with the exception of the PolarFire SoC IOMUX configuration. 42 PolarFire SoC allows multiple non-concurrent uses of some external pins through 43 IOMUX configuration. This feature allows optimization of external pin usage by 44 assigning external pins for use by either the microprocessor subsystem or the 45 FPGA fabric. The MSS SPI serial signals are routed through IOMUXs to the 46 PolarFire SoC device external pins. The MSS SPI serial signals may also be 47 routed through IOMUXs to the PolarFire SoC FPGA fabric. 48 The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You 49 must ensure that the MSS SPI peripherals are enabled and configured in the 50 PolarFire SoC MSS configurator if you wish to use them. For more information 51 on IOMUX, refer to the I/O Configuration section of the PolarFire SoC 52 Microprocessor Subsystem (MSS) User's Guide. 53 The base address, register addresses and interrupt number assignment for the 54 MSS SPI peripherals are defined as constants in the PolarFire SoC HAL. 55 You must ensure that the latest PolarFire SoC HAL is included in the 56 project settings of the software tool chain used to build your project and 57 that it is generated into your project. 58 59 @section theory_op Theory of Operation 60 The MSS SPI driver functions are grouped in following categories: 61 • Initialization 62 • Configure either master or slave mode 63 • SPI Master frame transfer control 64 • SPI Master block transfer control 65 • SPI Slave frame transfer control 66 • SPI Slave block transfer control 67 Frame transfer allows the MSS SPI to write or read up to 32 bits of data in a 68 SPI transaction. For example, a frame transfer of 12 bits might be used to 69 read the result of ADC conversion from SPI analog to digital converter. 70 Block transfer allows the MSS SPI to write and read several bytes in a SPI 71 transaction. Block transfer transaction allow the data transfer in multiple of 72 8 bits (8, 16, 24, 32 ….). Block transfers are typically used with the 73 byte-oriented devices such as SPI FLASH device. 74 75 76 Initialization 77 The MSS SPI driver is initialized through a call to the MSS_SPI_init() 78 function. The MSS_SPI_init() function takes only one parameter, a pointer to 79 one of two global data structures used by the driver to store state 80 information for each MSS SPI. A pointer to these data structures is also used 81 as first parameter to any of the driver functions to identify which MSS SPI 82 will be used by the called function. The names of these two data structures 83 are g_mss_spi0 and g_mss_spi1. Therefore any call to an MSS SPI driver 84 function should be of the form MSS_SPI_function_name(&g_mss_spi0, ... ) or 85 MSS_SPI_function_name( &g_mss_spi1, ... ). 86 The user must reset the MSS SPI core before calling MSS_SPI_init() function. 87 The MSS_SPI_init() function resets the specified MSS SPI hardware block and 88 clears any pending interrupts from local interrupt controller or PLIC. 89 The MSS_SPI_init() function must be called before any other MSS SPI driver 90 functions can be called. 91 92 Configuration 93 An MSS SPI block can operate either as a master or slave SPI device. There are 94 two distinct functions for configuring a MSS SPI block for master or slave 95 operations. 96 97 Master configuration 98 The MSS_SPI_configure_master_mode() function configures the specified MSS SPI 99 block for operations as a SPI master. It must be called once for each remote 100 SPI slave device which the MSS SPI block will communicate with. It is used to 101 provide the following information about each SPI slave’s communication 102 characteristics: 103 • The SPI protocol mode 104 • The SPI clock speed 105 • The frame bit length 106 • The SPI overflow handler 107 This information is held by the driver and will be used to alter the 108 configuration of the MSS SPI block each time a slave is selected through a 109 call to MSS_SPI_set_slave_select(). The SPI protocol mode defines the initial 110 state of the clock signal at the start of a transaction and which clock edge 111 will be used to sample the data signal (Motorola SPI modes), or it defines 112 whether the SPI block will operate in Texas Instruments (TI) synchronous 113 serial mode or in National Semiconductor (NSC) MICROWIRE mode. 114 The MSS_SPI_configure_master_mode() function will register the 115 MSS_SPI_overflow_handler() function to the SPI instance, 116 MSS_SPI_overflow_handler() function is used by driver in case of buffer 117 overflow. 118 119 Slave configuration 120 The MSS_SPI_configure_slave_mode() function configures the specified MSS SPI 121 block for operations as a SPI slave. It configures the following SPI 122 communication characteristics: 123 • The SPI protocol mode 124 • The frame bit length 125 • The SPI overflow handler 126 The SPI protocol mode defines the initial state of the clock signal at the 127 start of a transaction and which clock edge will be used to sample the data 128 signal (Motorola SPI modes), or it defines whether the SPI block will operate 129 in TI synchronous serial mode or in NSC MICROWIRE mode. 130 The MSS_SPI_configure_slave_mode() function will register the 131 MSS_SPI_overflow_handler() function to the SPI instance, 132 MSS_SPI_overflow_handler() function is used by driver in case of buffer 133 overflow. 134 135 SPI master frame transfer control 136 The following functions are used as part of SPI master frame transfers: 137 - MSS_SPI_set_slave_select() 138 - MSS_SPI_transfer_frame() 139 - MSS_SPI_clear_slave_select() 140 The master must first select the target slave through a call to 141 MSS_SPI_set_slave_select(). This causes the relevant slave select line to 142 become asserted while data is clocked out onto the SPI data line. 143 A call is then made to MSS_SPI_transfer_frame() specifying the value of the 144 data frame to be sent. 145 The function MSS_SPI_clear_slave_select() can be used after the transfer is 146 complete to prevent this slave select line from being asserted during 147 subsequent SPI transactions. A call to this function is only required if the 148 master is communicating with multiple slave devices. 149 150 SPI master block transfer control 151 The following functions are used as part of SPI master block transfers: 152 - MSS_SPI_set_slave_select() 153 - MSS_SPI_clear_slave_select() 154 - MSS_SPI_transfer_block() 155 The master must first select the target slave through a call to 156 MSS_SPI_set_slave_select(). This causes the relevant slave select line to 157 become asserted while data is clocked out onto the SPI data line. 158 A call is then made to MSS_SPI_transfer_block (). The parameters of 159 this function specify: 160 - the number of bytes to be transmitted 161 - a pointer to the buffer containing the data to be transmitted 162 - the number of bytes to be received 163 - a pointer to the buffer where received data will be stored 164 The number of bytes to be transmitted can be set to zero to indicate that the 165 transfer is purely a block read transfer. Alternatively, the number of bytes 166 to be received can be set to zero to specify that the transfer is purely a 167 block write transfer. 168 The function MSS_SPI_clear_slave_select() can be used after the transfer is 169 complete to prevent this slave select line from being asserted during 170 subsequent SPI transactions. A call to this function is only required if the 171 master is communicating with multiple slave devices. 172 Note: Unlike in previous versions of this driver, the SPS bit is set in the 173 CONTROL register in Motorola modes so that the Slave Select line remains 174 asserted throughout block transfers. 175 176 SPI slave frame transfer control 177 The following functions are used as part of SPI slave frame transfers: 178 - MSS_SPI_set_slave_tx_frame() 179 - MSS_SPI_set_frame_rx_handler() 180 The MSS_SPI_set_slave_tx_frame() function specifies the frame data that will 181 be returned to the SPI master. The frame data specified through this function 182 is the value that will be read over the SPI bus by the remote SPI master when 183 it initiates a transaction. A call to MSS_SPI_set_slave_tx_frame() is only 184 required if the MSS SPI slave is the target of SPI read transactions, i.e. if 185 data is meant to be read from the PolarFire SoC device over SPI. 186 The MSS_SPI_set_frame_rx_handler() function specifies the receive handler 187 function that will called when a frame of data has been received by the MSS 188 SPI when it is configured as a slave. The receive handler function specified 189 through this call will process the frame data written, over the SPI bus, to 190 the MSS SPI slave by the remote SPI master. The receive handler function must 191 be implemented as part of the application. It is only required if the MSS SPI 192 slave is the target of SPI frame write transactions. 193 Successive master writes need to take into account the time taken to execute 194 the receive handler if the interface is to work reliably. 195 SPI slave block transfer control 196 The following functions are used as part of SPI slave block transfers: 197 - MSS_SPI_set_slave_block_buffers() 198 - MSS_SPI_set_cmd_handler() 199 - MSS_SPI_set_cmd_response() 200 The MSS_SPI_set_slave_block_buffers() function is used to configure a MSS SPI 201 slave for block transfer operations. It specifies: 202 - The buffer containing the data that will be returned to the remote SPI 203 master 204 - The buffer where data received from the remote SPI master will be stored 205 - The handler function that will be called after the receive buffer has been 206 filled 207 The MSS_SPI_set_cmd_handler() function specifies a command handler function 208 that will be called by the driver once a specific number of bytes has been 209 received after the SPI chip select signal becoming active. The number of bytes 210 making up the command part of the transaction is specified as part of the 211 parameters to MSS_SPI_set_cmd_handler(). The command handler function 212 is implemented as part of the application making use of the SPI driver and 213 would typically call the MSS_SPI_set_cmd_response() function. 214 The MSS_SPI_set_cmd_response() function specifies the data that will be 215 returned to the master. Typically the MSS_SPI_set_slave_block_buffers() will 216 have been called as part of the system initialization to specify the data sent 217 to the master while the command bytes are being received. The transmit buffer 218 specified through the call to MSS_SPI_set_slave_block_buffers() would also 219 typically include one or more bytes allowing for the turn around time required 220 for the command handler function to execute and call 221 MSS_SPI_set_cmd_response(). 222 223 *//*=========================================================================*/ 224 #ifndef MSS_SPI_H_ 225 #define MSS_SPI_H_ 226 227 #include <stddef.h> 228 #include <stdint.h> 229 230 /*Register map of the MPFS MSS SPI*/ 231 typedef struct 232 { 233 volatile uint32_t CONTROL; 234 volatile uint32_t FRAMESIZE;/* SPEC 2.13 , removed TXRXDF_SIZE;*/ 235 volatile uint32_t STATUS; 236 volatile uint32_t INT_CLEAR; 237 volatile uint32_t RX_DATA; 238 volatile uint32_t TX_DATA; 239 volatile uint32_t CLK_GEN; 240 volatile uint32_t SLAVE_SELECT; 241 volatile uint32_t MIS; 242 volatile uint32_t RIS; 243 volatile uint32_t CONTROL2; 244 volatile uint32_t COMMAND; 245 volatile uint32_t PKTSIZE; 246 volatile uint32_t CMDSIZE; 247 volatile uint32_t HWSTATUS; 248 volatile uint32_t STAT8; 249 volatile uint32_t CTRL0; 250 volatile uint32_t CTRL1; 251 volatile uint32_t CTRL2; 252 volatile uint32_t CTRL3; 253 volatile uint32_t FRAMESUP; /* SPEC 2.13 */ 254 } SPI_TypeDef; 255 256 #define SPI0_LO_BASE 0x20108000u 257 #define SPI1_LO_BASE 0x20109000u 258 #define SPI0_HI_BASE 0x28108000u 259 #define SPI1_HI_BASE 0x28109000u 260 261 #define MSS_SPI0_LO_BASE ((SPI_TypeDef *) SPI0_LO_BASE) 262 #define MSS_SPI1_LO_BASE ((SPI_TypeDef *) SPI1_LO_BASE) 263 #define MSS_SPI0_HI_BASE ((SPI_TypeDef *) SPI0_HI_BASE) 264 #define MSS_SPI1_HI_BASE ((SPI_TypeDef *) SPI1_HI_BASE) 265 266 #ifdef __cplusplus 267 extern "C" { 268 #endif 269 270 /***************************************************************************//** 271 This defines the function prototype that must be followed by MSS SPI slave 272 frame receive handler functions. These functions are registered with the MSS 273 SPI driver through the MSS_SPI_set_frame_rx_handler () function. 274 275 Declaring and Implementing Slave Frame Receive Handler Functions: 276 Slave frame receive handler functions should follow the following prototype: 277 void slave_frame_receive_handler ( uint32_t rx_frame ); 278 The actual name of the receive handler is unimportant. You can use any name 279 of your choice for the receive frame handler. The rx_frame parameter will 280 contain the value of the received frame. 281 */ 282 typedef void (*mss_spi_frame_rx_handler_t)( uint32_t rx_frame ); 283 284 /***************************************************************************//** 285 This defines the function prototype that must be followed by MSS SPI slave 286 block receive handler functions. These functions are registered with the MSS 287 SPI driver through the MSS_SPI_set_slave_block_buffers() function. 288 289 Declaring and Implementing Slave Block Receive Handler Functions 290 Slave block receive handler functions should follow the following prototype: 291 void mss_spi_block_rx_handler ( uint8_t * rx_buff, uint16_t rx_size ); 292 The actual name of the receive handler is unimportant. You can use any name 293 of your choice for the receive frame handler. The rx_buff parameter will 294 contain a pointer to the start of the received block. The rx_size parameter 295 indicates the number of bytes in the received block. 296 297 */ 298 typedef void (*mss_spi_block_rx_handler_t)(uint8_t * rx_buff, uint32_t rx_size); 299 300 /**************************************************************************//** 301 This defines the function prototype that must be used by the MSS SPI init 302 functions. This handler functions is registered with the MSS SPI driver 303 through the MSS_SPI_init() function. 304 Declaring and Implementing Overflow handler functions 305 The buffer overflow handler functions must use the following prototype 306 void mss_spi0_overflow_handler(uint8_t mss_spi_core); 307 The actual name of the overflow handler is not important. User can use any 308 name of choice. This function is passed as a argument to the MSS_SPI_init(), 309 which registers overflow handler to the MSS SPI instance.The parameter 310 passed with the function informs the handler function about which SPI core 311 to reset.This variable can later be used by the driver to recover from 312 buffer overflow situations. 313 */ 314 typedef void (*mss_spi_oveflow_handler_t)(uint8_t mss_spi_core); 315 316 /***************************************************************************//** 317 This enumeration is used to define the settings for the SPI protocol mode 318 bits which select the different modes of operation for the MSS SPI. It is used 319 as a parameter to the MSS_SPI_configure_master_mode() and 320 MSS_SPI_configure_slave_mode() functions. 321 322 - MSS_SPI_MODE0: 323 Clock starts low, data read on clock's rising edge, data changes on 324 falling edge. 325 326 - MSS_SPI_MODE1: 327 Clock starts low, data read on clock's falling edge, data changes on 328 rising edge. 329 330 - MSS_SPI_MODE2: 331 Clock starts high, data read on clock's falling edge, data changes on 332 rising edge. 333 334 - MSS_SPI_MODE3: 335 Clock starts high, data read on clock's rising edge, data changes on 336 falling edge. 337 338 - MSS_TI_MODE: 339 TI synchronous serial mode. Slave select is pulsed at start of transfer. 340 341 - MSS_NSC_MODE: 342 NSC Microwire mode. 343 */ 344 typedef enum __mss_spi_protocol_mode_t 345 { 346 MSS_SPI_MODE0 = 0x00000000, 347 MSS_SPI_TI_MODE = 0x01000004, 348 MSS_SPI_NSC_MODE = 0x00000008, 349 MSS_SPI_MODE2 = 0x01000000, 350 MSS_SPI_MODE1 = 0x02000000, 351 MSS_SPI_MODE3 = 0x03000000 352 } mss_spi_protocol_mode_t; 353 354 /***************************************************************************//** 355 This enumeration is used to select a specific SPI slave device (0 to 7). It is 356 used as a parameter to the MSS_SPI_configure_master_mode(), 357 MSS_SPI_set_slave_select() and MSS_SPI_clear_slave_select () functions. 358 */ 359 typedef enum __mss_spi_slave_t 360 { 361 MSS_SPI_SLAVE_0 = 0, 362 MSS_SPI_SLAVE_1 = 1, 363 MSS_SPI_SLAVE_2 = 2, 364 MSS_SPI_SLAVE_3 = 3, 365 MSS_SPI_SLAVE_4 = 4, 366 MSS_SPI_SLAVE_5 = 5, 367 MSS_SPI_SLAVE_6 = 6, 368 MSS_SPI_SLAVE_7 = 7, 369 MSS_SPI_MAX_NB_OF_SLAVES = 8 370 } mss_spi_slave_t; 371 372 /***************************************************************************//** 373 MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE 374 ================================= 375 This constant defines a frame size of 8 bits when configuring an MSS SPI to 376 perform block transfer data transactions. 377 It must be used as the value for the frame_bit_length parameter of function 378 MSS_SPI_configure_master_mode() when performing block transfers between the 379 MSS SPI master and the target SPI slave. 380 It must also be used as the value for the frame_bit_length parameter of 381 MSS_SPI_configure_slave_mode() when performing block transfers between the 382 MSS SPI slave and the remote SPI master. 383 */ 384 #define MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE 8u 385 386 /***************************************************************************//** 387 The mss_spi_slave_cfg_t holds the MSS SPI configuration that must be used to 388 communicate with a specific SPI slave. 389 */ 390 typedef struct __mss_spi_slave_cfg_t 391 { 392 uint32_t ctrl_reg; 393 uint8_t txrxdf_size_reg; 394 uint8_t clk_gen; 395 } mss_spi_slave_cfg_t; 396 397 /***************************************************************************//** 398 This enumeration is used to indicate the current slave mode transfer type so 399 that we are not relying on buffer comparisons to dictate the logic of the driver. 400 */ 401 typedef enum __mss_spi_sxfer_mode_t 402 { 403 MSS_SPI_SLAVE_XFER_NONE = 0, /* Not configured yet */ 404 MSS_SPI_SLAVE_XFER_BLOCK = 1, /* Block transfers, with SSEND delimiting end 405 of block */ 406 MSS_SPI_SLAVE_XFER_FRAME = 2 /* Single frame transfers */ 407 } mss_spi_sxfer_mode_t; 408 409 /***************************************************************************//** 410 There is one instance of this structure for each of the microprocessor 411 subsystem's SPIs. Instances of this structure are used to identify a specific 412 SPI. A pointer to an instance of the mss_spi_instance_t structure is passed as 413 the first parameter to MSS SPI driver functions to identify which SPI should 414 perform the requested operation. 415 */ 416 typedef struct __mss_spi_instance_t 417 { 418 /* SPI hardware identification definitions . */ 419 SPI_TypeDef * hw_reg; /*!< Pointer to SPI registers. */ 420 uint8_t irqn; /*!< SPI's PLIC interrupt number. */ 421 422 /* Internal transmit state: */ 423 const uint8_t * slave_tx_buffer; /*!< Pointer to slave transmit buffer. */ 424 uint32_t slave_tx_size; /*!< Size of slave transmit buffer. */ 425 uint32_t slave_tx_idx; /*!< Current index into slave transmit buffer. */ 426 427 /* Slave command response buffer: */ 428 const uint8_t * resp_tx_buffer; 429 uint32_t resp_buff_size; 430 uint32_t resp_buff_tx_idx; 431 mss_spi_block_rx_handler_t cmd_handler; 432 uint32_t cmd_done; /*!< Flag which indicates response has been set up and 433 it is safe to pad with 0s once the response is sent. */ 434 435 /* Internal receive state: */ 436 uint8_t * slave_rx_buffer; /*!< Pointer to buffer where data received by a slave will be stored. */ 437 uint32_t slave_rx_size; /*!< Slave receive buffer siSze. */ 438 uint32_t slave_rx_idx; /*!< Current index into slave receive buffer. */ 439 440 /* Configuration for each target slave. */ 441 mss_spi_slave_cfg_t slaves_cfg[MSS_SPI_MAX_NB_OF_SLAVES]; 442 443 /* Slave received frame handler: */ 444 mss_spi_frame_rx_handler_t frame_rx_handler; /*!< Pointer to function that will be called when a frame is received when the SPI block is configured as slave. */ 445 446 uint32_t slave_tx_frame; /*!< Value of the data frame that will be transmitted when the SPI block is configured as slave. */ 447 448 /* Slave block rx handler: */ 449 mss_spi_block_rx_handler_t block_rx_handler; /*!< Pointer to the function that will be called when a data block has been received. */ 450 451 /* How we are expecting to deal with slave transfers */ 452 mss_spi_sxfer_mode_t slave_xfer_mode; /*!< Current slave mode transfer configuration. */ 453 454 /* MSS SPI reset handler*/ 455 mss_spi_oveflow_handler_t buffer_overflow_handler; 456 457 } mss_spi_instance_t; 458 459 460 /***************************************************************************//** 461 This instance of mss_spi_instance_t holds all data related to the operations 462 performed by the MSS SPI. The function MSS_SPI_init() initializes this structure. 463 A pointer to g_mss_spi0_lo is passed as the first parameter to MSS SPI driver 464 functions to indicate that SPI0 should perform the requested operation. 465 */ 466 467 extern mss_spi_instance_t g_mss_spi0_lo; 468 extern mss_spi_instance_t g_mss_spi1_lo; 469 470 extern mss_spi_instance_t g_mss_spi0_hi; 471 extern mss_spi_instance_t g_mss_spi1_hi; 472 /***************************************************************************//** 473 The MSS_SPI_init() function initializes and hardware and data structures of 474 one of the MSS SPIs. The MSS_SPI_init() function must be called before any 475 other MSS SPI driver functions can be called. 476 477 @param this_spi 478 The this_spi parameter is a pointer to an mss_spi_instance_t structure 479 identifying the MSS SPI hardware block to be initialized. There are two such 480 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 481 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 482 or g_mss_spi1 global data structure defined within the SPI driver. 483 484 Example: 485 @code 486 MSS_SPI_init(&g_mss_spi0); 487 @endcode 488 */ 489 void MSS_SPI_init 490 ( 491 mss_spi_instance_t * this_spi 492 ); 493 494 /***************************************************************************//** 495 The MSS_SPI_configure_slave_mode() function configure a MSS SPI block for 496 operations as a slave SPI device. It configures the SPI hardware with the 497 selected SPI protocol mode and frame size for communication with a specific 498 SPI master. 499 500 @param this_spi 501 The this_spi parameter is a pointer to an mss_spi_instance_t structure 502 identifying the MSS SPI hardware block to be configured. There are two such 503 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 504 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 505 or g_mss_spi1 global data structure defined within the SPI driver. 506 507 @param protocol_mode 508 This parameter is used to specify the SPI operating mode. Allowed values are: 509 - MSS_SPI_MODE0 510 - MSS_SPI_MODE1 511 - MSS_SPI_MODE2 512 - MSS_SPI_MODE3 513 - MSS_TI_MODE 514 - MSS_NSC_MODE 515 516 @param frame_bit_length 517 Number of bits making up the frame. You must use the 518 MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE constant as the value for frame_bit_length 519 when configuring the MSS SPI master for block transfer transactions with the 520 target SPI slave. 521 522 @param recieve_buffer_overflow_handler 523 The recieve_buffer_overflow_handler parameter is a pointer to the callback 524 function which is called when rx overflow occurs. The 525 MSS_SPI_configure_master_mode() function registers user implemented receive 526 buffer overflow handler to the mss_spi_instance_t structure. This registered 527 handler is used by driver to recover from buffer overflow situation. 528 Note: There is no restriction in naming the buffer overflow handler, 529 User can name as per wish. 530 531 532 Example: 533 @code 534 MSS_SPI_init(&g_mss_spi0); 535 MSS_SPI_configure_slave_mode 536 ( 537 &g_mss_spi0, 538 MSS_SPI_MODE2, 539 MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE, 540 mss_spi_overflow_handler 541 ); 542 @endcode 543 544 */ 545 void MSS_SPI_configure_slave_mode 546 ( 547 mss_spi_instance_t * this_spi, 548 mss_spi_protocol_mode_t protocol_mode, 549 uint8_t frame_bit_length, 550 mss_spi_oveflow_handler_t recieve_buffer_overflow_handler 551 ); 552 553 /***************************************************************************//** 554 The MSS_SPI_configure_master_mode() function configures the protocol mode, 555 serial clock speed and frame size for a specific target SPI slave device. It 556 is used when the MSS SPI hardware block is used as a SPI master. This function 557 must be called once for each target SPI slave which the MSS SPI master is 558 wishes to communicate with. The SPI master hardware will be configured with 559 the configuration specified by this function during calls to 560 MSS_SPI_set_slave_select(). 561 562 @param this_spi 563 The this_spi parameter is a pointer to an mss_spi_instance_t structure 564 identifying the MSS SPI hardware block to be configured. There are two such 565 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 566 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 567 or g_mss_spi1 global data structure defined within the SPI driver. 568 569 @param slave 570 The slave parameter is used to identify a target SPI slave. The driver will 571 hold the MSS SPI master configuration required to communicate with this 572 slave, as specified by the other function parameters. Allowed values are: 573 * MSS_SPI_SLAVE_0 574 * MSS_SPI_SLAVE_1 575 * MSS_SPI_SLAVE_2 576 * MSS_SPI_SLAVE_3 577 * MSS_SPI_SLAVE_4 578 * MSS_SPI_SLAVE_5 579 * MSS_SPI_SLAVE_6 580 * MSS_SPI_SLAVE_7 581 582 @param protocol_mode 583 This parameter is used to specify the SPI operating mode. Allowed values are: 584 * MSS_SPI_MODE0 585 * MSS_SPI_MODE1 586 * MSS_SPI_MODE2 587 * MSS_SPI_MODE3 588 * MSS_SPI_TI_MODE 589 * MSS_SPI_NSC_MODE 590 591 @param clk_div 592 SPI clock divider value used to generate serial interface clock signal from 593 PCLK. Allowed values are even numbers in the range from 2 to 512. The PCLK 594 frequency is divided by the specified value to give the serial interface 595 clock frequency. 596 597 @param frame_bit_length 598 Number of bits making up the frame. The maximum frame length is 32 bits. You 599 must use the MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE constant as the value for 600 frame_bit_length when configuring the MSS SPI master for block transfer 601 transactions with the target SPI slave. 602 603 @param recieve_buffer_overflow_handler 604 The recieve_buffer_overflow_handler parameter is a pointer to the callback 605 function receive buffer overflow handler. User must implement a local 606 function to handle buffer overflow. The MSS_SPI_configure_master_mode() 607 function registers user implemented receive buffer overflow handler to 608 the mss_spi_instance_t structure. This registered handler is used by driver 609 to prevent in state of buffer overflow. 610 611 Note: There is no limitation in naming the buffer overflow handler, User 612 can name as per wish . 613 614 Example: 615 @code 616 MSS_SPI_init(&g_mss_spi0); 617 618 MSS_SPI_configure_master_mode 619 ( 620 &g_mss_spi0, 621 MSS_SPI_SLAVE_0, 622 MSS_SPI_MODE2, 623 64u, 624 12, 625 mss_spi_overflow_handler 626 ); 627 628 MSS_SPI_configure_master_mode 629 ( 630 &g_mss_spi0, 631 MSS_SPI_SLAVE_1, 632 MSS_SPI_TI_MODE, 633 128u, 634 MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE, 635 mss_spi_overflow_handler 636 ); 637 638 MSS_SPI_set_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_0); 639 MSS_SPI_transfer_frame(&g_mss_spi0, 0xaaa); 640 MSS_SPI_clear_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_0); 641 642 MSS_SPI_set_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_1); 643 MSS_SPI_transfer_frame(&g_mss_spi0, 0x55); 644 MSS_SPI_clear_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_1); 645 @endcode 646 */ 647 void MSS_SPI_configure_master_mode 648 ( 649 mss_spi_instance_t * this_spi, 650 mss_spi_slave_t slave, 651 mss_spi_protocol_mode_t protocol_mode, 652 uint32_t clk_div, 653 uint8_t frame_bit_length, 654 mss_spi_oveflow_handler_t recieve_buffer_overflow_handler 655 ); 656 /*============================================================================== 657 * Master functions 658 *============================================================================*/ 659 660 /***************************************************************************//** 661 The MSS_SPI_set_slave_select() function is used by a MSS SPI master to select 662 a specific slave. This function causes the relevant slave select signal to be 663 asserted while data is clocked out onto the SPI data line. This function also 664 configures the MSS SPI master with the configuration settings necessary for 665 communication with the specified slave. These configuration settings must be 666 specified in a previous call to the MSS_SPI_configure_master_mode() function. 667 668 @param this_spi 669 The this_spi parameter is a pointer to an mss_spi_instance_t structure 670 identifying the MSS SPI hardware block to operate on. There are two such 671 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 672 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 673 or g_mss_spi1 global data structure defined within the SPI driver. 674 675 @param slave 676 The slave parameter is one of the mss_spi_slave_t enumerated constants 677 identifying the slave. 678 679 Example: 680 @code 681 const uint8_t frame_size = 25; 682 const uint32_t master_tx_frame = 0x0100A0E1; 683 684 MSS_SPI_init(&g_mss_spi0); 685 MSS_SPI_configure_master_mode 686 ( 687 &g_mss_spi0, 688 MSS_SPI_SLAVE_0, 689 MSS_SPI_MODE1, 690 256u, 691 frame_size, 692 mss_spi_overflow_handler 693 ); 694 695 MSS_SPI_set_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_0); 696 MSS_SPI_transfer_frame(&g_mss_spi0, master_tx_frame); 697 MSS_SPI_clear_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_0); 698 @endcode 699 */ 700 void MSS_SPI_set_slave_select 701 ( 702 mss_spi_instance_t * this_spi, 703 mss_spi_slave_t slave 704 ); 705 706 /***************************************************************************//** 707 The MSS_SPI_clear_slave_select() function is used by a MSS SPI Master to 708 deselect a specific slave. This function causes the relevant slave select 709 signal to be de-asserted. 710 711 @param this_spi 712 The this_spi parameter is a pointer to an mss_spi_instance_t structure 713 identifying the MSS SPI hardware block to operate on. There are two such 714 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 715 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 716 or g_mss_spi1 global data structure defined within the SPI driver. 717 718 @param slave 719 The slave parameter is one of mss_spi_slave_t enumerated constants 720 identifying a slave. 721 722 Example: 723 @code 724 const uint8_t frame_size = 25; 725 const uint32_t master_tx_frame = 0x0100A0E1; 726 727 MSS_SPI_init(&g_mss_spi0); 728 MSS_SPI_configure_master_mode 729 ( 730 &g_mss_spi0, 731 MSS_SPI_SLAVE_0, 732 MSS_SPI_MODE1, 733 256u, 734 frame_size, 735 mss_spi_overflow_handler 736 ); 737 MSS_SPI_set_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_0); 738 MSS_SPI_transfer_frame(&g_mss_spi0, master_tx_frame); 739 MSS_SPI_clear_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_0); 740 @endcode 741 */ 742 void MSS_SPI_clear_slave_select 743 ( 744 mss_spi_instance_t * this_spi, 745 mss_spi_slave_t slave 746 ); 747 748 /***************************************************************************//** 749 The MSS_SPI_disable() function is used to temporarily disable a MSS SPI 750 hardware block. 751 752 @param this_spi 753 The this_spi parameter is a pointer to an mss_spi_instance_t structure 754 identifying the MSS SPI hardware block to operate on. There are two such 755 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 756 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 757 or g_mss_spi1 global data structure defined within the SPI driver. 758 759 Example: 760 @code 761 uint32_t transfer_size; 762 uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 763 764 transfer_size = sizeof(tx_buffer); 765 766 MSS_SPI_disable(&g_mss_spi0); 767 MSS_SPI_set_transfer_byte_count(&g_mss_spi0, transfer_size); 768 769 @endcode 770 */ 771 void MSS_SPI_disable 772 ( 773 mss_spi_instance_t * this_spi 774 ); 775 776 /***************************************************************************//** 777 The MSS_SPI_enable() function is used to re-enable a MSS SPI hardware block 778 after it was disabled using the SPI_disable() function. 779 780 @param this_spi 781 The this_spi parameter is a pointer to an mss_spi_instance_t structure 782 identifying the MSS SPI hardware block to operate on. There are two such 783 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 784 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 785 or g_mss_spi1 global data structure defined within the SPI driver. 786 787 Example: 788 @code 789 uint32_t transfer_size; 790 uint8_t tx_buffer[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 791 792 transfer_size = sizeof(tx_buffer); 793 794 MSS_SPI_disable(&g_mss_spi0); 795 MSS_SPI_set_transfer_byte_count(&g_mss_spi0, transfer_size); 796 797 MSS_SPI_enable(&g_mss_spi0); 798 799 @endcode 800 */ 801 void MSS_SPI_enable 802 ( 803 mss_spi_instance_t * this_spi 804 ); 805 806 /***************************************************************************//** 807 The MSS_SPI_transfer_frame() function is used by a MSS SPI master to transmit 808 and receive a frame up to 32 bits long. This function is typically used for 809 transactions with a SPI slave where the number of transmit and receive bits is 810 not divisible by 8. 811 812 Note: The maximum frame size in NSC Microwire mode is 24 bits organized as an 813 8 bit command followed by up to 16 bits of data . 814 @param this_spi 815 The this_spi parameter is a pointer to an mss_spi_instance_t structure 816 identifying the MSS SPI hardware block to operate on. There are two such 817 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 818 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 819 or g_mss_spi1 global data structure defined within the SPI driver. 820 821 822 @param tx_bits 823 The tx_bits parameter is a 32 bits word containing the data that will be 824 transmitted. 825 Note: The bit length of the value to be transmitted to the slave must be 826 specified as the frame_bit_length parameter in a previous call to 827 the MSS_SPI_configure_master_mode() function. 828 829 @return 830 This function returns a 32 bits word containing the value that is received 831 from the slave. 832 833 Example: 834 @code 835 const uint8_t frame_size = 25; 836 const uint32_t master_tx_frame = 0x0100A0E1; 837 uint32_t master_rx; 838 839 MSS_SPI_init(&g_mss_spi0); 840 MSS_SPI_configure_master_mode 841 ( 842 &g_mss_spi0, 843 MSS_SPI_SLAVE_0, 844 MSS_SPI_MODE1, 845 256u, 846 frame_size, 847 mss_spi_overflow_handler 848 ); 849 850 MSS_SPI_set_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_0); 851 master_rx = MSS_SPI_transfer_frame(&g_mss_spi0, master_tx_frame); 852 MSS_SPI_clear_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_0); 853 @endcode 854 */ 855 uint32_t MSS_SPI_transfer_frame 856 ( 857 mss_spi_instance_t * this_spi, 858 uint32_t tx_bits 859 ); 860 861 /***************************************************************************//** 862 The MSS_SPI_transfer_block() function is used by MSS SPI masters to transmit 863 and receive blocks of data organized as a specified number of bytes. It can 864 be used for: 865 • Writing a data block to a slave 866 • Reading a data block from a slave 867 • Sending a command to a slave followed by reading the response to the 868 command in a single SPI transaction. 869 870 @param this_spi 871 The this_spi parameter is a pointer to an mss_spi_instance_t structure 872 identifying the MSS SPI hardware block to operate on. There are two such 873 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 874 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 875 or g_mss_spi1 global data structure defined within the SPI driver. 876 877 @param cmd_buffer 878 The cmd_buffer parameter is a pointer to the buffer containing the data that 879 will be sent by the master from the beginning of the transfer. 880 881 @param cmd_byte_size 882 The cmd_byte_size parameter specifies the number of bytes contained in 883 cmd_buffer that will be sent. A value of 0 indicates that no data needs to 884 be sent to the slave. 885 886 @param rd_buffer 887 The rd_buffer parameter is a pointer to the buffer where the data received 888 from the slave after the command has been sent will be stored. 889 890 @param rd_byte_size 891 The rd_byte_size parameter specifies the number of bytes to be received from 892 the slave and stored in the rd_buffer. A value of 0 indicates that no data 893 is to be read from the slave. 894 895 Polled write transfer example: 896 @code 897 uint8_t master_tx_buffer[MASTER_TX_BUFFER] = 898 { 899 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A 900 }; 901 MSS_SPI_init(&g_mss_spi0); 902 MSS_SPI_configure_master_mode 903 ( 904 &g_mss_spi0, 905 MSS_SPI_SLAVE_0, 906 MSS_SPI_MODE1, 907 256u, 908 MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE, 909 mss_spi_overflow_handler 910 ); 911 912 MSS_SPI_set_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_0); 913 MSS_SPI_transfer_block 914 ( 915 &g_mss_spi0, 916 master_tx_buffer, 917 sizeof(master_tx_buffer), 918 0, 919 0 920 ); 921 MSS_SPI_clear_slave_select(&g_mss_spi0, MSS_SPI_SLAVE_0); 922 @endcode 923 */ 924 void MSS_SPI_transfer_block 925 ( 926 mss_spi_instance_t * this_spi, 927 const uint8_t cmd_buffer[], 928 uint32_t cmd_byte_size, 929 uint8_t rd_buffer[], 930 uint32_t rd_byte_size 931 ); 932 933 /*============================================================================== 934 * Slave functions 935 *============================================================================*/ 936 937 /***************************************************************************//** 938 The MSS_SPI_set_frame_rx_handler() function is used by MSS SPI slaves to 939 specify the receive handler function that will be called by the MSS SPI driver 940 interrupt handler when a a frame of data is received by the MSS SPI slave. 941 942 @param this_spi 943 The this_spi parameter is a pointer to an mss_spi_instance_t structure 944 identifying the MSS SPI hardware block to operate on. There are two such 945 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 946 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 947 or g_mss_spi1 global data structure defined within the SPI driver. 948 949 @param rx_handler 950 The rx_handler parameter is a pointer to the frame receive handler that must 951 be called when a frame is received by the MSS SPI slave. 952 953 Example: 954 @code 955 uint32_t g_slave_rx_frame = 0; 956 957 void slave_frame_handler(uint32_t rx_frame) 958 { 959 g_slave_rx_frame = rx_frame; 960 } 961 962 int setup_slave(void) 963 { 964 const uint16_t frame_size = 25; 965 MSS_SPI_init(&g_mss_spi1); 966 MSS_SPI_configure_slave_mode 967 ( 968 &g_mss_spi0, 969 MSS_SPI_MODE2, 970 frame_size, 971 mss_spi_overflow_handler 972 ); 973 MSS_SPI_set_frame_rx_handler(&g_mss_spi1, slave_frame_handler); 974 } 975 @endcode 976 */ 977 void MSS_SPI_set_frame_rx_handler 978 ( 979 mss_spi_instance_t * this_spi, 980 mss_spi_frame_rx_handler_t rx_handler 981 ); 982 983 /***************************************************************************//** 984 The MSS_SPI_set_slave_tx_frame() function is used by MSS SPI slaves to specify 985 the frame that will be transmitted when a transaction is initiated by the SPI 986 master. 987 988 @param this_spi 989 The this_spi parameter is a pointer to an mss_spi_instance_t structure 990 identifying the MSS SPI hardware block to operate on. There are two such 991 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 992 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 993 or g_mss_spi1 global data structure defined within the SPI driver. 994 995 996 @param frame_value 997 The frame_value parameter contains the value of the frame to be sent to the 998 master. 999 Note: The bit length of the value to be transmitted to the master must be 1000 specified as the frame_bit_length parameter in a previous call to 1001 the MSS_SPI_configure_slave_mode() function. 1002 1003 Example: 1004 @code 1005 const uint16_t frame_size = 25; 1006 const uint32_t slave_tx_frame = 0x0110F761; 1007 uint32_t master_rx; 1008 1009 MSS_SPI_init(&g_mss_spi1); 1010 MSS_SPI_configure_slave_mode 1011 ( 1012 &g_mss_spi0, 1013 MSS_SPI_MODE2, 1014 frame_size, 1015 mss_spi_overflow_handler 1016 ); 1017 MSS_SPI_set_slave_tx_frame(&g_mss_spi1, slave_tx_frame); 1018 @endcode 1019 */ 1020 void MSS_SPI_set_slave_tx_frame 1021 ( 1022 mss_spi_instance_t * this_spi, 1023 uint32_t frame_value 1024 ); 1025 1026 /***************************************************************************//** 1027 The MSS_SPI_set_slave_block_buffers() function is used to configure an MSS 1028 SPI slave for block transfer operations. It specifies one or more of the 1029 following: 1030 - The data that will be transmitted when accessed by a master. 1031 - The buffer where data received from a master will be stored. 1032 - The handler function that must be called after the receive buffer has been 1033 filled. 1034 - The maximum number of bytes that the slave will accept from the master 1035 (excess bytes are discarded). 1036 These parameters allow the following use cases: 1037 - Slave performing an action after receiving a block of data from a master 1038 containing a command. The action will be performed by the receive handler 1039 based on the content of the receive data buffer. 1040 - Slave returning a block of data to the master. The type of information is 1041 always the same but the actual values change over time. For example, 1042 returning the voltage of a predefined set of analog inputs. 1043 - Slave returning data based on a command contained in the first part of the 1044 SPI transaction. For example, reading the voltage of the analog input 1045 specified by the first data byte by the master. This is achieved by using 1046 the MSS_SPI_set_slave_block_buffers() function in conjunction with 1047 functions MSS_SPI_set_cmd_handler() and MSS_SPI_set_cmd_response(). Please 1048 refer to the MSS_SPI_set_cmd_handler() function description for details of 1049 this use case. 1050 1051 @param this_spi 1052 The this_spi parameter is a pointer to an mss_spi_instance_t structure 1053 identifying the MSS SPI hardware block to operate on. There are two such 1054 data structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and 1055 MSS SPI 1 respectively. This parameter must point to either the g_mss_spi0 1056 or g_mss_spi1 global data structure defined within the SPI driver. 1057 1058 @param tx_buffer 1059 The tx_buffer parameter is a pointer to a buffer containing the data that 1060 will be sent to the master. This parameter can be set to 0 if the MSS SPI 1061 slave is not intended to be the target of SPI read. 1062 1063 @param tx_buff_size 1064 The tx_buff_size parameter specifies the number of bytes that will be 1065 transmitted by the SPI slave. It is the number of bytes contained in the 1066 tx_buffer. This parameter can be set to 0 if the MSS SPI slave is not 1067 intended to be the target of SPI read transactions. 1068 1069 @param rx_buffer 1070 The rx_buffer parameter is a pointer to the buffer where data received from 1071 the master will be stored. This parameter can be set to 0 if the MSS SPI 1072 slave is not intended to be the target of SPI write or write-read 1073 transactions. 1074 1075 @param rx_buff_size 1076 The rx_buff_size parameter specifies the size of the receive buffer. It is 1077 also the number of bytes that must be received before the receive handler 1078 is called, if a receive handler is specified using the block_rx_handler 1079 parameter. This parameter can be set to 0 if the MSS SPI slave is not 1080 intended to be the target of SPI write or write-read transactions. 1081 1082 @param block_rx_handler 1083 The block_rx_handler parameter is a pointer to a function that will be 1084 called when the receive buffer has been filled. This parameter can be set to 1085 0 if the MSS SPI slave is not intended to be the target of SPI write or 1086 write-read transactions. 1087 1088 Slave performing operation based on master command: 1089 In this example the SPI slave is configured to receive 10 bytes of data or 1090 command from the SPI master and process the data received. 1091 @code 1092 uint32_t nb_of_rx_handler_calls = 0; 1093 1094 void spi1_block_rx_handler_b 1095 ( 1096 uint8_t * rx_buff, 1097 uint16_t rx_size 1098 ) 1099 { 1100 ++nb_of_rx_handler_calls; 1101 } 1102 1103 void setup_slave(void) 1104 { 1105 uint8_t slave_rx_buffer[10] = 1106 { 1107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1108 }; 1109 1110 MSS_SPI_init(&g_mss_spi1); 1111 MSS_SPI_configure_slave_mode 1112 ( 1113 &g_mss_spi0, 1114 MSS_SPI_MODE2, 1115 MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE, 1116 mss_spi_overflow_handler 1117 ); 1118 1119 MSS_SPI_set_slave_block_buffers 1120 ( 1121 &g_mss_spi1, 1122 0, 1123 0, 1124 slave_rx_buffer, 1125 sizeof(slave_rx_buffer), 1126 spi1_block_rx_handler_b 1127 ); 1128 } 1129 @endcode 1130 */ 1131 void MSS_SPI_set_slave_block_buffers 1132 ( 1133 mss_spi_instance_t * this_spi, 1134 const uint8_t * tx_buffer, 1135 uint32_t tx_buff_size, 1136 uint8_t * rx_buffer, 1137 uint32_t rx_buff_size, 1138 mss_spi_block_rx_handler_t spi_block_rx_handler 1139 ); 1140 1141 /***************************************************************************//** 1142 The MSS_SPI_set_cmd_handler() function specifies a command handler function 1143 that will be called when the number of bytes received reaches the command size 1144 specified as parameter. 1145 This function is used by SPI slaves performing block transfers. Its purpose is 1146 to allow a SPI slave to decide the data that will be returned to the master 1147 while a SPI transaction is taking place. Typically, one of more command bytes 1148 are sent by the master to request some specific data. The slave interprets the 1149 command byte(s) while one or more turn-around bytes are transmitted. The 1150 slave adjusts its transmit data buffer based on the command during the 1151 turnaround time. 1152 The diagram below provides an example of the use of this function where the 1153 SPI slave returns data bytes D0 to D6 based on the value of a command. The 1154 3 bytes long command is made up of a command opcode byte followed by an address 1155 byte followed by a size byte. The cmd_handler() function specified through an 1156 earlier call to MSS_SPI_set_cmd_handler() is called by the SPI driver once the 1157 third byte is received. The cmd_handler() function interprets the command bytes 1158 and calls MSS_SPI_set_cmd_response() to set the SPI slave's response transmit 1159 buffer with the data to be transmitted after the turnaround bytes (T0 to T3). 1160 The number of turnaround bytes must be sufficient to give enough time for the 1161 cmd_handler() to execute. The number of turnaround bytes is specified by the 1162 protocol used on top of the SPI transport layer, so both the master and slave 1163 must adhere to this. 1164 1165 t0 t1 t2 t3 t4 1166 | | | | | 1167 |------------------------------------------------------------------| 1168 | COMMAND | TURN-AROUND | DATA | 1169 |------------------------------------------------------------------| 1170 | C | A | S | T0 | T1 | T2 | T4 | D0 | D1 | D2 | D3 | D4 | D5 | D6 | 1171 |------------------------------------------------------------------| 1172 | 1173 | 1174 --> cmd_handler() called here. 1175 | 1176 | 1177 --> MSS_SPI_set_cmd_response() called here by 1178 implementation of cmd_handler() to set the data 1179 that will be transmitted by the SPI slave. 1180 1181 @param this_spi 1182 The this_spi parameter is a pointer to an mss_spi_instance_t structure 1183 identifying the MSS SPI hardware block used. There are two such data 1184 structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and MSS SPI 1185 1 respectively. This parameter must point to either the g_mss_spi0 or 1186 g_mss_spi1 global data structure defined within the SPI driver. 1187 1188 @param cmd_handler 1189 The cmd_handler parameter is a pointer to a function with prototype: 1190 void cmd_handler(uint8_t * rx_buff, uint32_t rx_size); 1191 It specifies the function that will be called when the number of bytes 1192 specified by parameter cmd_size has been received. 1193 1194 Passing in a null pointer for this disables the command handler and the 1195 associated interrupt. 1196 1197 @param cmd_size 1198 The cmd_size parameter specifies the number of bytes that must be received 1199 before the command handler function specified by cmd_handler is called. 1200 1201 The example below demonstrates how to configure SPI1 to implement the protocol 1202 given as example in the diagram above. 1203 The configure_slave() function configures SPI1. It sets the receive and transmit 1204 buffers. The transmit buffer specified through the call to 1205 MSS_SPI_set_slave_block_buffers() specifies the data that will be returned to 1206 the master in bytes between t0 and t3. These are the bytes that will be sent 1207 to the master while the master transmits the command and dummy bytes. 1208 The spi1_slave_cmd_handler() function will be called by the driver at time t1 1209 after the 3 command bytes have been received. 1210 The spi1_block_rx_handler() function will be called by the driver at time t4 1211 when the transaction completes when the slave select signal becomes de-asserted. 1212 1213 @code 1214 #define COMMAND_SIZE 3 1215 #define NB_OF_DUMMY_BYTES 4 1216 #define MAX_TRANSACTION_SIZE 16 1217 1218 uint8_t slave_tx_buffer[COMMAND_SIZE + NB_OF_DUMMY_BYTES]; 1219 uint8_t slave_rx_buffer[MAX_TRANSACTION_SIZE]; 1220 1221 void configure_slave(void) 1222 { 1223 MSS_SPI_init(&g_mss_spi1); 1224 1225 MSS_SPI_configure_slave_mode 1226 ( 1227 &g_mss_spi1, 1228 MSS_SPI_MODE1, 1229 MSS_SPI_BLOCK_TRANSFER_FRAME_SIZE, 1230 mss_spi_overflow_handler 1231 ); 1232 1233 MSS_SPI_set_slave_block_buffers 1234 ( 1235 &g_mss_spi1, 1236 slave_tx_buffer, 1237 COMMAND_SIZE + NB_OF_DUMMY_BYTES, 1238 slave_rx_buffer, 1239 sizeof(slave_rx_buffer), 1240 spi1_block_rx_handler 1241 ); 1242 1243 1244 MSS_SPI_set_cmd_handler 1245 ( 1246 &g_mss_spi1, 1247 spi1_slave_cmd_handler, 1248 COMMAND_SIZE 1249 ); 1250 } 1251 1252 void spi1_slave_cmd_handler 1253 ( 1254 uint8_t * rx_buff, 1255 uint32_t rx_size 1256 ) 1257 { 1258 uint8_t command; 1259 uint8_t address; 1260 uint8_t size; 1261 1262 uint8_t * p_response; 1263 uint32_t response_size; 1264 1265 command = rx_buff[0]; 1266 address = rx_buff[1]; 1267 size = rx_buff[2]; 1268 1269 p_response = get_response_data(command, address, size, &response_size); 1270 1271 MSS_SPI_set_cmd_response(&g_mss_spi1, p_response, response_size); 1272 } 1273 1274 void spi1_block_rx_handler 1275 ( 1276 uint8_t * rx_buff, 1277 uint32_t rx_size 1278 ) 1279 { 1280 process_rx_data(rx_buff, rx_size); 1281 } 1282 @endcode 1283 */ 1284 void MSS_SPI_set_cmd_handler 1285 ( 1286 mss_spi_instance_t * this_spi, 1287 mss_spi_block_rx_handler_t cmd_handler, 1288 uint32_t cmd_size 1289 ); 1290 1291 /***************************************************************************//** 1292 The MSS_SPI_set_cmd_response() function specifies the data that will be 1293 returned to the master, when a command has been received by the slave. This 1294 function is called as part of the MSS_SPI_set_cmd_handler(). 1295 See the description of MSS_SPI_set_cmd_handler() for more details. 1296 1297 @param this_spi 1298 The this_spi parameter is a pointer to an mss_spi_instance_t structure 1299 identifying the MSS SPI hardware block used. There are two such data 1300 structures, g_mss_spi0 and g_mss_spi1, associated with MSS SPI 0 and MSS SPI 1301 1 respectively. This parameter must point to either the g_mss_spi0 or 1302 g_mss_spi1 global data structure defined within the SPI driver. 1303 1304 @param resp_tx_buffer 1305 The resp_tx_buffer parameter is a pointer to the buffer containing the data 1306 that must be returned to the host in the data phase of a SPI command oriented 1307 transaction. 1308 1309 @param resp_buff_size 1310 The resp_buff_size parameter specifies the size of the buffer pointed to by 1311 the resp_tx_buffer parameter. 1312 */ 1313 void MSS_SPI_set_cmd_response 1314 ( 1315 mss_spi_instance_t * this_spi, 1316 const uint8_t * resp_tx_buffer, 1317 uint32_t resp_buff_size 1318 ); 1319 1320 #ifdef __cplusplus 1321 } 1322 #endif 1323 1324 #endif /* MSS_SPI_H_*/ 1325