ChibiOS 21.11.5
hal_xsnor_base.c
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006-2026 Giovanni Di Sirio.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file hal_xsnor_base.c
19 * @brief Generated SNOR Base Driver source.
20 * @note This is a generated file, do not edit directly.
21 *
22 * @addtogroup HAL_XSNOR_BASE
23 * @{
24 */
25
26#include "hal.h"
27#include "hal_xsnor_base.h"
28
29/*===========================================================================*/
30/* Module local definitions. */
31/*===========================================================================*/
32
33/*===========================================================================*/
34/* Module local macros. */
35/*===========================================================================*/
36
37/*===========================================================================*/
38/* Module exported variables. */
39/*===========================================================================*/
40
41/*===========================================================================*/
42/* Module local types. */
43/*===========================================================================*/
44
45/*===========================================================================*/
46/* Module local variables. */
47/*===========================================================================*/
48
49/*===========================================================================*/
50/* Module local functions. */
51/*===========================================================================*/
52
53/*===========================================================================*/
54/* Module exported functions. */
55/*===========================================================================*/
56
57/*===========================================================================*/
58/* Module class "hal_xsnor_base_c" methods. */
59/*===========================================================================*/
60
61/**
62 * @name Interfaces implementation of hal_xsnor_base_c
63 * @{
64 */
65/**
66 * @brief Implementation of interface method @p flsGetDescriptor().
67 *
68 * @param[in,out] ip Pointer to the @p flash_interface_i class
69 * interface.
70 * @return A flash device descriptor.
71 */
73 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
74
75 return &self->descriptor;
76}
77
78/**
79 * @brief Implementation of interface method @p flsRead().
80 *
81 * @param[in,out] ip Pointer to the @p flash_interface_i class
82 * interface.
83 * @param[in] offset Flash offset.
84 * @param[in] n Number of bytes to be read.
85 * @param[out] rp Pointer to the data buffer.
86 * @return An error code.
87 */
89 size_t n, uint8_t *rp) {
90 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
91 flash_error_t err;
92
93 osalDbgCheck((self != NULL) && (rp != NULL) && (n > 0U));
94 osalDbgAssert((self->state == FLASH_READY) || (self->state == FLASH_ERASE),
95 "invalid state");
96
97 if (self->state == FLASH_ERASE) {
98 return FLASH_BUSY_ERASING;
99 }
100
101 /* Bus acquired.*/
103
104 /* FLASH_READY state while the operation is performed.*/
105 self->state = FLASH_READ;
106
107 /* Actual read implementation.*/
108 err = xsnor_device_read(self, offset, n, rp);
109
110 /* Ready state again.*/
111 self->state = FLASH_READY;
112
113 /* Bus released.*/
115
116 return err;
117}
118
119/**
120 * @brief Implementation of interface method @p flsProgram().
121 *
122 * @param[in,out] ip Pointer to the @p flash_interface_i class
123 * interface.
124 * @param[in] offset Flash offset.
125 * @param[in] n Number of bytes to be programmed.
126 * @param[in] pp Pointer to the data buffer.
127 * @return An error code.
128 */
130 size_t n, const uint8_t *pp) {
131 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
132 flash_error_t err;
133
134 osalDbgCheck((self != NULL) && (pp != NULL) && (n > 0U));
135 osalDbgAssert((self->state == FLASH_READY) || (self->state == FLASH_ERASE),
136 "invalid state");
137
138 if (self->state == FLASH_ERASE) {
139 return FLASH_BUSY_ERASING;
140 }
141
142 /* Bus acquired.*/
144
145 /* FLASH_PGM state while the operation is performed.*/
146 self->state = FLASH_PGM;
147
148 /* Actual program implementation.*/
149 err = xsnor_device_program(self, offset, n, pp);
150
151 /* Ready state again.*/
152 self->state = FLASH_READY;
153
154 /* Bus released.*/
156
157 return err;
158}
159
160/**
161 * @brief Implementation of interface method @p flsStartEraseAll().
162 *
163 * @param[in,out] ip Pointer to the @p flash_interface_i class
164 * interface.
165 * @return An error code.
166 */
168 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
169 flash_error_t err;
170
171 osalDbgCheck(self != NULL);
172 osalDbgAssert((self->state == FLASH_READY) || (self->state == FLASH_ERASE),
173 "invalid state");
174
175 if (self->state == FLASH_ERASE) {
176 return FLASH_BUSY_ERASING;
177 }
178
179 /* Bus acquired.*/
181
182 /* FLASH_ERASE state while the operation is performed.*/
183 self->state = FLASH_ERASE;
184
185 /* Actual erase implementation.*/
187
188 /* Restore ready state on failure.*/
189 if (err != FLASH_NO_ERROR) {
190 self->state = FLASH_READY;
191 }
192
193 /* Bus released.*/
195
196 return err;
197}
198
199/**
200 * @brief Implementation of interface method @p flsStartEraseSector().
201 *
202 * @param[in,out] ip Pointer to the @p flash_interface_i class
203 * interface.
204 * @param[in] sector Sector to be erased.
205 * @return An error code.
206 */
208 flash_sector_t sector) {
209 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
210 flash_error_t err;
211
212 osalDbgCheck(self != NULL);
213 osalDbgAssert((self->state == FLASH_READY) || (self->state == FLASH_ERASE),
214 "invalid state");
215
216 if (self->state == FLASH_ERASE) {
217 return FLASH_BUSY_ERASING;
218 }
219
220 /* Bus acquired.*/
222
223 /* FLASH_ERASE state while the operation is performed.*/
224 self->state = FLASH_ERASE;
225
226 /* Actual erase implementation.*/
227 err = xsnor_device_start_erase_sector(self, sector);
228
229 /* Restore ready state on failure.*/
230 if (err != FLASH_NO_ERROR) {
231 self->state = FLASH_READY;
232 }
233
234 /* Bus released.*/
236
237 return err;
238}
239
240/**
241 * @brief Implementation of interface method @p flsQueryErase().
242 *
243 * @param[in,out] ip Pointer to the @p flash_interface_i class
244 * interface.
245 * @param[out] msec Recommended time, in milliseconds, that should
246 * be spent before calling this function again,
247 * can be @p NULL
248 * @return An error code.
249 */
250static flash_error_t __xsnor_fls_query_erase_impl(void *ip, unsigned *msec) {
251 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
252 flash_error_t err;
253
254 osalDbgCheck(self != NULL);
255 osalDbgAssert((self->state == FLASH_READY) || (self->state == FLASH_ERASE),
256 "invalid state");
257
258 /* If there is an erase in progress then the device must be checked.*/
259 if (self->state == FLASH_ERASE) {
260
261 /* Bus acquired.*/
263
264 /* Actual query erase implementation.*/
265 err = xsnor_device_query_erase(self, msec);
266
267 /* The device is ready to accept commands.*/
268 if (err == FLASH_NO_ERROR) {
269 self->state = FLASH_READY;
270 }
271
272 /* Bus released.*/
274 }
275 else {
276 err = FLASH_NO_ERROR;
277 }
278
279 return err;
280}
281
282/**
283 * @brief Implementation of interface method @p flsVerifyErase().
284 *
285 * @param[in,out] ip Pointer to the @p flash_interface_i class
286 * interface.
287 * @param[in] sector Sector to be verified.
288 * @return An error code.
289 */
291 flash_sector_t sector) {
292 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
293 flash_error_t err;
294
295 osalDbgCheck(self != NULL);
296 osalDbgAssert((self->state == FLASH_READY) || (self->state == FLASH_ERASE),
297 "invalid state");
298
299 if (self->state == FLASH_ERASE) {
300 return FLASH_BUSY_ERASING;
301 }
302
303 /* Bus acquired.*/
305
306 /* FLASH_READY state while the operation is performed.*/
307 self->state = FLASH_READ;
308
309 /* Actual verify erase implementation.*/
310 err = xsnor_device_verify_erase(self, sector);
311
312 /* Ready state again.*/
313 self->state = FLASH_READY;
314
315 /* Bus released.*/
317
318 return err;
319}
320
321/**
322 * @brief Implementation of interface method @p flsAcquireExclusive().
323 *
324 * @param[in,out] ip Pointer to the @p flash_interface_i class
325 * interface.
326 * @return An error code.
327 */
329 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
330
331 osalMutexLock(&self->mutex);
332 return FLASH_NO_ERROR;
333}
334
335/**
336 * @brief Implementation of interface method @p flsReleaseExclusive().
337 *
338 * @param[in,out] ip Pointer to the @p flash_interface_i class
339 * interface.
340 * @return An error code.
341 */
343 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
344
345 osalMutexUnlock(&self->mutex);
346 return FLASH_NO_ERROR;
347}
348/** @} */
349
350/**
351 * @name Methods implementations of hal_xsnor_base_c
352 * @{
353 */
354/**
355 * @brief Implementation of object creation.
356 * @note This function is meant to be used by derived classes.
357 *
358 * @param[out] ip Pointer to a @p hal_xsnor_base_c instance to be
359 * initialized.
360 * @param[in] vmt VMT pointer for the new object.
361 * @return A new reference to the object.
362 */
363void *__xsnor_objinit_impl(void *ip, const void *vmt) {
365
366 /* Initialization of the ancestors-defined parts.*/
367 __bo_objinit_impl(self, vmt);
368
369 /* Initialization of interface flash_interface_i.*/
370 {
371 static const struct flash_interface_vmt xsnor_fls_vmt = {
372 .instance_offset = offsetof(hal_xsnor_base_c, fls),
373 .get_descriptor = __xsnor_fls_get_descriptor_impl,
374 .read = __xsnor_fls_read_impl,
375 .program = __xsnor_fls_program_impl,
376 .start_erase_all = __xsnor_fls_start_erase_all_impl,
377 .start_erase_sector = __xsnor_fls_start_erase_sector_impl,
378 .query_erase = __xsnor_fls_query_erase_impl,
379 .verify_erase = __xsnor_fls_verify_erase_impl,
380 .acquire_exclusive = __xsnor_fls_acquire_exclusive_impl,
381 .release_exclusive = __xsnor_fls_release_exclusive_impl
382 };
383 oopIfObjectInit(&self->fls, &xsnor_fls_vmt);
384 }
385
386 /* Initialization code.*/
387 self->state = FLASH_STOP;
388 self->config = NULL;
389#if XSNOR_USE_WSPI == TRUE
390 self->commands = NULL;
391#endif
392 osalMutexObjectInit(&self->mutex);
393
394 return self;
395}
396
397/**
398 * @brief Implementation of object finalization.
399 * @note This function is meant to be used by derived classes.
400 *
401 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance to be
402 * disposed.
403 */
404void __xsnor_dispose_impl(void *ip) {
406
407 /* Finalization code.*/
408 self->state = FLASH_UNINIT;
409
410 /* Finalization of the ancestors-defined parts.*/
411 __bo_dispose_impl(self);
412}
413/** @} */
414
415/**
416 * @name Regular methods of hal_xsnor_base_c
417 * @{
418 */
419#if (XSNOR_USE_SPI == TRUE) || defined (__DOXYGEN__)
420/**
421 * @brief Sends command and address over SPI.
422 *
423 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
424 * @param[in] cmd Instruction code.
425 * @param[in] offset Flash offset.
426 */
427void __xsnor_spi_cmd_addr(void *ip, uint32_t cmd, flash_offset_t offset) {
429 const xsnor_config_t *config = self->config;
430
431 config->buffers->spibuf[0] = cmd;
432 if ((self->descriptor.attributes & FLASH_ATTR_SPI_4BYTES_ADDR_HINT) != 0U) {
433 config->buffers->spibuf[1] = (uint8_t)(offset >> 24);
434 config->buffers->spibuf[2] = (uint8_t)(offset >> 16);
435 config->buffers->spibuf[3] = (uint8_t)(offset >> 8);
436 config->buffers->spibuf[4] = (uint8_t)(offset >> 0);
437 spiSend(config->bus.spi.drv, 5, config->buffers->spibuf);
438 }
439 else {
440 config->buffers->spibuf[1] = (uint8_t)(offset >> 16);
441 config->buffers->spibuf[2] = (uint8_t)(offset >> 8);
442 config->buffers->spibuf[3] = (uint8_t)(offset >> 0);
443 spiSend(config->bus.spi.drv, 4, config->buffers->spibuf);
444 }
445}
446#endif /* XSNOR_USE_SPI == TRUE */
447
448#if (XSNOR_SHARED_BUS == TRUE) || defined (__DOXYGEN__)
449/**
450 * @brief Bus acquisition and lock.
451 *
452 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
453 */
454void __xsnor_bus_acquire(void *ip) {
456
457#if XSNOR_USE_BOTH == TRUE
458 if (self->config->bus_type != XSNOR_BUS_MODE_SPI) {
459#endif
460#if XSNOR_USE_WSPI == TRUE
461 wspiAcquireBus(self->config->bus.wspi.drv);
462 if (self->config->bus.wspi.cfg != self->config->bus.wspi.drv->config) {
463 wspiStart(self->config->bus.wspi.drv, self->config->bus.wspi.cfg);
464 }
465#endif
466#if XSNOR_USE_BOTH == TRUE
467 }
468 else {
469#endif
470#if XSNOR_USE_SPI == TRUE
471 spiAcquireBus(self->config->bus.spi.drv);
472 if (self->config->bus.spi.cfg != self->config->bus.spi.drv->config) {
473 spiStart(self->config->bus.spi.drv, self->config->bus.spi.cfg);
474 }
475#endif
476#if XSNOR_USE_BOTH == TRUE
477 }
478#endif
479}
480
481/**
482 * @brief Bus release and unlock.
483 *
484 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
485 */
486void __xsnor_bus_release(void *ip) {
488
489#if XSNOR_USE_BOTH == TRUE
490 if (self->config->bus_type != XSNOR_BUS_MODE_SPI) {
491#endif
492#if XSNOR_USE_WSPI == TRUE
493 wspiReleaseBus(self->config->bus.wspi.drv);
494#endif
495#if XSNOR_USE_BOTH == TRUE
496 }
497 else {
498#endif
499#if XSNOR_USE_SPI == TRUE
500 spiReleaseBus(self->config->bus.spi.drv);
501#endif
502#if XSNOR_USE_BOTH == TRUE
503 }
504#endif
505}
506#endif /* XSNOR_SHARED_BUS == TRUE */
507
508/**
509 * @brief Sends a naked command.
510 *
511 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
512 * @param[in] cmd Instruction code.
513 */
514void __xsnor_bus_cmd(void *ip, uint32_t cmd) {
516 const xsnor_config_t *config = self->config;
517
518#if XSNOR_USE_BOTH == TRUE
519 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
520#endif
521#if XSNOR_USE_WSPI == TRUE
522 wspi_command_t mode;
523
524 mode.cmd = cmd;
525 mode.cfg = self->commands->cmd;
526 mode.addr = 0U;
527 mode.alt = 0U;
528 mode.dummy = 0U;
529 wspiCommand(config->bus.wspi.drv, &mode);
530#endif
531#if XSNOR_USE_BOTH == TRUE
532 }
533 else {
534#endif
535#if XSNOR_USE_SPI == TRUE
536
537 spiSelect(config->bus.spi.drv);
538 config->buffers->spibuf[0] = cmd;
539 spiSend(config->bus.spi.drv, 1, config->buffers->spibuf);
540 spiUnselect(config->bus.spi.drv);
541#endif
542#if XSNOR_USE_BOTH == TRUE
543 }
544#endif
545}
546
547/**
548 * @brief Sends a command followed by a data transmit phase.
549 *
550 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
551 * @param[in] cmd Instruction code.
552 * @param[in] n Number of bytes to transmit.
553 * @param[in] p Data buffer.
554 */
555void __xsnor_bus_cmd_send(void *ip, uint32_t cmd, size_t n, const uint8_t *p) {
557 const xsnor_config_t *config = self->config;
558
559#if XSNOR_USE_BOTH == TRUE
560 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
561#endif
562#if XSNOR_USE_WSPI == TRUE
563 wspi_command_t mode;
564
565 mode.cmd = cmd;
566 mode.cfg = self->commands->cmd_data;
567 mode.addr = 0U;
568 mode.alt = 0U;
569 mode.dummy = 0U;
570 wspiSend(config->bus.wspi.drv, &mode, n, p);
571#endif
572#if XSNOR_USE_BOTH == TRUE
573 }
574 else {
575#endif
576#if XSNOR_USE_SPI == TRUE
577
578 spiSelect(config->bus.spi.drv);
579 config->buffers->spibuf[0] = cmd;
580 spiSend(config->bus.spi.drv, 1, config->buffers->spibuf);
581 spiSend(config->bus.spi.drv, n, p);
582 spiUnselect(config->bus.spi.drv);
583#endif
584#if XSNOR_USE_BOTH == TRUE
585 }
586#endif
587}
588
589/**
590 * @brief Sends a command followed by a data receive phase.
591 *
592 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
593 * @param[in] cmd Instruction code.
594 * @param[in] n Number of bytes to receive.
595 * @param[out] p Data buffer.
596 */
597void __xsnor_bus_cmd_receive(void *ip, uint32_t cmd, size_t n, uint8_t *p) {
599 const xsnor_config_t *config = self->config;
600
601#if XSNOR_USE_BOTH == TRUE
602 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
603#endif
604#if XSNOR_USE_WSPI == TRUE
605 wspi_command_t mode;
606
607 mode.cmd = cmd;
608 mode.cfg = self->commands->cmd_data;
609 mode.addr = 0U;
610 mode.alt = 0U;
611 mode.dummy = 0U;
612 wspiReceive(config->bus.wspi.drv, &mode, n, p);
613#endif
614#if XSNOR_USE_BOTH == TRUE
615 }
616 else {
617#endif
618#if XSNOR_USE_SPI == TRUE
619
620 spiSelect(config->bus.spi.drv);
621 config->buffers->spibuf[0] = cmd;
622 spiSend(config->bus.spi.drv, 1, config->buffers->spibuf);
623 spiReceive(config->bus.spi.drv, n, p);
624 spiUnselect(config->bus.spi.drv);
625#endif
626#if XSNOR_USE_BOTH == TRUE
627 }
628#endif
629}
630
631/**
632 * @brief Sends a command followed by a flash address.
633 *
634 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
635 * @param[in] cmd Instruction code.
636 * @param[in] offset Flash offset.
637 */
638void __xsnor_bus_cmd_addr(void *ip, uint32_t cmd, flash_offset_t offset) {
640 const xsnor_config_t *config = self->config;
641
642#if XSNOR_USE_BOTH == TRUE
643 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
644#endif
645#if XSNOR_USE_WSPI == TRUE
646 wspi_command_t mode;
647
648 mode.cmd = cmd;
649 mode.cfg = self->commands->cmd_addr;
650 mode.addr = offset;
651 mode.alt = 0U;
652 mode.dummy = 0U;
653 wspiCommand(config->bus.wspi.drv, &mode);
654#endif
655#if XSNOR_USE_BOTH == TRUE
656 }
657 else {
658#endif
659#if XSNOR_USE_SPI == TRUE
660
661 spiSelect(config->bus.spi.drv);
662 __xsnor_spi_cmd_addr(self, cmd, offset);
663 spiUnselect(config->bus.spi.drv);
664#endif
665#if XSNOR_USE_BOTH == TRUE
666 }
667#endif
668}
669
670/**
671 * @brief Sends a command followed by a flash address and a data transmit
672 * phase.
673 *
674 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
675 * @param[in] cmd Instruction code.
676 * @param[in] offset Flash offset.
677 * @param[in] n Number of bytes to transmit.
678 * @param[in] p Data buffer.
679 */
680void __xsnor_bus_cmd_addr_send(void *ip, uint32_t cmd, flash_offset_t offset,
681 size_t n, const uint8_t *p) {
683 const xsnor_config_t *config = self->config;
684
685#if XSNOR_USE_BOTH == TRUE
686 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
687#endif
688#if XSNOR_USE_WSPI == TRUE
689 wspi_command_t mode;
690
691 mode.cmd = cmd;
692 mode.cfg = self->commands->cmd_addr_data;
693 mode.addr = offset;
694 mode.alt = 0U;
695 mode.dummy = 0U;
696 wspiSend(config->bus.wspi.drv, &mode, n, p);
697#endif
698#if XSNOR_USE_BOTH == TRUE
699 }
700 else {
701#endif
702#if XSNOR_USE_SPI == TRUE
703
704 spiSelect(config->bus.spi.drv);
705 __xsnor_spi_cmd_addr(self, cmd, offset);
706 spiSend(config->bus.spi.drv, n, p);
707 spiUnselect(config->bus.spi.drv);
708#endif
709#if XSNOR_USE_BOTH == TRUE
710 }
711#endif
712}
713
714/**
715 * @brief Sends a command followed by a flash address and a data receive
716 * phase.
717 *
718 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
719 * @param[in] cmd Instruction code.
720 * @param[in] offset Flash offset.
721 * @param[in] n Number of bytes to receive.
722 * @param[in] p Data buffer.
723 */
724void __xsnor_bus_cmd_addr_receive(void *ip, uint32_t cmd,
725 flash_offset_t offset, size_t n, uint8_t *p) {
727 const xsnor_config_t *config = self->config;
728
729#if XSNOR_USE_BOTH == TRUE
730 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
731#endif
732#if XSNOR_USE_WSPI == TRUE
733 wspi_command_t mode;
734
735 mode.cmd = cmd;
736 mode.cfg = self->commands->cmd_addr_data;
737 mode.addr = offset;
738 mode.alt = 0U;
739 mode.dummy = 0U;
740 wspiReceive(config->bus.wspi.drv, &mode, n, p);
741#endif
742#if XSNOR_USE_BOTH == TRUE
743 }
744 else {
745#endif
746#if XSNOR_USE_SPI == TRUE
747
748 spiSelect(config->bus.spi.drv);
749 __xsnor_spi_cmd_addr(self, cmd, offset);
750 spiReceive(config->bus.spi.drv, n, p);
751 spiUnselect(config->bus.spi.drv);
752#endif
753#if XSNOR_USE_BOTH == TRUE
754 }
755#endif
756}
757
758/**
759 * @brief Sends a command followed by dummy cycles and a data receive
760 * phase.
761 *
762 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
763 * @param[in] cmd Instruction code.
764 * @param[in] dummy Number of dummy cycles.
765 * @param[in] n Number of bytes to receive.
766 * @param[out] p Data buffer.
767 */
768void __xsnor_bus_cmd_dummy_receive(void *ip, uint32_t cmd, uint32_t dummy,
769 size_t n, uint8_t *p) {
771 const xsnor_config_t *config = self->config;
772
773#if XSNOR_USE_BOTH == TRUE
774 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
775#endif
776#if XSNOR_USE_WSPI == TRUE
777 wspi_command_t mode;
778
779 mode.cmd = cmd;
780 mode.cfg = self->commands->cmd_data;
781 mode.addr = 0U;
782 mode.alt = 0U;
783 mode.dummy = dummy;
784 wspiReceive(config->bus.wspi.drv, &mode, n, p);
785#endif
786#if XSNOR_USE_BOTH == TRUE
787 }
788 else {
789#endif
790#if XSNOR_USE_SPI == TRUE
791 osalDbgAssert((dummy & 7) == 0U, "multiple of 8 dummy cycles");
792
793 spiSelect(config->bus.spi.drv);
794 config->buffers->spibuf[0] = cmd;
795 spiSend(config->bus.spi.drv, 1, config->buffers->spibuf);
796 if (dummy != 0U) {
797 spiIgnore(config->bus.spi.drv, dummy / 8U);
798 }
799 spiReceive(config->bus.spi.drv, n, p);
800 spiUnselect(config->bus.spi.drv);
801#endif
802#if XSNOR_USE_BOTH == TRUE
803 }
804#endif
805}
806
807/**
808 * @brief Sends a complete header followed by a data receive phase.
809 *
810 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
811 * @param[in] cmd Instruction code.
812 * @param[in] offset Flash offset.
813 * @param[in] dummy Number of dummy cycles.
814 * @param[in] n Number of bytes to receive.
815 * @param[out] p Data buffer.
816 */
817void __xsnor_bus_cmd_addr_dummy_receive(void *ip, uint32_t cmd,
818 flash_offset_t offset, uint32_t dummy,
819 size_t n, uint8_t *p) {
821 const xsnor_config_t *config = self->config;
822
823#if XSNOR_USE_BOTH == TRUE
824 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
825#endif
826#if XSNOR_USE_WSPI == TRUE
827 wspi_command_t mode;
828
829 mode.cmd = cmd;
830 mode.cfg = self->commands->cmd_addr_data;
831 mode.addr = offset;
832 mode.alt = 0U;
833 mode.dummy = dummy;
834 wspiReceive(config->bus.wspi.drv, &mode, n, p);
835#endif
836#if XSNOR_USE_BOTH == TRUE
837 }
838 else {
839#endif
840#if XSNOR_USE_SPI == TRUE
841 osalDbgAssert((dummy & 7) == 0U, "multiple of 8 dummy cycles");
842
843 spiSelect(config->bus.spi.drv);
844 __xsnor_spi_cmd_addr(self, cmd, offset);
845 if (dummy != 0U) {
846 spiIgnore(config->bus.spi.drv, dummy / 8U);
847 }
848 spiReceive(config->bus.spi.drv, n, p);
849 spiUnselect(config->bus.spi.drv);
850#endif
851#if XSNOR_USE_BOTH == TRUE
852 }
853#endif
854}
855
856/**
857 * @brief Configures and activates a SNOR driver.
858 *
859 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
860 * @param[in] config Pointer to the configuration.
861 * @return An error code.
862 * @retval FLASH_NO_ERROR Operation successful.
863 * @retval FLASH_ERROR_HW_FAILURE If initialization failed.
864 *
865 * @api
866 */
867flash_error_t xsnorStart(void *ip, const xsnor_config_t *config) {
870
871 osalDbgCheck((self != NULL) && (config != NULL));
872 osalDbgAssert(self->state != FLASH_UNINIT, "invalid state");
873
874 self->config = config;
875
876 if (self->state == FLASH_STOP) {
877
878 /* Bus acquisition.*/
880
881#if XSNOR_USE_BOTH == TRUE
882 if (self->config->bus_type != XSNOR_BUS_MODE_SPI) {
883#endif
884#if XSNOR_USE_WSPI == TRUE
885 wspiStart(self->config->bus.wspi.drv, self->config->bus.wspi.cfg);
886#endif
887#if XSNOR_USE_BOTH == TRUE
888 }
889 else {
890#endif
891#if XSNOR_USE_SPI == TRUE
892 spiStart(self->config->bus.spi.drv, self->config->bus.spi.cfg);
893#endif
894#if XSNOR_USE_BOTH == TRUE
895 }
896#endif
897
898 /* Device identification and initialization.*/
899 err = xsnor_device_init(self);
900 if (err == FLASH_NO_ERROR) {
901 /* Driver in ready state.*/
902 self->state = FLASH_READY;
903 }
904
905 /* Bus release.*/
907 }
908
909 return err;
910}
911
912/**
913 * @brief Deactivates a SNOR driver.
914 *
915 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
916 *
917 * @api
918 */
919void xsnorStop(void *ip) {
921 osalDbgCheck(self != NULL);
922 osalDbgAssert(self->state != FLASH_UNINIT, "invalid state");
923
924 if (self->state != FLASH_STOP) {
925
926 /* Stopping bus device.*/
927#if XSNOR_USE_BOTH == TRUE
928 if (self->config->bus_type != XSNOR_BUS_MODE_SPI) {
929#endif
930#if XSNOR_USE_WSPI == TRUE
931 wspiStop(self->config->bus.wspi.drv);
932#endif
933#if XSNOR_USE_BOTH == TRUE
934 }
935 else {
936#endif
937#if XSNOR_USE_SPI == TRUE
938 spiStop(self->config->bus.spi.drv);
939#endif
940#if XSNOR_USE_BOTH == TRUE
941 }
942#endif
943
944 /* Driver stopped.*/
945 self->state = FLASH_STOP;
946
947 /* Deleting current configuration.*/
948 self->config = NULL;
949 }
950}
951
952#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined (__DOXYGEN__)
953/**
954 * @brief Enters the memory mapped mode.
955 *
956 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
957 * @param[out] addrp Pointer to the memory mapped memory or @p NULL
958 * @return An error code.
959 * @retval FLASH_NO_ERROR Operation successful.
960 * @retval FLASH_ERROR_HW_FAILURE If memory mapped mode failed.
961 *
962 * @api
963 */
964flash_error_t xsnorMemoryMap(void *ip, uint8_t **addrp) {
966 flash_error_t err;
967
968 /* Activating XIP mode in the device.*/
969 err = xsnor_device_mmap_on(self, addrp);
970
971 return err;
972}
973
974/**
975 * @brief Leaves the memory mapped mode.
976 *
977 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
978 *
979 * @api
980 */
981void xsnorMemoryUnmap(void *ip) {
983
985}
986#endif /* WSPI_SUPPORTS_MEMMAP == TRUE */
987/** @} */
988
989/** @} */
Base class of all SNOR drivers.
static const struct EFlashDriverVMT vmt
Definition hal_efl.c:71
uint32_t flash_sector_t
Type of a flash sector number.
Definition hal_flash.h:117
uint32_t flash_offset_t
Type of a flash offset.
Definition hal_flash.h:112
flash_error_t
Type of a flash error code.
Definition hal_flash.h:98
@ FLASH_ERASE
Definition hal_flash.h:92
@ FLASH_READ
Definition hal_flash.h:90
@ FLASH_READY
Definition hal_flash.h:89
@ FLASH_STOP
Definition hal_flash.h:88
@ FLASH_PGM
Definition hal_flash.h:91
@ FLASH_UNINIT
Definition hal_flash.h:87
@ FLASH_BUSY_ERASING
Definition hal_flash.h:100
@ FLASH_NO_ERROR
Definition hal_flash.h:99
#define FLASH_ATTR_SPI_4BYTES_ADDR_HINT
Hint to use 4 bytes addresses in SPI protocol.
static flash_error_t __xsnor_fls_verify_erase_impl(void *ip, flash_sector_t sector)
Implementation of interface method flsVerifyErase().
void __xsnor_dispose_impl(void *ip)
Implementation of object finalization.
static flash_error_t __xsnor_fls_start_erase_all_impl(void *ip)
Implementation of interface method flsStartEraseAll().
static flash_error_t __xsnor_fls_query_erase_impl(void *ip, unsigned *msec)
Implementation of interface method flsQueryErase().
void __xsnor_bus_cmd_send(void *ip, uint32_t cmd, size_t n, const uint8_t *p)
Sends a command followed by a data transmit phase.
void __xsnor_spi_cmd_addr(void *ip, uint32_t cmd, flash_offset_t offset)
Sends command and address over SPI.
#define __xsnor_bus_release(self)
static CC_FORCE_INLINE void xsnor_device_mmap_off(void *ip)
#define XSNOR_BUS_MODE_SPI
void * __xsnor_objinit_impl(void *ip, const void *vmt)
Implementation of object creation.
static CC_FORCE_INLINE flash_error_t xsnor_device_mmap_on(void *ip, uint8_t **addrp)
void __xsnor_bus_cmd_addr_send(void *ip, uint32_t cmd, flash_offset_t offset, size_t n, const uint8_t *p)
Sends a command followed by a flash address and a data transmit phase.
static CC_FORCE_INLINE flash_error_t xsnor_device_start_erase_sector(void *ip, flash_sector_t sector)
Starts a sector erase operation.
static CC_FORCE_INLINE flash_error_t xsnor_device_read(void *ip, flash_offset_t offset, size_t n, uint8_t *rp)
Read operation.
void __xsnor_bus_cmd_addr(void *ip, uint32_t cmd, flash_offset_t offset)
Sends a command followed by a flash address.
void xsnorMemoryUnmap(void *ip)
Leaves the memory mapped mode.
static flash_error_t __xsnor_fls_program_impl(void *ip, flash_offset_t offset, size_t n, const uint8_t *pp)
Implementation of interface method flsProgram().
static flash_error_t __xsnor_fls_read_impl(void *ip, flash_offset_t offset, size_t n, uint8_t *rp)
Implementation of interface method flsRead().
void __xsnor_bus_cmd(void *ip, uint32_t cmd)
Sends a naked command.
flash_error_t xsnorStart(void *ip, const xsnor_config_t *config)
Configures and activates a SNOR driver.
static flash_error_t __xsnor_fls_release_exclusive_impl(void *ip)
Implementation of interface method flsReleaseExclusive().
static const flash_descriptor_t * __xsnor_fls_get_descriptor_impl(void *ip)
Implementation of interface method flsGetDescriptor().
struct xsnor_config xsnor_config_t
Type of a SNOR configuration structure.
void __xsnor_bus_cmd_addr_dummy_receive(void *ip, uint32_t cmd, flash_offset_t offset, uint32_t dummy, size_t n, uint8_t *p)
Sends a complete header followed by a data receive phase.
static CC_FORCE_INLINE flash_error_t xsnor_device_query_erase(void *ip, unsigned *msec)
Queries the driver for erase operation progress.
void __xsnor_bus_cmd_dummy_receive(void *ip, uint32_t cmd, uint32_t dummy, size_t n, uint8_t *p)
Sends a command followed by dummy cycles and a data receive phase.
static CC_FORCE_INLINE flash_error_t xsnor_device_init(void *ip)
static CC_FORCE_INLINE flash_error_t xsnor_device_program(void *ip, flash_offset_t offset, size_t n, const uint8_t *pp)
Program operation.
void __xsnor_bus_cmd_receive(void *ip, uint32_t cmd, size_t n, uint8_t *p)
Sends a command followed by a data receive phase.
void __xsnor_bus_cmd_addr_receive(void *ip, uint32_t cmd, flash_offset_t offset, size_t n, uint8_t *p)
Sends a command followed by a flash address and a data receive phase.
void xsnorStop(void *ip)
Deactivates a SNOR driver.
#define __xsnor_bus_acquire(self)
static flash_error_t __xsnor_fls_acquire_exclusive_impl(void *ip)
Implementation of interface method flsAcquireExclusive().
static CC_FORCE_INLINE flash_error_t xsnor_device_verify_erase(void *ip, flash_sector_t sector)
Returns the erase state of a sector.
flash_error_t xsnorMemoryMap(void *ip, uint8_t **addrp)
Enters the memory mapped mode.
static flash_error_t __xsnor_fls_start_erase_sector_impl(void *ip, flash_sector_t sector)
Implementation of interface method flsStartEraseSector().
static CC_FORCE_INLINE flash_error_t xsnor_device_start_erase_all(void *ip)
Starts a whole-device erase operation.
static void osalMutexObjectInit(mutex_t *mp)
Initializes a mutex_t object.
Definition osal.h:753
void osalMutexLock(mutex_t *mp)
Locks the specified mutex.
Definition osal.c:380
#define osalDbgAssert(c, remark)
Condition assertion.
Definition osal.h:264
void osalMutexUnlock(mutex_t *mp)
Unlocks the specified mutex.
Definition osal.c:400
#define osalDbgCheck(c)
Function parameters check.
Definition osal.h:284
void spiSelect(SPIDriver *spip)
Asserts the slave select signal and prepares for transfers.
void spiReleaseBus(SPIDriver *spip)
Releases exclusive access to the SPI bus.
void spiSend(SPIDriver *spip, size_t n, const void *txbuf)
Sends data over the SPI bus.
void spiIgnore(SPIDriver *spip, size_t n)
Ignores data on the SPI bus.
void spiAcquireBus(SPIDriver *spip)
Gains exclusive access to the SPI bus.
msg_t spiStart(SPIDriver *spip, const SPIConfig *config)
Configures and activates the SPI peripheral.
void spiStop(SPIDriver *spip)
Deactivates the SPI peripheral.
void spiReceive(SPIDriver *spip, size_t n, void *rxbuf)
Receives data from the SPI bus.
void spiUnselect(SPIDriver *spip)
Deasserts the slave select signal.
void wspiAcquireBus(WSPIDriver *wspip)
Gains exclusive access to the WSPI bus.
Definition hal_wspi.c:399
msg_t wspiStart(WSPIDriver *wspip, const WSPIConfig *config)
Configures and activates the WSPI peripheral.
Definition hal_wspi.c:92
bool wspiReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, uint8_t *rxbuf)
Sends a command then receives data over the WSPI bus.
Definition hal_wspi.c:311
void wspiReleaseBus(WSPIDriver *wspip)
Releases exclusive access to the WSPI bus.
Definition hal_wspi.c:415
bool wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp)
Sends a command without data phase.
Definition hal_wspi.c:237
bool wspiSend(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, const uint8_t *txbuf)
Sends a command with data over the WSPI bus.
Definition hal_wspi.c:273
void wspiStop(WSPIDriver *wspip)
Deactivates the WSPI peripheral.
Definition hal_wspi.c:131
HAL subsystem header.
Generated SNOR Base Driver header.
Type of a flash device descriptor.
Definition hal_flash.h:136
Interface flash_interface_i virtual methods table.
Type of a WSPI command descriptor.
Definition hal_wspi.h:101
uint32_t dummy
Number of dummy cycles to be inserted.
Definition hal_wspi.h:121
uint32_t cfg
Transfer configuration field.
Definition hal_wspi.h:105
uint32_t alt
Alternate phase data.
Definition hal_wspi.h:117
uint32_t addr
Address phase data.
Definition hal_wspi.h:113
uint32_t cmd
Command phase data.
Definition hal_wspi.h:109
uint8_t spibuf[8]
Non-cacheable SPI buffer.
SPIDriver * drv
SPI driver to be used for physical communication.
WSPIDriver * drv
WSPI driver to be used for physical communication.
int bus_type
Bus type selection switch.
union xsnor_bus_configs bus
WSPI driver configuration.
xsnor_buffers_t * buffers
Pointer to the non-cacheable buffers.
struct xsnor_bus_wspi wspi
struct xsnor_bus_spi spi