1717
1818#include <drivers/mspi/nrfe_mspi.h>
1919
20- #define CE_PINS_MAX 9
20+ #define SUPPORTED_IO_MODES_COUNT 7
21+
22+ #define DEVICES_MAX 5
2123#define DATA_PINS_MAX 8
2224#define VIO_COUNT 11
2325
24- #define SUPPORTED_IO_MODES_COUNT 7
26+ #define MAX_FREQUENCY 64000000
27+
28+ #define CE_PIN_UNUSED UINT8_MAX
2529
2630#define HRT_IRQ_PRIORITY 2
2731#define HRT_VEVIF_IDX_WRITE 18
2832
2933#define VEVIF_IRQN (vevif ) VEVIF_IRQN_1(vevif)
3034#define VEVIF_IRQN_1 (vevif ) VPRCLIC_##vevif##_IRQn
3135
32- /* In OCTAL mode 4 bytes for address + 32 bytes for up to 32 dummy cycles*/
36+ /* In OCTAL mode 4 bytes for address + 32 bytes for up to 32 dummy cycles. */
3337#define ADDR_AND_CYCLES_MAX_SIZE 36
3438
3539static const uint8_t pin_to_vio_map [VIO_COUNT ] = {
@@ -57,18 +61,28 @@ static const hrt_xfer_bus_widths_t io_modes[SUPPORTED_IO_MODES_COUNT] = {
5761};
5862
5963static volatile uint8_t ce_vios_count ;
60- static volatile uint8_t ce_vios [CE_PINS_MAX ];
64+ static volatile uint8_t ce_vios [DEVICES_MAX ];
6165static volatile uint8_t data_vios_count ;
6266static volatile uint8_t data_vios [DATA_PINS_MAX ];
63- static volatile struct mspi_cfg nrfe_mspi_cfg ;
64- static volatile struct mspi_dev_cfg nrfe_mspi_dev_cfg ;
65- static volatile struct mspi_xfer nrfe_mspi_xfer ;
67+ static volatile nrfe_mspi_xfer_config_t nrfe_mspi_xfer_config ;
68+ static volatile nrfe_mspi_dev_config_t nrfe_mspi_devices [ DEVICES_MAX ] ;
69+
6670static volatile hrt_xfer_t xfer_params ;
6771static volatile uint8_t address_and_dummy_cycles [ADDR_AND_CYCLES_MAX_SIZE ];
6872
6973static struct ipc_ept ep ;
7074static atomic_t ipc_atomic_sem = ATOMIC_INIT (0 );
7175
76+ NRF_STATIC_INLINE void nrf_vpr_csr_vio_out_or_set (uint16_t value )
77+ {
78+ nrf_csr_set_bits (VPRCSR_NORDIC_OUT , value );
79+ }
80+
81+ NRF_STATIC_INLINE void nrf_vpr_csr_vio_out_clear_set (uint16_t value )
82+ {
83+ nrf_csr_clear_bits (VPRCSR_NORDIC_OUT , value );
84+ }
85+
7286static void adjust_tail (volatile hrt_xfer_data_t * xfer_data , uint16_t frame_width ,
7387 uint32_t data_length )
7488{
@@ -152,38 +166,39 @@ static void configure_clock(enum mspi_cpp_mode cpp_mode)
152166 nrf_vpr_csr_vio_config_set (& vio_config );
153167}
154168
155- static void xfer_execute (struct mspi_xfer_packet xfer_packet )
169+ static void xfer_execute (nrfe_mspi_xfer_packet_msg_t * xfer_packet )
156170{
157- NRFX_ASSERT ( nrfe_mspi_dev_cfg . ce_num < ce_vios_count );
158- NRFX_ASSERT ( nrfe_mspi_dev_cfg . io_mode < SUPPORTED_IO_MODES_COUNT ) ;
171+ volatile nrfe_mspi_dev_config_t * device =
172+ & nrfe_mspi_devices [ nrfe_mspi_xfer_config . device_index ] ;
159173
160174 xfer_params .counter_value = 4 ;
161- xfer_params .ce_vio = ce_vios [nrfe_mspi_dev_cfg . ce_num ];
162- xfer_params .ce_hold = nrfe_mspi_xfer .hold_ce ;
163- xfer_params .ce_polarity = nrfe_mspi_dev_cfg . ce_polarity ;
164- xfer_params .bus_widths = io_modes [nrfe_mspi_dev_cfg . io_mode ];
175+ xfer_params .ce_vio = ce_vios [device -> ce_index ];
176+ xfer_params .ce_hold = nrfe_mspi_xfer_config .hold_ce ;
177+ xfer_params .ce_polarity = device -> ce_polarity ;
178+ xfer_params .bus_widths = io_modes [device -> io_mode ];
165179
166- /* Fix position of command if command length is < BITS_IN_WORD,
180+ /* Fix position of command and address if command/address length is < BITS_IN_WORD,
167181 * so that leading zeros would not be printed instead of data bits.
168182 */
169- xfer_packet .cmd = xfer_packet .cmd
170- << (BITS_IN_WORD - nrfe_mspi_xfer .cmd_length * BITS_IN_BYTE );
183+ xfer_packet -> command =
184+ xfer_packet -> command
185+ << (BITS_IN_WORD - nrfe_mspi_xfer_config .command_length * BITS_IN_BYTE );
171186
172187 xfer_params .xfer_data [HRT_FE_COMMAND ].vio_out_set =
173188 & nrf_vpr_csr_vio_out_buffered_reversed_word_set ;
174- xfer_params .xfer_data [HRT_FE_COMMAND ].data = (uint8_t * )& xfer_packet . cmd ;
189+ xfer_params .xfer_data [HRT_FE_COMMAND ].data = (uint8_t * )& xfer_packet -> command ;
175190 xfer_params .xfer_data [HRT_FE_COMMAND ].word_count = 0 ;
176191
177192 adjust_tail (& xfer_params .xfer_data [HRT_FE_COMMAND ], xfer_params .bus_widths .command ,
178- nrfe_mspi_xfer . cmd_length * BITS_IN_BYTE );
193+ nrfe_mspi_xfer_config . command_length * BITS_IN_BYTE );
179194
180- /* Reverse address byte order so that address values are sent instead of zeros */
181- for (uint8_t i = 0 ; i < nrfe_mspi_xfer . addr_length ; i ++ ) {
195+ /* Reverse address byte order so that address values are sent instead of zeros. */
196+ for (uint8_t i = 0 ; i < nrfe_mspi_xfer_config . address_length ; i ++ ) {
182197 address_and_dummy_cycles [i ] =
183- * (((uint8_t * )& xfer_packet . address ) + nrfe_mspi_xfer . addr_length - i - 1 );
198+ * (((uint8_t * )& xfer_packet -> address ) + nrfe_mspi_xfer_config . address_length - i - 1 );
184199 }
185200
186- for (uint8_t i = nrfe_mspi_xfer . addr_length ; i < ADDR_AND_CYCLES_MAX_SIZE ; i ++ ) {
201+ for (uint8_t i = nrfe_mspi_xfer_config . address_length ; i < ADDR_AND_CYCLES_MAX_SIZE ; i ++ ) {
187202 address_and_dummy_cycles [i ] = 0 ;
188203 }
189204
@@ -193,21 +208,21 @@ static void xfer_execute(struct mspi_xfer_packet xfer_packet)
193208 xfer_params .xfer_data [HRT_FE_ADDRESS ].word_count = 0 ;
194209
195210 adjust_tail (& xfer_params .xfer_data [HRT_FE_ADDRESS ], xfer_params .bus_widths .address ,
196- nrfe_mspi_xfer . addr_length * BITS_IN_BYTE +
197- nrfe_mspi_xfer .tx_dummy * xfer_params .bus_widths .address );
211+ nrfe_mspi_xfer_config . address_length * BITS_IN_BYTE +
212+ nrfe_mspi_xfer_config .tx_dummy * xfer_params .bus_widths .address );
198213
199214 xfer_params .xfer_data [HRT_FE_DATA ].vio_out_set =
200215 & nrf_vpr_csr_vio_out_buffered_reversed_byte_set ;
201- xfer_params .xfer_data [HRT_FE_DATA ].data = xfer_packet . data_buf ;
216+ xfer_params .xfer_data [HRT_FE_DATA ].data = xfer_packet -> data ;
202217 xfer_params .xfer_data [HRT_FE_DATA ].word_count = 0 ;
203218
204219 adjust_tail (& xfer_params .xfer_data [HRT_FE_DATA ], xfer_params .bus_widths .data ,
205- xfer_packet . num_bytes * BITS_IN_BYTE );
220+ xfer_packet -> num_bytes * BITS_IN_BYTE );
206221
207222 nrf_vpr_clic_int_pending_set (NRF_VPRCLIC , VEVIF_IRQN (HRT_VEVIF_IDX_WRITE ));
208223}
209224
210- static void config_pins (nrfe_mspi_pinctrl_soc_pin_t * pins_cfg )
225+ static void config_pins (nrfe_mspi_pinctrl_soc_pin_msg_t * pins_cfg )
211226{
212227 ce_vios_count = 0 ;
213228 data_vios_count = 0 ;
@@ -249,7 +264,11 @@ static void config_pins(nrfe_mspi_pinctrl_soc_pin_t *pins_cfg)
249264 }
250265 }
251266 nrf_vpr_csr_vio_dir_set (xfer_params .tx_direction_mask );
252- nrf_vpr_csr_vio_out_set (VPRCSR_NORDIC_OUT_HIGH << pin_to_vio_map [NRFE_MSPI_CS0_PIN_NUMBER ]);
267+
268+ /* Set all devices as undefined. */
269+ for (uint8_t i = 0 ; i < DEVICES_MAX ; i ++ ) {
270+ nrfe_mspi_devices [i ].ce_index = CE_PIN_UNUSED ;
271+ }
253272}
254273
255274static void ep_bound (void * priv )
@@ -261,46 +280,68 @@ static void ep_recv(const void *data, size_t len, void *priv)
261280{
262281 (void )priv ;
263282 (void )len ;
264- nrfe_mspi_flpr_response_t response ;
283+ nrfe_mspi_flpr_response_msg_t response ;
265284 uint8_t opcode = * (uint8_t * )data ;
266285
267286 response .opcode = opcode ;
268287
269288 switch (opcode ) {
270289 case NRFE_MSPI_CONFIG_PINS : {
271- nrfe_mspi_pinctrl_soc_pin_t * pins_cfg = (nrfe_mspi_pinctrl_soc_pin_t * )data ;
290+ nrfe_mspi_pinctrl_soc_pin_msg_t * pins_cfg = (nrfe_mspi_pinctrl_soc_pin_msg_t * )data ;
272291
273292 config_pins (pins_cfg );
274293 break ;
275294 }
276- case NRFE_MSPI_CONFIG_CTRL : {
277- nrfe_mspi_cfg_t * cfg = (nrfe_mspi_cfg_t * )data ;
278-
279- nrfe_mspi_cfg = cfg -> cfg ;
280- break ;
281- }
282295 case NRFE_MSPI_CONFIG_DEV : {
283- nrfe_mspi_dev_cfg_t * cfg = (nrfe_mspi_dev_cfg_t * )data ;
296+ nrfe_mspi_dev_config_msg_t * dev_config = (nrfe_mspi_dev_config_msg_t * )data ;
297+
298+ NRFX_ASSERT (dev_config -> device_index < DEVICES_MAX );
299+ NRFX_ASSERT (dev_config -> dev_config .io_mode < SUPPORTED_IO_MODES_COUNT );
300+ NRFX_ASSERT (dev_config -> dev_config .cpp <= MSPI_CPP_MODE_3 );
301+ NRFX_ASSERT (dev_config -> dev_config .ce_index < ce_vios_count );
302+ NRFX_ASSERT (dev_config -> dev_config .ce_polarity <= MSPI_CE_ACTIVE_HIGH );
303+ NRFX_ASSERT (dev_config -> dev_config .freq <= MAX_FREQUENCY );
304+
305+ nrfe_mspi_devices [dev_config -> device_index ] = dev_config -> dev_config ;
306+
307+ /* Configure CE pin. */
308+ if (nrfe_mspi_devices [dev_config -> device_index ].ce_polarity == MSPI_CE_ACTIVE_LOW ) {
309+ nrf_vpr_csr_vio_out_or_set (
310+ BIT (ce_vios [nrfe_mspi_devices [dev_config -> device_index ].ce_index ]));
311+ } else {
312+ nrf_vpr_csr_vio_out_clear_set (
313+ BIT (ce_vios [nrfe_mspi_devices [dev_config -> device_index ].ce_index ]));
314+ }
284315
285- nrfe_mspi_dev_cfg = cfg -> cfg ;
286- configure_clock (nrfe_mspi_dev_cfg .cpp );
287316 break ;
288317 }
289318 case NRFE_MSPI_CONFIG_XFER : {
290- nrfe_mspi_xfer_t * xfer = (nrfe_mspi_xfer_t * )data ;
319+ nrfe_mspi_xfer_config_msg_t * xfer_config = (nrfe_mspi_xfer_config_msg_t * )data ;
291320
292- nrfe_mspi_xfer = xfer -> xfer ;
321+ NRFX_ASSERT (xfer_config -> xfer_config .device_index < DEVICES_MAX );
322+ /* Check if device was configured. */
323+ NRFX_ASSERT (nrfe_mspi_devices [xfer_config -> xfer_config .device_index ].ce_index <
324+ ce_vios_count );
325+ NRFX_ASSERT (xfer_config -> xfer_config .command_length <= sizeof (uint32_t ));
326+ NRFX_ASSERT (xfer_config -> xfer_config .address_length <= sizeof (uint32_t ));
327+ NRFX_ASSERT (xfer_config -> xfer_config .tx_dummy == 0 ||
328+ xfer_config -> xfer_config .command_length != 0 ||
329+ xfer_config -> xfer_config .address_length != 0 );
330+
331+ nrfe_mspi_xfer_config = xfer_config -> xfer_config ;
332+
333+ configure_clock (nrfe_mspi_devices [nrfe_mspi_xfer_config .device_index ].cpp );
293334 break ;
294335 }
295336 case NRFE_MSPI_TX :
337+ nrfe_mspi_xfer_packet_msg_t * packet = (nrfe_mspi_xfer_packet_msg_t * )data ;
338+
339+ xfer_execute (packet );
340+ break ;
296341 case NRFE_MSPI_TXRX : {
297- nrfe_mspi_xfer_packet_t * packet = (nrfe_mspi_xfer_packet_t * )data ;
342+ nrfe_mspi_xfer_packet_msg_t * packet = (nrfe_mspi_xfer_packet_msg_t * )data ;
298343
299- if (packet -> packet .dir == MSPI_RX ) {
300- /* TODO: Process received data */
301- } else if (packet -> packet .dir == MSPI_TX ) {
302- xfer_execute (packet -> packet );
303- }
344+ (void )packet ;
304345 break ;
305346 }
306347 default :
@@ -322,7 +363,7 @@ static int backend_init(void)
322363 volatile uint32_t delay = 0 ;
323364
324365#if !defined(CONFIG_SYS_CLOCK_EXISTS )
325- /* Wait a little bit for IPC service to be ready on APP side */
366+ /* Wait a little bit for IPC service to be ready on APP side. */
326367 while (delay < 1000 ) {
327368 delay ++ ;
328369 }
@@ -340,7 +381,7 @@ static int backend_init(void)
340381 return ret ;
341382 }
342383
343- /* Wait for endpoint to be bound */
384+ /* Wait for endpoint to be bound. */
344385 while (!atomic_test_and_clear_bit (& ipc_atomic_sem , NRFE_MSPI_EP_BOUNDED )) {
345386 }
346387
0 commit comments