ChibiOS/HAL 9.0.0
hal_serial_nor.c
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006..2018 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_serial_nor.c
19 * @brief Serial NOR serial flash driver code.
20 *
21 * @addtogroup HAL_SERIAL_NOR
22 * @{
23 */
24
25#include "hal.h"
26#include "hal_serial_nor.h"
27
28/*===========================================================================*/
29/* Driver local definitions. */
30/*===========================================================================*/
31
32/*===========================================================================*/
33/* Driver exported variables. */
34/*===========================================================================*/
35
36/*===========================================================================*/
37/* Driver local variables and types. */
38/*===========================================================================*/
39
40static const flash_descriptor_t *snor_get_descriptor(void *instance);
41static flash_error_t snor_read(void *instance, flash_offset_t offset,
42 size_t n, uint8_t *rp);
43static flash_error_t snor_program(void *instance, flash_offset_t offset,
44 size_t n, const uint8_t *pp);
45static flash_error_t snor_start_erase_all(void *instance);
46static flash_error_t snor_start_erase_sector(void *instance,
47 flash_sector_t sector);
48static flash_error_t snor_verify_erase(void *instance,
49 flash_sector_t sector);
50static flash_error_t snor_query_erase(void *instance, uint32_t *msec);
51static flash_error_t snor_acquire_exclusive(void *instance);
52static flash_error_t snor_release_exclusive(void *instance);
53static flash_error_t snor_read_sfdp(void *instance, flash_offset_t offset,
54 size_t n, uint8_t *rp);
55
56/**
57 * @brief Virtual methods table.
58 */
66
67/*===========================================================================*/
68/* Driver local functions. */
69/*===========================================================================*/
70
71/**
72 * @brief Returns a pointer to the device descriptor.
73 *
74 * @param[in] instance instance pointer
75 * @return Pointer to a static descriptor structure.
76 */
77static const flash_descriptor_t *snor_get_descriptor(void *instance) {
78 SNORDriver *devp = (SNORDriver *)instance;
79
80 osalDbgCheck(instance != NULL);
81 osalDbgAssert((devp->state != FLASH_UNINIT) && (devp->state != FLASH_STOP),
82 "invalid state");
83
84 return &snor_descriptor;
85}
86
87static flash_error_t snor_read(void *instance, flash_offset_t offset,
88 size_t n, uint8_t *rp) {
89 SNORDriver *devp = (SNORDriver *)instance;
90 flash_error_t err;
91
92 osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U));
93 osalDbgCheck((size_t)offset + n <= (size_t)snor_descriptor.sectors_count *
94 (size_t)snor_descriptor.sectors_size);
95 osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
96 "invalid state");
97
98 if (devp->state == FLASH_ERASE) {
99 return FLASH_BUSY_ERASING;
100 }
101
102 /* Bus acquired.*/
103 bus_acquire(devp->config->busp, devp->config->buscfg);
104
105 /* FLASH_READY state while the operation is performed.*/
106 devp->state = FLASH_READ;
107
108 /* Actual read implementation.*/
109 err = snor_device_read(devp, offset, n, rp);
110
111 /* Ready state again.*/
112 devp->state = FLASH_READY;
113
114 /* Bus released.*/
115 bus_release(devp->config->busp);
116
117 return err;
118}
119
120static flash_error_t snor_program(void *instance, flash_offset_t offset,
121 size_t n, const uint8_t *pp) {
122 SNORDriver *devp = (SNORDriver *)instance;
123 flash_error_t err;
124
125 osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U));
126 osalDbgCheck((size_t)offset + n <= (size_t)snor_descriptor.sectors_count *
127 (size_t)snor_descriptor.sectors_size);
128 osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
129 "invalid state");
130
131 if (devp->state == FLASH_ERASE) {
132 return FLASH_BUSY_ERASING;
133 }
134
135 /* Bus acquired.*/
136 bus_acquire(devp->config->busp, devp->config->buscfg);
137
138 /* FLASH_PGM state while the operation is performed.*/
139 devp->state = FLASH_PGM;
140
141 /* Actual program implementation.*/
142 err = snor_device_program(devp, offset, n, pp);
143
144 /* Ready state again.*/
145 devp->state = FLASH_READY;
146
147 /* Bus released.*/
148 bus_release(devp->config->busp);
149
150 return err;
151}
152
153static flash_error_t snor_start_erase_all(void *instance) {
154 SNORDriver *devp = (SNORDriver *)instance;
155 flash_error_t err;
156
157 osalDbgCheck(instance != NULL);
158 osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
159 "invalid state");
160
161 if (devp->state == FLASH_ERASE) {
162 return FLASH_BUSY_ERASING;
163 }
164
165 /* Bus acquired.*/
166 bus_acquire(devp->config->busp, devp->config->buscfg);
167
168 /* FLASH_ERASE state while the operation is performed.*/
169 devp->state = FLASH_ERASE;
170
171 /* Actual erase implementation.*/
172 err = snor_device_start_erase_all(devp);
173
174 /* Bus released.*/
175 bus_release(devp->config->busp);
176
177 return err;
178}
179
181 flash_sector_t sector) {
182 SNORDriver *devp = (SNORDriver *)instance;
183 flash_error_t err;
184
185 osalDbgCheck(instance != NULL);
186 osalDbgCheck(sector < snor_descriptor.sectors_count);
187 osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
188 "invalid state");
189
190 if (devp->state == FLASH_ERASE) {
191 return FLASH_BUSY_ERASING;
192 }
193
194 /* Bus acquired.*/
195 bus_acquire(devp->config->busp, devp->config->buscfg);
196
197 /* FLASH_ERASE state while the operation is performed.*/
198 devp->state = FLASH_ERASE;
199
200 /* Actual erase implementation.*/
201 err = snor_device_start_erase_sector(devp, sector);
202
203 /* Bus released.*/
204 bus_release(devp->config->busp);
205
206 return err;
207}
208
209static flash_error_t snor_verify_erase(void *instance,
210 flash_sector_t sector) {
211 SNORDriver *devp = (SNORDriver *)instance;
212 flash_error_t err;
213
214 osalDbgCheck(instance != NULL);
215 osalDbgCheck(sector < snor_descriptor.sectors_count);
216 osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
217 "invalid state");
218
219 if (devp->state == FLASH_ERASE) {
220 return FLASH_BUSY_ERASING;
221 }
222
223 /* Bus acquired.*/
224 bus_acquire(devp->config->busp, devp->config->buscfg);
225
226 /* FLASH_READY state while the operation is performed.*/
227 devp->state = FLASH_READ;
228
229 /* Actual verify erase implementation.*/
230 err = snor_device_verify_erase(devp, sector);
231
232 /* Ready state again.*/
233 devp->state = FLASH_READY;
234
235 /* Bus released.*/
236 bus_release(devp->config->busp);
237
238 return err;
239}
240
241static flash_error_t snor_query_erase(void *instance, uint32_t *msec) {
242 SNORDriver *devp = (SNORDriver *)instance;
243 flash_error_t err;
244
245 osalDbgCheck(instance != NULL);
246 osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
247 "invalid state");
248
249 /* If there is an erase in progress then the device must be checked.*/
250 if (devp->state == FLASH_ERASE) {
251
252 /* Bus acquired.*/
253 bus_acquire(devp->config->busp, devp->config->buscfg);
254
255 /* Actual query erase implementation.*/
256 err = snor_device_query_erase(devp, msec);
257
258 /* The device is ready to accept commands.*/
259 if (err == FLASH_NO_ERROR) {
260 devp->state = FLASH_READY;
261 }
262
263 /* Bus released.*/
264 bus_release(devp->config->busp);
265 }
266 else {
267 err = FLASH_NO_ERROR;
268 }
269
270 return err;
271}
272
273static flash_error_t snor_read_sfdp(void *instance, flash_offset_t offset,
274 size_t n, uint8_t *rp) {
275 SNORDriver *devp = (SNORDriver *)instance;
276 flash_error_t err;
277
278 osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U));
279 osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
280 "invalid state");
281
282 if (devp->state == FLASH_ERASE) {
283 return FLASH_BUSY_ERASING;
284 }
285
286 /* Bus acquired.*/
287 bus_acquire(devp->config->busp, devp->config->buscfg);
288
289 /* Actual read SFDP implementation.*/
290 err = snor_device_read_sfdp(devp, offset, n, rp);
291
292 /* The device is ready to accept commands.*/
293 if (err == FLASH_NO_ERROR) {
294 devp->state = FLASH_READY;
295 }
296
297 /* Bus released.*/
298 bus_release(devp->config->busp);
299
300 return err;
301}
302
303static flash_error_t snor_acquire_exclusive(void *instance) {
304#if (SNOR_USE_MUTUAL_EXCLUSION == TRUE)
305 SNORDriver *devp = (SNORDriver *)instance;
306
307 osalMutexLock(&devp->mutex);
308 return FLASH_NO_ERROR;
309#else
310 (void)instance;
311 osalDbgAssert(false, "mutual exclusion not enabled");
313#endif
314}
315
316static flash_error_t snor_release_exclusive(void *instance) {
317#if (SNOR_USE_MUTUAL_EXCLUSION == TRUE)
318 SNORDriver *devp = (SNORDriver *)instance;
319
320 osalMutexUnlock(&devp->mutex);
321 return FLASH_NO_ERROR;
322#else
323 (void)instance;
324 osalDbgAssert(false, "mutual exclusion not enabled");
326#endif
327}
328
329#if (SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_SPI) || defined(__DOXYGEN__)
330void snor_spi_cmd_addr(BUSDriver *busp, uint32_t cmd, flash_offset_t offset) {
331#if (SNOR_SPI_4BYTES_ADDRESS == TRUE)
332 uint8_t buf[5];
333
334 buf[0] = cmd;
335 buf[1] = (uint8_t)(offset >> 24);
336 buf[2] = (uint8_t)(offset >> 16);
337 buf[3] = (uint8_t)(offset >> 8);
338 buf[4] = (uint8_t)(offset >> 0);
339 spiSend(busp, 5, buf);
340#else
341 uint8_t buf[4];
342
343 buf[0] = cmd;
344 buf[1] = (uint8_t)(offset >> 16);
345 buf[2] = (uint8_t)(offset >> 8);
346 buf[3] = (uint8_t)(offset >> 0);
347 spiSend(busp, 4, buf);
348#endif
349}
350#endif
351
352/*===========================================================================*/
353/* Driver exported functions. */
354/*===========================================================================*/
355
356#if ((SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI) && \
357 (SNOR_SHARED_BUS == TRUE)) || defined(__DOXYGEN__)
358/**
359 * @brief Bus acquisition and lock.
360 *
361 * @param[in] busp pointer to the bus driver
362 * @param[in] config bus configuration
363 *
364 * @notapi
365 */
366void bus_acquire(BUSDriver *busp, const BUSConfig *config) {
367
368 (void)config;
369
370 wspiAcquireBus(busp);
371 if (busp->config != config) {
372 wspiStart(busp, config);
373 }
374}
375
376/**
377 * @brief Bus release.
378 *
379 * @param[in] busp pointer to the bus driver
380 *
381 * @notapi
382 */
384
385 wspiReleaseBus(busp);
386}
387#endif
388
389#if (SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_SPI) && \
390 (SNOR_SHARED_BUS == TRUE)
391void bus_acquire(BUSDriver *busp, const BUSConfig *config) {
392
393 spiAcquireBus(busp);
394 if (busp->config != config) {
395 spiStart(busp, config);
396 }
397}
398
399void bus_release(BUSDriver *busp) {
400
401 spiReleaseBus(busp);
402}
403#endif
404
405/**
406 * @brief Stops the underlying bus driver.
407 *
408 * @param[in] busp pointer to the bus driver
409 *
410 * @notapi
411 */
412void bus_stop(BUSDriver *busp) {
413
414#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
415 wspiStop(busp);
416#else
417 spiStop(busp);
418#endif
419}
420
421/**
422 * @brief Sends a naked command.
423 *
424 * @param[in] busp pointer to the bus driver
425 * @param[in] cmd instruction code
426 *
427 * @notapi
428 */
429void bus_cmd(BUSDriver *busp, uint32_t cmd) {
430#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
431 wspi_command_t mode;
432
433 mode.cmd = cmd;
434 mode.cfg = SNOR_WSPI_CFG_CMD;
435 mode.addr = 0U;
436 mode.alt = 0U;
437 mode.dummy = 0U;
438 wspiCommand(busp, &mode);
439#else
440 uint8_t buf[1];
441
442 spiSelect(busp);
443 buf[0] = cmd;
444 spiSend(busp, 1, buf);
445 spiUnselect(busp);
446#endif
447}
448
449/**
450 * @brief Sends a command followed by a data transmit phase.
451 *
452 * @param[in] busp pointer to the bus driver
453 * @param[in] cmd instruction code
454 * @param[in] n number of bytes to transmit
455 * @param[in] p data buffer
456 *
457 * @notapi
458 */
459void bus_cmd_send(BUSDriver *busp, uint32_t cmd, size_t n, const uint8_t *p) {
460#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
461 wspi_command_t mode;
462
463 mode.cmd = cmd;
464 mode.cfg = SNOR_WSPI_CFG_CMD_DATA;
465 mode.addr = 0U;
466 mode.alt = 0U;
467 mode.dummy = 0U;
468 wspiSend(busp, &mode, n, p);
469#else
470 uint8_t buf[1];
471
472 spiSelect(busp);
473 buf[0] = cmd;
474 spiSend(busp, 1, buf);
475 spiSend(busp, n, p);
476 spiUnselect(busp);
477#endif
478}
479
480/**
481 * @brief Sends a command followed by a data receive phase.
482 *
483 * @param[in] busp pointer to the bus driver
484 * @param[in] cmd instruction code
485 * @param[in] n number of bytes to receive
486 * @param[out] p data buffer
487 *
488 * @notapi
489 */
491 uint32_t cmd,
492 size_t n,
493 uint8_t *p) {
494#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
495 wspi_command_t mode;
496
497 mode.cmd = cmd;
498 mode.cfg = SNOR_WSPI_CFG_CMD_DATA;
499 mode.addr = 0U;
500 mode.alt = 0U;
501 mode.dummy = 0U;
502 wspiReceive(busp, &mode, n, p);
503#else
504 uint8_t buf[1];
505
506 spiSelect(busp);
507 buf[0] = cmd;
508 spiSend(busp, 1, buf);
509 spiReceive(busp, n, p);
510 spiUnselect(busp);
511#endif
512}
513
514/**
515 * @brief Sends a command followed by a flash address.
516 *
517 * @param[in] busp pointer to the bus driver
518 * @param[in] cmd instruction code
519 * @param[in] offset flash offset
520 *
521 * @notapi
522 */
523void bus_cmd_addr(BUSDriver *busp, uint32_t cmd, flash_offset_t offset) {
524#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
525 wspi_command_t mode;
526
527 mode.cmd = cmd;
528 mode.cfg = SNOR_WSPI_CFG_CMD_ADDR;
529 mode.addr = offset;
530 mode.alt = 0U;
531 mode.dummy = 0U;
532 wspiCommand(busp, &mode);
533#else
534 spiSelect(busp);
535 snor_spi_cmd_addr(busp, cmd, offset);
536 spiUnselect(busp);
537#endif
538}
539
540/**
541 * @brief Sends a command followed by a flash address and a data transmit
542 * phase.
543 *
544 * @param[in] busp pointer to the bus driver
545 * @param[in] cmd instruction code
546 * @param[in] offset flash offset
547 * @param[in] n number of bytes to receive
548 * @param[in] p data buffer
549 *
550 * @notapi
551 */
553 uint32_t cmd,
554 flash_offset_t offset,
555 size_t n,
556 const uint8_t *p) {
557#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
558 wspi_command_t mode;
559
560 mode.cmd = cmd;
561 mode.cfg = SNOR_WSPI_CFG_CMD_ADDR_DATA;
562 mode.addr = offset;
563 mode.alt = 0U;
564 mode.dummy = 0U;
565 wspiSend(busp, &mode, n, p);
566#else
567 spiSelect(busp);
568 snor_spi_cmd_addr(busp, cmd, offset);
569 spiSend(busp, n, p);
570 spiUnselect(busp);
571#endif
572}
573
574/**
575 * @brief Sends a command followed by a flash address and a data receive
576 * phase.
577 *
578 * @param[in] busp pointer to the bus driver
579 * @param[in] cmd instruction code
580 * @param[in] offset flash offset
581 * @param[in] n number of bytes to receive
582 * @param[out] p data buffer
583 *
584 * @notapi
585 */
587 uint32_t cmd,
588 flash_offset_t offset,
589 size_t n,
590 uint8_t *p) {
591#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
592 wspi_command_t mode;
593
594 mode.cmd = cmd;
595 mode.cfg = SNOR_WSPI_CFG_CMD_ADDR_DATA;
596 mode.addr = offset;
597 mode.alt = 0U;
598 mode.dummy = 0U;
599 wspiReceive(busp, &mode, n, p);
600#else
601 spiSelect(busp);
602 snor_spi_cmd_addr(busp, cmd, offset);
603 spiReceive(busp, n, p);
604 spiUnselect(busp);
605#endif
606}
607
608/**
609 * @brief Sends a command followed by dummy cycles and a
610 * data receive phase.
611 *
612 * @param[in] busp pointer to the bus driver
613 * @param[in] cmd instruction code
614 * @param[in] dummy number of dummy cycles
615 * @param[in] n number of bytes to receive
616 * @param[out] p data buffer
617 *
618 * @notapi
619 */
621 uint32_t cmd,
622 uint32_t dummy,
623 size_t n,
624 uint8_t *p) {
625#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
626 wspi_command_t mode;
627
628 mode.cmd = cmd;
629 mode.cfg = SNOR_WSPI_CFG_CMD_DATA;
630 mode.addr = 0U;
631 mode.alt = 0U;
632 mode.dummy = dummy;
633 wspiReceive(busp, &mode, n, p);
634#else
635 uint8_t buf[1];
636
637 osalDbgAssert((dummy & 7) == 0U, "multiple of 8 dummy cycles");
638
639 spiSelect(busp);
640 buf[0] = cmd;
641 spiSend(busp, 1, buf);
642 if (dummy != 0U) {
643 spiIgnore(busp, dummy / 8U);
644 }
645 spiReceive(busp, n, p);
646 spiUnselect(busp);
647#endif
648}
649
650/**
651 * @brief Sends a command followed by a flash address, dummy cycles and a
652 * data receive phase.
653 *
654 * @param[in] busp pointer to the bus driver
655 * @param[in] cmd instruction code
656 * @param[in] offset flash offset
657 * @param[in] dummy number of dummy cycles
658 * @param[in] n number of bytes to receive
659 * @param[out] p data buffer
660 *
661 * @notapi
662 */
664 uint32_t cmd,
665 flash_offset_t offset,
666 uint32_t dummy,
667 size_t n,
668 uint8_t *p) {
669#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
670 wspi_command_t mode;
671
672 mode.cmd = cmd;
673 mode.cfg = SNOR_WSPI_CFG_CMD_ADDR_DATA;
674 mode.addr = offset;
675 mode.alt = 0U;
676 mode.dummy = dummy;
677 wspiReceive(busp, &mode, n, p);
678#else
679 osalDbgAssert((dummy & 7) == 0U, "multiple of 8 dummy cycles");
680
681 spiSelect(busp);
682 snor_spi_cmd_addr(busp, cmd, offset);
683 if (dummy != 0U) {
684 spiIgnore(busp, dummy / 8U);
685 }
686 spiReceive(busp, n, p);
687 spiUnselect(busp);
688#endif
689}
690
691/**
692 * @brief Initializes an instance.
693 *
694 * @param[out] devp pointer to the @p SNORDriver object
695 * @param[in] nocache pointer to the non-cacheable buffers
696 *
697 * @init
698 */
700
701 osalDbgCheck(devp != NULL);
702
703 devp->vmt = &snor_vmt;
704 devp->state = FLASH_STOP;
705 devp->config = NULL;
706 devp->nocache = nocache;
707#if SNOR_USE_MUTUAL_EXCLUSION == TRUE
709#endif
710}
711
712/**
713 * @brief Configures and activates SNOR driver.
714 *
715 * @param[in] devp pointer to the @p SNORDriver object
716 * @param[in] config pointer to the configuration
717 *
718 * @api
719 */
720void snorStart(SNORDriver *devp, const SNORConfig *config) {
721
722 osalDbgCheck((devp != NULL) && (config != NULL));
723 osalDbgAssert(devp->state != FLASH_UNINIT, "invalid state");
724
725 devp->config = config;
726
727 if (devp->state == FLASH_STOP) {
728
729 /* Bus acquisition.*/
730 bus_acquire(devp->config->busp, devp->config->buscfg);
731
732#if SNOR_SHARED_BUS == FALSE
733#if SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI
734 wspiStart(devp->config->busp, devp->config->buscfg);
735#elif SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_SPI
736 spiStart(devp->config->busp, devp->config->buscfg);
737#endif
738#endif
739
740 /* Device identification and initialization.*/
741 snor_device_init(devp);
742
743 /* Driver in ready state.*/
744 devp->state = FLASH_READY;
745
746 /* Bus release.*/
747 bus_release(devp->config->busp);
748 }
749}
750
751/**
752 * @brief Deactivates the SNOR driver.
753 *
754 * @param[in] devp pointer to the @p SNORDriver object
755 *
756 * @api
757 */
758void snorStop(SNORDriver *devp) {
759
760 osalDbgCheck(devp != NULL);
761 osalDbgAssert(devp->state != FLASH_UNINIT, "invalid state");
762
763 if (devp->state != FLASH_STOP) {
764
765 /* Bus acquisition.*/
766 bus_acquire(devp->config->busp, devp->config->buscfg);
767
768 /* Stopping bus device.*/
769 bus_stop(devp->config->busp);
770
771 /* Driver stopped.*/
772 devp->state = FLASH_STOP;
773
774 /* Bus release.*/
775 bus_release(devp->config->busp);
776
777 /* Deleting current configuration.*/
778 devp->config = NULL;
779 }
780}
781
782#if (SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI) || defined(__DOXYGEN__)
783#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
784/**
785 * @brief Enters the memory Mapping mode.
786 * @details The memory mapping mode is only available when the WSPI mode
787 * is selected and the underlying WSPI controller supports the
788 * feature.
789 *
790 * @param[in] devp pointer to the @p SNORDriver object
791 * @param[out] addrp pointer to the memory start address of the mapped
792 * flash or @p NULL
793 *
794 * @api
795 */
796void snorMemoryMap(SNORDriver *devp, uint8_t **addrp) {
797
798 /* Bus acquisition.*/
799 bus_acquire(devp->config->busp, devp->config->buscfg);
800
801#if SNOR_DEVICE_SUPPORTS_XIP == TRUE
802 /* Activating XIP mode in the device.*/
803 snor_activate_xip(devp);
804#endif
805
806 /* Starting WSPI memory mapped mode.*/
807 wspiMapFlash(devp->config->busp, &snor_memmap_read, addrp);
808
809 /* Bus release.*/
810 bus_release(devp->config->busp);
811}
812
813/**
814 * @brief Leaves the memory Mapping mode.
815 *
816 * @param[in] devp pointer to the @p SNORDriver object
817 *
818 * @api
819 */
821
822 /* Bus acquisition.*/
823 bus_acquire(devp->config->busp, devp->config->buscfg);
824
825 /* Stopping WSPI memory mapped mode.*/
826 wspiUnmapFlash(devp->config->busp);
827
828#if SNOR_DEVICE_SUPPORTS_XIP == TRUE
829 snor_reset_xip(devp);
830#endif
831
832 /* Bus release.*/
833 bus_release(devp->config->busp);
834}
835#endif /* WSPI_SUPPORTS_MEMMAP == TRUE */
836#endif /* SNOR_BUS_DRIVER == SNOR_BUS_DRIVER_WSPI */
837
838/** @} */
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_ERROR_UNIMPLEMENTED
Definition hal_flash.h:106
@ FLASH_NO_ERROR
Definition hal_flash.h:99
void bus_cmd(BUSDriver *busp, uint32_t cmd)
Sends a naked command.
static flash_error_t snor_start_erase_all(void *instance)
static flash_error_t snor_acquire_exclusive(void *instance)
void bus_cmd_addr_receive(BUSDriver *busp, 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.
#define BUSConfig
void bus_cmd_addr_dummy_receive(BUSDriver *busp, uint32_t cmd, flash_offset_t offset, uint32_t dummy, size_t n, uint8_t *p)
Sends a command followed by a flash address, dummy cycles and a data receive phase.
void snorStop(SNORDriver *devp)
Deactivates the SNOR driver.
#define bus_acquire(busp, config)
void snorStart(SNORDriver *devp, const SNORConfig *config)
Configures and activates SNOR driver.
void bus_cmd_send(BUSDriver *busp, uint32_t cmd, size_t n, const uint8_t *p)
Sends a command followed by a data transmit phase.
static const struct SNORDriverVMT snor_vmt
Virtual methods table.
static flash_error_t snor_start_erase_sector(void *instance, flash_sector_t sector)
#define bus_release(busp)
static flash_error_t snor_verify_erase(void *instance, flash_sector_t sector)
static flash_error_t snor_program(void *instance, flash_offset_t offset, size_t n, const uint8_t *pp)
#define BUSDriver
void bus_cmd_receive(BUSDriver *busp, uint32_t cmd, size_t n, uint8_t *p)
Sends a command followed by a data receive phase.
void snorMemoryUnmap(SNORDriver *devp)
Leaves the memory Mapping mode.
void snor_spi_cmd_addr(BUSDriver *busp, uint32_t cmd, flash_offset_t offset)
static flash_error_t snor_read(void *instance, flash_offset_t offset, size_t n, uint8_t *rp)
void bus_cmd_addr(BUSDriver *busp, uint32_t cmd, flash_offset_t offset)
Sends a command followed by a flash address.
static flash_error_t snor_query_erase(void *instance, uint32_t *msec)
void bus_cmd_addr_send(BUSDriver *busp, 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 flash_error_t snor_release_exclusive(void *instance)
void snorMemoryMap(SNORDriver *devp, uint8_t **addrp)
Enters the memory Mapping mode.
void bus_cmd_dummy_receive(BUSDriver *busp, uint32_t cmd, uint32_t dummy, size_t n, uint8_t *p)
Sends a command followed by dummy cycles and a data receive phase.
void bus_stop(BUSDriver *busp)
Stops the underlying bus driver.
static flash_error_t snor_read_sfdp(void *instance, flash_offset_t offset, size_t n, uint8_t *rp)
struct snor_nocache_buffer snor_nocache_buffer_t
static const flash_descriptor_t * snor_get_descriptor(void *instance)
Returns a pointer to the device descriptor.
void snorObjectInit(SNORDriver *devp, snor_nocache_buffer_t *nocache)
Initializes an instance.
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 wspiMapFlash(WSPIDriver *wspip, const wspi_command_t *cmdp, uint8_t **addrp)
Maps in memory space a WSPI flash device.
Definition hal_wspi.c:346
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 wspiUnmapFlash(WSPIDriver *wspip)
Unmaps from memory space a WSPI flash device.
Definition hal_wspi.c:372
void wspiStop(WSPIDriver *wspip)
Deactivates the WSPI peripheral.
Definition hal_wspi.c:131
HAL subsystem header.
Serial NOR driver header.
Type of a SNOR configuration structure.
BUSDriver * busp
const BUSConfig * buscfg
Type of SNOR flash class.
const struct SNORDriverVMT * vmt
SNORDriver Virtual Methods Table.
mutex_t mutex
Mutex protecting SNOR.
snor_nocache_buffer_t * nocache
Non-cacheable buffer associated to this instance.
_base_flash_data const SNORConfig * config
Current configuration data.
SNOR virtual methods table.
Type of a flash device descriptor.
Definition hal_flash.h:136
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