ChibiOS 21.11.4
hal_xsnor_base.c
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006..2025 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 /* Bus released.*/
190
191 return err;
192}
193
194/**
195 * @brief Implementation of interface method @p flsStartEraseSector().
196 *
197 * @param[in,out] ip Pointer to the @p flash_interface_i class
198 * interface.
199 * @param[in] sector Sector to be erased.
200 * @return An error code.
201 */
203 flash_sector_t sector) {
204 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
205 flash_error_t err;
206
207 osalDbgCheck(self != NULL);
208 osalDbgAssert((self->state == FLASH_READY) || (self->state == FLASH_ERASE),
209 "invalid state");
210
211 if (self->state == FLASH_ERASE) {
212 return FLASH_BUSY_ERASING;
213 }
214
215 /* Bus acquired.*/
217
218 /* FLASH_ERASE state while the operation is performed.*/
219 self->state = FLASH_ERASE;
220
221 /* Actual erase implementation.*/
222 err = xsnor_device_start_erase_sector(self, sector);
223
224 /* Bus released.*/
226
227 return err;
228}
229
230/**
231 * @brief Implementation of interface method @p flsQueryErase().
232 *
233 * @param[in,out] ip Pointer to the @p flash_interface_i class
234 * interface.
235 * @param[out] msec Recommended time, in milliseconds, that should
236 * be spent before calling this function again,
237 * can be @p NULL
238 * @return An error code.
239 */
240static flash_error_t __xsnor_fls_query_erase_impl(void *ip, unsigned *msec) {
241 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
242 flash_error_t err;
243
244 osalDbgCheck(self != NULL);
245 osalDbgAssert((self->state == FLASH_READY) || (self->state == FLASH_ERASE),
246 "invalid state");
247
248 /* If there is an erase in progress then the device must be checked.*/
249 if (self->state == FLASH_ERASE) {
250
251 /* Bus acquired.*/
253
254 /* Actual query erase implementation.*/
255 err = xsnor_device_query_erase(self, msec);
256
257 /* The device is ready to accept commands.*/
258 if (err == FLASH_NO_ERROR) {
259 self->state = FLASH_READY;
260 }
261
262 /* Bus released.*/
264 }
265 else {
266 err = FLASH_NO_ERROR;
267 }
268
269 return err;
270}
271
272/**
273 * @brief Implementation of interface method @p flsVerifyErase().
274 *
275 * @param[in,out] ip Pointer to the @p flash_interface_i class
276 * interface.
277 * @param[in] sector Sector to be verified.
278 * @return An error code.
279 */
281 flash_sector_t sector) {
282 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
283 flash_error_t err;
284
285 osalDbgCheck(self != NULL);
286 osalDbgAssert((self->state == FLASH_READY) || (self->state == FLASH_ERASE),
287 "invalid state");
288
289 if (self->state == FLASH_ERASE) {
290 return FLASH_BUSY_ERASING;
291 }
292
293 /* Bus acquired.*/
295
296 /* FLASH_READY state while the operation is performed.*/
297 self->state = FLASH_READ;
298
299 /* Actual verify erase implementation.*/
300 err = xsnor_device_verify_erase(self, sector);
301
302 /* Ready state again.*/
303 self->state = FLASH_READY;
304
305 /* Bus released.*/
307
308 return err;
309}
310
311/**
312 * @brief Implementation of interface method @p flsAcquireExclusive().
313 *
314 * @param[in,out] ip Pointer to the @p flash_interface_i class
315 * interface.
316 * @return An error code.
317 */
319 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
320
321 osalMutexLock(&self->mutex);
322 return FLASH_NO_ERROR;
323}
324
325/**
326 * @brief Implementation of interface method @p flsReleaseExclusive().
327 *
328 * @param[in,out] ip Pointer to the @p flash_interface_i class
329 * interface.
330 * @return An error code.
331 */
333 hal_xsnor_base_c *self = oopIfGetOwner(hal_xsnor_base_c, ip);
334
335 osalMutexUnlock(&self->mutex);
336 return FLASH_NO_ERROR;
337}
338/** @} */
339
340/**
341 * @name Methods implementations of hal_xsnor_base_c
342 * @{
343 */
344/**
345 * @brief Implementation of object creation.
346 * @note This function is meant to be used by derived classes.
347 *
348 * @param[out] ip Pointer to a @p hal_xsnor_base_c instance to be
349 * initialized.
350 * @param[in] vmt VMT pointer for the new object.
351 * @return A new reference to the object.
352 */
353void *__xsnor_objinit_impl(void *ip, const void *vmt) {
355
356 /* Initialization of the ancestors-defined parts.*/
357 __bo_objinit_impl(self, vmt);
358
359 /* Initialization of interface flash_interface_i.*/
360 {
361 static const struct flash_interface_vmt xsnor_fls_vmt = {
362 .instance_offset = offsetof(hal_xsnor_base_c, fls),
363 .get_descriptor = __xsnor_fls_get_descriptor_impl,
364 .read = __xsnor_fls_read_impl,
365 .program = __xsnor_fls_program_impl,
366 .start_erase_all = __xsnor_fls_start_erase_all_impl,
367 .start_erase_sector = __xsnor_fls_start_erase_sector_impl,
368 .query_erase = __xsnor_fls_query_erase_impl,
369 .verify_erase = __xsnor_fls_verify_erase_impl,
370 .acquire_exclusive = __xsnor_fls_acquire_exclusive_impl,
371 .release_exclusive = __xsnor_fls_release_exclusive_impl
372 };
373 oopIfObjectInit(&self->fls, &xsnor_fls_vmt);
374 }
375
376 /* Initialization code.*/
377 self->state = FLASH_STOP;
378 self->config = NULL;
379#if XSNOR_USE_WSPI == TRUE
380 self->commands = NULL;
381#endif
382 osalMutexObjectInit(&self->mutex);
383
384 return self;
385}
386
387/**
388 * @brief Implementation of object finalization.
389 * @note This function is meant to be used by derived classes.
390 *
391 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance to be
392 * disposed.
393 */
394void __xsnor_dispose_impl(void *ip) {
396
397 /* Finalization code.*/
398 self->state = FLASH_UNINIT;
399
400 /* Finalization of the ancestors-defined parts.*/
401 __bo_dispose_impl(self);
402}
403/** @} */
404
405/**
406 * @name Regular methods of hal_xsnor_base_c
407 * @{
408 */
409#if (XSNOR_USE_SPI == TRUE) || defined (__DOXYGEN__)
410/**
411 * @brief Sends command and address over SPI.
412 *
413 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
414 * @param[in] cmd Instruction code.
415 * @param[in] offset Flash offset.
416 */
417void __xsnor_spi_cmd_addr(void *ip, uint32_t cmd, flash_offset_t offset) {
419 const xsnor_config_t *config = self->config;
420
421 config->buffers->spibuf[0] = cmd;
422 if ((self->descriptor.attributes & FLASH_ATTR_SPI_4BYTES_ADDR_HINT) != 0U) {
423 config->buffers->spibuf[1] = (uint8_t)(offset >> 24);
424 config->buffers->spibuf[2] = (uint8_t)(offset >> 16);
425 config->buffers->spibuf[3] = (uint8_t)(offset >> 8);
426 config->buffers->spibuf[4] = (uint8_t)(offset >> 0);
427 spiSend(config->bus.spi.drv, 5, config->buffers->spibuf);
428 }
429 else {
430 config->buffers->spibuf[1] = (uint8_t)(offset >> 16);
431 config->buffers->spibuf[2] = (uint8_t)(offset >> 8);
432 config->buffers->spibuf[3] = (uint8_t)(offset >> 0);
433 spiSend(config->bus.spi.drv, 4, config->buffers->spibuf);
434 }
435}
436#endif /* XSNOR_USE_SPI == TRUE */
437
438#if (XSNOR_SHARED_BUS == TRUE) || defined (__DOXYGEN__)
439/**
440 * @brief Bus acquisition and lock.
441 *
442 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
443 */
444void __xsnor_bus_acquire(void *ip) {
446
447#if XSNOR_USE_BOTH == TRUE
448 if (self->config->bus_type != XSNOR_BUS_MODE_SPI) {
449#endif
450#if XSNOR_USE_WSPI == TRUE
451 wspiAcquireBus(self->config->bus.wspi.drv);
452 if (self->config->bus.wspi.cfg != self->config->bus.wspi.drv->config) {
453 wspiStart(self->config->bus.wspi.drv, self->config->bus.wspi.cfg);
454 }
455#endif
456#if XSNOR_USE_BOTH == TRUE
457 }
458 else {
459#endif
460#if XSNOR_USE_SPI == TRUE
461 spiAcquireBus(self->config->bus.spi.drv);
462 if (self->config->bus.spi.cfg != self->config->bus.spi.drv->config) {
463 spiStart(self->config->bus.spi.drv, self->config->bus.spi.cfg);
464 }
465#endif
466#if XSNOR_USE_BOTH == TRUE
467 }
468#endif
469}
470
471/**
472 * @brief Bus release and unlock.
473 *
474 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
475 */
476void __xsnor_bus_release(void *ip) {
478
479#if XSNOR_USE_BOTH == TRUE
480 if (self->config->bus_type != XSNOR_BUS_MODE_SPI) {
481#endif
482#if XSNOR_USE_WSPI == TRUE
483 wspiReleaseBus(self->config->bus.wspi.drv);
484#endif
485#if XSNOR_USE_BOTH == TRUE
486 }
487 else {
488#endif
489#if XSNOR_USE_SPI == TRUE
490 spiReleaseBus(self->config->bus.spi.drv);
491#endif
492#if XSNOR_USE_BOTH == TRUE
493 }
494#endif
495}
496#endif /* XSNOR_SHARED_BUS == TRUE */
497
498/**
499 * @brief Sends a naked command.
500 *
501 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
502 * @param[in] cmd Instruction code.
503 */
504void __xsnor_bus_cmd(void *ip, uint32_t cmd) {
506 const xsnor_config_t *config = self->config;
507
508#if XSNOR_USE_BOTH == TRUE
509 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
510#endif
511#if XSNOR_USE_WSPI == TRUE
512 wspi_command_t mode;
513
514 mode.cmd = cmd;
515 mode.cfg = self->commands->cmd;
516 mode.addr = 0U;
517 mode.alt = 0U;
518 mode.dummy = 0U;
519 wspiCommand(config->bus.wspi.drv, &mode);
520#endif
521#if XSNOR_USE_BOTH == TRUE
522 }
523 else {
524#endif
525#if XSNOR_USE_SPI == TRUE
526
527 spiSelect(config->bus.spi.drv);
528 config->buffers->spibuf[0] = cmd;
529 spiSend(config->bus.spi.drv, 1, config->buffers->spibuf);
530 spiUnselect(config->bus.spi.drv);
531#endif
532#if XSNOR_USE_BOTH == TRUE
533 }
534#endif
535}
536
537/**
538 * @brief Sends a command followed by a data transmit phase.
539 *
540 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
541 * @param[in] cmd Instruction code.
542 * @param[in] n Number of bytes to transmit.
543 * @param[in] p Data buffer.
544 */
545void __xsnor_bus_cmd_send(void *ip, uint32_t cmd, size_t n, const uint8_t *p) {
547 const xsnor_config_t *config = self->config;
548
549#if XSNOR_USE_BOTH == TRUE
550 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
551#endif
552#if XSNOR_USE_WSPI == TRUE
553 wspi_command_t mode;
554
555 mode.cmd = cmd;
556 mode.cfg = self->commands->cmd_data;
557 mode.addr = 0U;
558 mode.alt = 0U;
559 mode.dummy = 0U;
560 wspiSend(config->bus.wspi.drv, &mode, n, p);
561#endif
562#if XSNOR_USE_BOTH == TRUE
563 }
564 else {
565#endif
566#if XSNOR_USE_SPI == TRUE
567
568 spiSelect(config->bus.spi.drv);
569 config->buffers->spibuf[0] = cmd;
570 spiSend(config->bus.spi.drv, 1, config->buffers->spibuf);
571 spiSend(config->bus.spi.drv, n, p);
572 spiUnselect(config->bus.spi.drv);
573#endif
574#if XSNOR_USE_BOTH == TRUE
575 }
576#endif
577}
578
579/**
580 * @brief Sends a command followed by a data receive phase.
581 *
582 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
583 * @param[in] cmd Instruction code.
584 * @param[in] n Number of bytes to receive.
585 * @param[out] p Data buffer.
586 */
587void __xsnor_bus_cmd_receive(void *ip, uint32_t cmd, size_t n, uint8_t *p) {
589 const xsnor_config_t *config = self->config;
590
591#if XSNOR_USE_BOTH == TRUE
592 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
593#endif
594#if XSNOR_USE_WSPI == TRUE
595 wspi_command_t mode;
596
597 mode.cmd = cmd;
598 mode.cfg = self->commands->cmd_data;
599 mode.addr = 0U;
600 mode.alt = 0U;
601 mode.dummy = 0U;
602 wspiReceive(config->bus.wspi.drv, &mode, n, p);
603#endif
604#if XSNOR_USE_BOTH == TRUE
605 }
606 else {
607#endif
608#if XSNOR_USE_SPI == TRUE
609
610 spiSelect(config->bus.spi.drv);
611 config->buffers->spibuf[0] = cmd;
612 spiSend(config->bus.spi.drv, 1, config->buffers->spibuf);
613 spiReceive(config->bus.spi.drv, n, p);
614 spiUnselect(config->bus.spi.drv);
615#endif
616#if XSNOR_USE_BOTH == TRUE
617 }
618#endif
619}
620
621/**
622 * @brief Sends a command followed by a flash address.
623 *
624 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
625 * @param[in] cmd Instruction code.
626 * @param[in] offset Flash offset.
627 */
628void __xsnor_bus_cmd_addr(void *ip, uint32_t cmd, flash_offset_t offset) {
630 const xsnor_config_t *config = self->config;
631
632#if XSNOR_USE_BOTH == TRUE
633 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
634#endif
635#if XSNOR_USE_WSPI == TRUE
636 wspi_command_t mode;
637
638 mode.cmd = cmd;
639 mode.cfg = self->commands->cmd_addr;
640 mode.addr = offset;
641 mode.alt = 0U;
642 mode.dummy = 0U;
643 wspiCommand(config->bus.wspi.drv, &mode);
644#endif
645#if XSNOR_USE_BOTH == TRUE
646 }
647 else {
648#endif
649#if XSNOR_USE_SPI == TRUE
650
651 spiSelect(config->bus.spi.drv);
652 __xsnor_spi_cmd_addr(self, cmd, offset);
653 spiUnselect(config->bus.spi.drv);
654#endif
655#if XSNOR_USE_BOTH == TRUE
656 }
657#endif
658}
659
660/**
661 * @brief Sends a command followed by a flash address and a data transmit
662 * phase.
663 *
664 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
665 * @param[in] cmd Instruction code.
666 * @param[in] offset Flash offset.
667 * @param[in] n Number of bytes to transmit.
668 * @param[in] p Data buffer.
669 */
670void __xsnor_bus_cmd_addr_send(void *ip, uint32_t cmd, flash_offset_t offset,
671 size_t n, const uint8_t *p) {
673 const xsnor_config_t *config = self->config;
674
675#if XSNOR_USE_BOTH == TRUE
676 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
677#endif
678#if XSNOR_USE_WSPI == TRUE
679 wspi_command_t mode;
680
681 mode.cmd = cmd;
682 mode.cfg = self->commands->cmd_addr_data;
683 mode.addr = offset;
684 mode.alt = 0U;
685 mode.dummy = 0U;
686 wspiSend(config->bus.wspi.drv, &mode, n, p);
687#endif
688#if XSNOR_USE_BOTH == TRUE
689 }
690 else {
691#endif
692#if XSNOR_USE_SPI == TRUE
693
694 spiSelect(config->bus.spi.drv);
695 __xsnor_spi_cmd_addr(self, cmd, offset);
696 spiSend(config->bus.spi.drv, n, p);
697 spiUnselect(config->bus.spi.drv);
698#endif
699#if XSNOR_USE_BOTH == TRUE
700 }
701#endif
702}
703
704/**
705 * @brief Sends a command followed by a flash address and a data receive
706 * phase.
707 *
708 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
709 * @param[in] cmd Instruction code.
710 * @param[in] offset Flash offset.
711 * @param[in] n Number of bytes to receive.
712 * @param[in] p Data buffer.
713 */
714void __xsnor_bus_cmd_addr_receive(void *ip, uint32_t cmd,
715 flash_offset_t offset, size_t n, uint8_t *p) {
717 const xsnor_config_t *config = self->config;
718
719#if XSNOR_USE_BOTH == TRUE
720 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
721#endif
722#if XSNOR_USE_WSPI == TRUE
723 wspi_command_t mode;
724
725 mode.cmd = cmd;
726 mode.cfg = self->commands->cmd_addr_data;
727 mode.addr = offset;
728 mode.alt = 0U;
729 mode.dummy = 0U;
730 wspiReceive(config->bus.wspi.drv, &mode, n, p);
731#endif
732#if XSNOR_USE_BOTH == TRUE
733 }
734 else {
735#endif
736#if XSNOR_USE_SPI == TRUE
737
738 spiSelect(config->bus.spi.drv);
739 __xsnor_spi_cmd_addr(self, cmd, offset);
740 spiReceive(config->bus.spi.drv, n, p);
741 spiUnselect(config->bus.spi.drv);
742#endif
743#if XSNOR_USE_BOTH == TRUE
744 }
745#endif
746}
747
748/**
749 * @brief Sends a command followed by dummy cycles and a data receive
750 * phase.
751 *
752 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
753 * @param[in] cmd Instruction code.
754 * @param[in] dummy Number of dummy cycles.
755 * @param[in] n Number of bytes to receive.
756 * @param[out] p Data buffer.
757 */
758void __xsnor_bus_cmd_dummy_receive(void *ip, uint32_t cmd, uint32_t dummy,
759 size_t n, uint8_t *p) {
761 const xsnor_config_t *config = self->config;
762
763#if XSNOR_USE_BOTH == TRUE
764 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
765#endif
766#if XSNOR_USE_WSPI == TRUE
767 wspi_command_t mode;
768
769 mode.cmd = cmd;
770 mode.cfg = self->commands->cmd_data;
771 mode.addr = 0U;
772 mode.alt = 0U;
773 mode.dummy = dummy;
774 wspiReceive(config->bus.wspi.drv, &mode, n, p);
775#endif
776#if XSNOR_USE_BOTH == TRUE
777 }
778 else {
779#endif
780#if XSNOR_USE_SPI == TRUE
781 osalDbgAssert((dummy & 7) == 0U, "multiple of 8 dummy cycles");
782
783 spiSelect(config->bus.spi.drv);
784 config->buffers->spibuf[0] = cmd;
785 spiSend(config->bus.spi.drv, 1, config->buffers->spibuf);
786 if (dummy != 0U) {
787 spiIgnore(config->bus.spi.drv, dummy / 8U);
788 }
789 spiReceive(config->bus.spi.drv, n, p);
790 spiUnselect(config->bus.spi.drv);
791#endif
792#if XSNOR_USE_BOTH == TRUE
793 }
794#endif
795}
796
797/**
798 * @brief Sends a complete header followed by a data receive phase.
799 *
800 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
801 * @param[in] cmd Instruction code.
802 * @param[in] offset Flash offset.
803 * @param[in] dummy Number of dummy cycles.
804 * @param[in] n Number of bytes to receive.
805 * @param[out] p Data buffer.
806 */
807void __xsnor_bus_cmd_addr_dummy_receive(void *ip, uint32_t cmd,
808 flash_offset_t offset, uint32_t dummy,
809 size_t n, uint8_t *p) {
811 const xsnor_config_t *config = self->config;
812
813#if XSNOR_USE_BOTH == TRUE
814 if (config->bus_type != XSNOR_BUS_MODE_SPI) {
815#endif
816#if XSNOR_USE_WSPI == TRUE
817 wspi_command_t mode;
818
819 mode.cmd = cmd;
820 mode.cfg = self->commands->cmd_addr_data;
821 mode.addr = offset;
822 mode.alt = 0U;
823 mode.dummy = dummy;
824 wspiReceive(config->bus.wspi.drv, &mode, n, p);
825#endif
826#if XSNOR_USE_BOTH == TRUE
827 }
828 else {
829#endif
830#if XSNOR_USE_SPI == TRUE
831 osalDbgAssert((dummy & 7) == 0U, "multiple of 8 dummy cycles");
832
833 spiSelect(config->bus.spi.drv);
834 __xsnor_spi_cmd_addr(self, cmd, offset);
835 if (dummy != 0U) {
836 spiIgnore(config->bus.spi.drv, dummy / 8U);
837 }
838 spiReceive(config->bus.spi.drv, n, p);
839 spiUnselect(config->bus.spi.drv);
840#endif
841#if XSNOR_USE_BOTH == TRUE
842 }
843#endif
844}
845
846/**
847 * @brief Configures and activates a SNOR driver.
848 *
849 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
850 * @param[in] config Pointer to the configuration.
851 * @return An error code.
852 * @retval FLASH_NO_ERROR Operation successful.
853 * @retval FLASH_ERROR_HW_FAILURE If initialization failed.
854 *
855 * @api
856 */
857flash_error_t xsnorStart(void *ip, const xsnor_config_t *config) {
859 flash_error_t err;
860
861 osalDbgCheck((self != NULL) && (config != NULL));
862 osalDbgAssert(self->state != FLASH_UNINIT, "invalid state");
863
864 self->config = config;
865
866 if (self->state == FLASH_STOP) {
867
868 /* Bus acquisition.*/
870
871#if XSNOR_USE_BOTH == TRUE
872 if (self->config->bus_type != XSNOR_BUS_MODE_SPI) {
873#endif
874#if XSNOR_USE_WSPI == TRUE
875 wspiStart(self->config->bus.wspi.drv, self->config->bus.wspi.cfg);
876#endif
877#if XSNOR_USE_BOTH == TRUE
878 }
879 else {
880#endif
881#if XSNOR_USE_SPI == TRUE
882 spiStart(self->config->bus.spi.drv, self->config->bus.spi.cfg);
883#endif
884#if XSNOR_USE_BOTH == TRUE
885 }
886#endif
887
888 /* Device identification and initialization.*/
889 err = xsnor_device_init(self);
890 if (err == FLASH_NO_ERROR) {
891 /* Driver in ready state.*/
892 self->state = FLASH_READY;
893 }
894
895 /* Bus release.*/
897 }
898
899 return err;
900}
901
902/**
903 * @brief Deactivates a SNOR driver.
904 *
905 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
906 *
907 * @api
908 */
909void xsnorStop(void *ip) {
911 osalDbgCheck(self != NULL);
912 osalDbgAssert(self->state != FLASH_UNINIT, "invalid state");
913
914 if (self->state != FLASH_STOP) {
915
916 /* Stopping bus device.*/
917#if XSNOR_USE_BOTH == TRUE
918 if (self->config->bus_type != XSNOR_BUS_MODE_SPI) {
919#endif
920#if XSNOR_USE_WSPI == TRUE
921 wspiStop(self->config->bus.wspi.drv);
922#endif
923#if XSNOR_USE_BOTH == TRUE
924 }
925 else {
926#endif
927#if XSNOR_USE_SPI == TRUE
928 spiStop(self->config->bus.spi.drv);
929#endif
930#if XSNOR_USE_BOTH == TRUE
931 }
932#endif
933
934 /* Driver stopped.*/
935 self->state = FLASH_STOP;
936
937 /* Deleting current configuration.*/
938 self->config = NULL;
939 }
940}
941
942#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined (__DOXYGEN__)
943/**
944 * @brief Enters the memory mapped mode.
945 *
946 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
947 * @param[out] addrp Pointer to the memory mapped memory or @p NULL
948 * @return An error code.
949 * @retval FLASH_NO_ERROR Operation successful.
950 * @retval FLASH_ERROR_HW_FAILURE If memory mapped mode failed.
951 *
952 * @api
953 */
954flash_error_t xsnorMemoryMap(void *ip, uint8_t **addrp) {
956 flash_error_t err;
957
958 /* Activating XIP mode in the device.*/
959 err = xsnor_device_mmap_on(self, addrp);
960
961 return err;
962}
963
964/**
965 * @brief Leaves the memory mapped mode.
966 *
967 * @param[in,out] ip Pointer to a @p hal_xsnor_base_c instance.
968 *
969 * @api
970 */
971void xsnorMemoryUnmap(void *ip) {
973
975}
976#endif /* WSPI_SUPPORTS_MEMMAP == TRUE */
977/** @} */
978
979/** @} */
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 an 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