diff options
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/components/flash/mflash/lpc55xxx/mflash_drv.c')
-rw-r--r-- | lib/chibios-contrib/ext/mcux-sdk/components/flash/mflash/lpc55xxx/mflash_drv.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/components/flash/mflash/lpc55xxx/mflash_drv.c b/lib/chibios-contrib/ext/mcux-sdk/components/flash/mflash/lpc55xxx/mflash_drv.c new file mode 100644 index 000000000..aefaea98e --- /dev/null +++ b/lib/chibios-contrib/ext/mcux-sdk/components/flash/mflash/lpc55xxx/mflash_drv.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * Copyright 2017-2020 NXP | ||
3 | * | ||
4 | * SPDX-License-Identifier: BSD-3-Clause | ||
5 | */ | ||
6 | |||
7 | #include <stdint.h> | ||
8 | #include <string.h> | ||
9 | |||
10 | #include "mflash_drv.h" | ||
11 | #include "fsl_iap.h" | ||
12 | #include "pin_mux.h" | ||
13 | |||
14 | static flash_config_t g_flash_instance = {0}; | ||
15 | |||
16 | static uint32_t g_pflashBlockBase = 0; | ||
17 | static uint32_t g_pflashTotalSize = 0; | ||
18 | static uint32_t g_pflashSectorSize = 0; | ||
19 | static uint32_t g_pflashPageSize = 0; | ||
20 | |||
21 | /* API - initialize 'mflash' */ | ||
22 | int32_t mflash_drv_init(void) | ||
23 | { | ||
24 | status_t result; | ||
25 | |||
26 | result = FLASH_Init(&g_flash_instance); | ||
27 | if (result != kStatus_Success) | ||
28 | return result; | ||
29 | |||
30 | result = FLASH_GetProperty(&g_flash_instance, kFLASH_PropertyPflashBlockBaseAddr, &g_pflashBlockBase); | ||
31 | if (result != kStatus_Success) | ||
32 | return result; | ||
33 | |||
34 | result = FLASH_GetProperty(&g_flash_instance, kFLASH_PropertyPflashSectorSize, &g_pflashSectorSize); | ||
35 | if (result != kStatus_Success) | ||
36 | return result; | ||
37 | |||
38 | result = FLASH_GetProperty(&g_flash_instance, kFLASH_PropertyPflashTotalSize, &g_pflashTotalSize); | ||
39 | if (result != kStatus_Success) | ||
40 | return result; | ||
41 | |||
42 | result = FLASH_GetProperty(&g_flash_instance, kFLASH_PropertyPflashPageSize, &g_pflashPageSize); | ||
43 | |||
44 | return result; | ||
45 | } | ||
46 | |||
47 | /* API - Erase single sector */ | ||
48 | int32_t mflash_drv_sector_erase(uint32_t sector_addr) | ||
49 | { | ||
50 | if (0 == mflash_drv_is_sector_aligned(sector_addr)) | ||
51 | return kStatus_InvalidArgument; | ||
52 | |||
53 | return FLASH_Erase(&g_flash_instance, sector_addr, MFLASH_SECTOR_SIZE, kFLASH_ApiEraseKey); | ||
54 | } | ||
55 | |||
56 | /* API - Page program */ | ||
57 | int32_t mflash_drv_page_program(uint32_t page_addr, uint32_t *data) | ||
58 | { | ||
59 | if (0 == mflash_drv_is_page_aligned(page_addr)) | ||
60 | return kStatus_InvalidArgument; | ||
61 | |||
62 | return FLASH_Program(&g_flash_instance, page_addr, (uint8_t *)data, MFLASH_PAGE_SIZE); | ||
63 | } | ||
64 | |||
65 | /* Internal - check FLASH status to avoid hardfault */ | ||
66 | int32_t mflash_drv_is_readable(uint32_t addr) | ||
67 | { | ||
68 | #define FLASH_READMODE_ECC_MASK (0x4U) | ||
69 | #define FLASH_READMODE_ECC_SHIFT (2U) | ||
70 | #define FLASH_READMODE_ECC(x) (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_ECC_SHIFT)) & FLASH_READMODE_ECC_MASK) | ||
71 | #define FLASH_READMODE_MARGIN_MASK (0xC00U) | ||
72 | #define FLASH_READMODE_MARGIN_SHIFT (10U) | ||
73 | #define FLASH_READMODE_MARGIN(x) \ | ||
74 | (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_MARGIN_SHIFT)) & FLASH_READMODE_MARGIN_MASK) | ||
75 | #define FLASH_READMODE_DMACC_MASK (0x8000U) | ||
76 | #define FLASH_READMODE_DMACC_SHIFT (15U) | ||
77 | #define FLASH_READMODE_DMACC(x) \ | ||
78 | (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_DMACC_SHIFT)) & FLASH_READMODE_DMACC_MASK) | ||
79 | |||
80 | uint32_t result = 0, result_mask = 0; | ||
81 | |||
82 | FLASH->INT_CLR_STATUS = FLASH_INT_CLR_STATUS_FAIL_MASK | FLASH_INT_CLR_STATUS_ERR_MASK | | ||
83 | FLASH_INT_CLR_STATUS_DONE_MASK | FLASH_INT_CLR_STATUS_ECC_ERR_MASK; | ||
84 | FLASH->STARTA = addr >> 4; | ||
85 | FLASH->DATAW[0] = FLASH_READMODE_ECC(g_flash_instance.modeConfig.readSingleWord.readWithEccOff) | | ||
86 | FLASH_READMODE_MARGIN(g_flash_instance.modeConfig.readSingleWord.readMarginLevel) | | ||
87 | FLASH_READMODE_DMACC(g_flash_instance.modeConfig.readSingleWord.readDmaccWord); | ||
88 | FLASH->CMD = 3; | ||
89 | while (!(FLASH->INT_STATUS & FLASH_INT_STATUS_DONE_MASK)) | ||
90 | ; | ||
91 | result = FLASH->INT_STATUS; | ||
92 | |||
93 | /* Report failure in case of errors */ | ||
94 | result_mask = FLASH_INT_STATUS_FAIL_MASK | FLASH_INT_STATUS_ERR_MASK | FLASH_INT_STATUS_ECC_ERR_MASK; | ||
95 | if (result_mask & result) | ||
96 | return kStatus_Fail; | ||
97 | |||
98 | return kStatus_Success; | ||
99 | } | ||
100 | |||
101 | /* API - Read data */ | ||
102 | int32_t mflash_drv_read(uint32_t addr, uint32_t *buffer, uint32_t len) | ||
103 | { | ||
104 | if (mflash_drv_is_readable(addr) != 0) | ||
105 | return kStatus_Fail; | ||
106 | |||
107 | memcpy(buffer, (void *)addr, len); | ||
108 | |||
109 | return kStatus_Success; | ||
110 | } | ||
111 | |||
112 | /* API - Get pointer to FLASH region */ | ||
113 | void *mflash_drv_phys2log(uint32_t addr, uint32_t len) | ||
114 | { | ||
115 | if (mflash_drv_is_readable(addr) != 0) | ||
116 | return NULL; | ||
117 | |||
118 | /* FLASH is directly mapped in the address space */ | ||
119 | return (void *)(addr); | ||
120 | } | ||
121 | |||
122 | /* API - Get pointer to FLASH region */ | ||
123 | uint32_t mflash_drv_log2phys(void *ptr, uint32_t len) | ||
124 | { | ||
125 | /* FLASH is directly mapped in the address space */ | ||
126 | return ((uint32_t)ptr); | ||
127 | } | ||