1414#include <soc.h>
1515#include <flash.h>
1616#include <string.h>
17+ #include <nrfx_nvmc.h>
1718
1819#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC )
1920#include <misc/__assert.h>
@@ -76,6 +77,7 @@ static struct k_sem sem_lock;
7677#define SYNC_LOCK ()
7778#define SYNC_UNLOCK ()
7879#endif
80+ static bool write_protect ;
7981
8082static int write (off_t addr , const void * data , size_t len );
8183static int erase (u32_t addr , u32_t size );
@@ -122,7 +124,7 @@ static inline bool is_addr_valid(off_t addr, size_t len)
122124
123125static void nvmc_wait_ready (void )
124126{
125- while (NRF_NVMC -> READY == NVMC_READY_READY_Busy ) {
127+ while (! nrfx_nvmc_write_done_check () ) {
126128 ;
127129 }
128130}
@@ -148,6 +150,10 @@ static int flash_nrf_write(struct device *dev, off_t addr,
148150{
149151 int ret ;
150152
153+ if (write_protect ) {
154+ return - EACCES ;
155+ }
156+
151157 if (!is_addr_valid (addr , len )) {
152158 return - EINVAL ;
153159 }
@@ -178,6 +184,10 @@ static int flash_nrf_erase(struct device *dev, off_t addr, size_t size)
178184 u32_t n_pages = size / pg_size ;
179185 int ret ;
180186
187+ if (write_protect ) {
188+ return - EACCES ;
189+ }
190+
181191 if (is_regular_addr_valid (addr , size )) {
182192 /* Erase can only be done per page */
183193 if (((addr % pg_size ) != 0 ) || ((size % pg_size ) != 0 )) {
@@ -215,16 +225,8 @@ static int flash_nrf_erase(struct device *dev, off_t addr, size_t size)
215225
216226static int flash_nrf_write_protection (struct device * dev , bool enable )
217227{
218- SYNC_LOCK ();
219-
220- if (enable ) {
221- NRF_NVMC -> CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos ;
222- } else {
223- NRF_NVMC -> CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos ;
224- }
225- nvmc_wait_ready ();
226-
227- SYNC_UNLOCK ();
228+ /* virtual write-erase protection */
229+ write_protect = enable ;
228230
229231 return 0 ;
230232}
@@ -264,6 +266,7 @@ static int nrf_flash_init(struct device *dev)
264266 dev_layout .pages_count = NRF_FICR -> CODESIZE ;
265267 dev_layout .pages_size = NRF_FICR -> CODEPAGESIZE ;
266268#endif
269+ write_protect = true;
267270
268271 return 0 ;
269272}
@@ -432,7 +435,6 @@ static int write_in_timeslice(off_t addr, const void *data, size_t len)
432435
433436static int erase_op (void * context )
434437{
435- u32_t prev_nvmc_cfg = NRF_NVMC -> CONFIG ;
436438 u32_t pg_size = NRF_FICR -> CODEPAGESIZE ;
437439 struct flash_context * e_ctx = context ;
438440
@@ -446,23 +448,15 @@ static int erase_op(void *context)
446448 }
447449#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
448450
449- /* Erase uses a specific configuration register */
450- NRF_NVMC -> CONFIG = NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos ;
451- nvmc_wait_ready ();
452-
453451#ifdef CONFIG_SOC_FLASH_NRF_UICR
454452 if (e_ctx -> flash_addr == (off_t )NRF_UICR ) {
455- NRF_NVMC -> ERASEUICR = 1 ;
456- nvmc_wait_ready ();
457- NRF_NVMC -> CONFIG = prev_nvmc_cfg ;
458- nvmc_wait_ready ();
453+ (void )nrfx_nvmc_uicr_erase ();
459454 return FLASH_OP_DONE ;
460455 }
461456#endif
462457
463458 do {
464- NRF_NVMC -> ERASEPAGE = e_ctx -> flash_addr ;
465- nvmc_wait_ready ();
459+ (void )nrfx_nvmc_page_erase (e_ctx -> flash_addr );
466460
467461 e_ctx -> len -= pg_size ;
468462 e_ctx -> flash_addr += pg_size ;
@@ -483,9 +477,6 @@ static int erase_op(void *context)
483477
484478 } while (e_ctx -> len > 0 );
485479
486- NRF_NVMC -> CONFIG = prev_nvmc_cfg ;
487- nvmc_wait_ready ();
488-
489480 return (e_ctx -> len > 0 ) ? FLASH_OP_ONGOING : FLASH_OP_DONE ;
490481}
491482
@@ -499,8 +490,6 @@ static void shift_write_context(u32_t shift, struct flash_context *w_ctx)
499490static int write_op (void * context )
500491{
501492 struct flash_context * w_ctx = context ;
502- u32_t addr_word ;
503- u32_t tmp_word ;
504493 u32_t count ;
505494
506495#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC )
@@ -513,23 +502,16 @@ static int write_op(void *context)
513502 }
514503#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
515504
516- /* Start with a word-aligned address and handle the offset */
517- addr_word = (u32_t )w_ctx -> flash_addr & ~0x3 ;
518-
519- /* If not aligned, read first word, update and write it back */
505+ /* If not aligned, write unaligned beginning */
520506 if (!is_aligned_32 (w_ctx -> flash_addr )) {
521- tmp_word = * (u32_t * )(addr_word );
522-
523507 count = sizeof (u32_t ) - (w_ctx -> flash_addr & 0x3 );
524508 if (count > w_ctx -> len ) {
525509 count = w_ctx -> len ;
526510 }
527511
528- memcpy ((u8_t * )& tmp_word + (w_ctx -> flash_addr & 0x3 ),
529- (void * )w_ctx -> data_addr ,
530- count );
531- nvmc_wait_ready ();
532- * (u32_t * )addr_word = tmp_word ;
512+ nrfx_nvmc_bytes_write (w_ctx -> flash_addr ,
513+ (const void * )w_ctx -> data_addr ,
514+ count );
533515
534516 shift_write_context (count , w_ctx );
535517
@@ -549,9 +531,8 @@ static int write_op(void *context)
549531
550532 /* Write all the 4-byte aligned data */
551533 while (w_ctx -> len >= sizeof (u32_t )) {
552- nvmc_wait_ready ();
553- * (u32_t * )w_ctx -> flash_addr =
554- UNALIGNED_GET ((u32_t * )w_ctx -> data_addr );
534+ nrfx_nvmc_word_write (w_ctx -> flash_addr ,
535+ UNALIGNED_GET ((u32_t * )w_ctx -> data_addr ));
555536
556537 shift_write_context (sizeof (u32_t ), w_ctx );
557538
@@ -571,12 +552,11 @@ static int write_op(void *context)
571552#endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */
572553 }
573554
574- /* Write remaining data */
555+ /* Write remaining unaligned data */
575556 if (w_ctx -> len ) {
576- tmp_word = * (u32_t * )(w_ctx -> flash_addr );
577- memcpy ((u8_t * )& tmp_word , (void * )w_ctx -> data_addr , w_ctx -> len );
578- nvmc_wait_ready ();
579- * (u32_t * )w_ctx -> flash_addr = tmp_word ;
557+ nrfx_nvmc_bytes_write (w_ctx -> flash_addr ,
558+ (const void * )w_ctx -> data_addr ,
559+ w_ctx -> len );
580560
581561 shift_write_context (w_ctx -> len , w_ctx );
582562 }
0 commit comments