aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/ext/mcux-sdk/components/mx25r_flash/mx25r_flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/components/mx25r_flash/mx25r_flash.c')
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/components/mx25r_flash/mx25r_flash.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/components/mx25r_flash/mx25r_flash.c b/lib/chibios-contrib/ext/mcux-sdk/components/mx25r_flash/mx25r_flash.c
new file mode 100644
index 000000000..f50eb1fda
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/components/mx25r_flash/mx25r_flash.c
@@ -0,0 +1,142 @@
1/*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9#include "mx25r_flash.h"
10
11#define MX25R_BYTE_ADDR1(address) ((address >> 16) & 0xf)
12#define MX25R_BYTE_ADDR2(address) ((address >> 8) & 0xf)
13#define MX25R_BYTE_ADDR3(address) (address & 0xf)
14
15/* initialize 'mx25r_instance' */
16mx25r_err_t mx25r_init(struct mx25r_instance *instance, transfer_cb_t callback, void *callback_prv)
17{
18 instance->callback = callback;
19 instance->prv = callback_prv;
20 return mx25r_err_ok;
21}
22
23/* read 'rdid' to 'result' */
24mx25r_err_t mx25r_cmd_rdid(struct mx25r_instance *instance, struct mx25r_rdid_result *result)
25{
26 instance->cmd[0] = 0x9f;
27 instance->callback(instance->prv, instance->cmd, NULL, 1, false);
28 instance->callback(instance->prv, NULL, (uint8_t *)result, sizeof(*result), true);
29 return mx25r_err_ok;
30}
31
32/* read n bytes starting at 'address' */
33mx25r_err_t mx25r_cmd_read(struct mx25r_instance *instance, uint32_t address, uint8_t *buffer, uint32_t size)
34{
35 if (address & 0xFF000000U)
36 {
37 return mx25r_err_out_of_range;
38 }
39 instance->cmd[0] = 0x03;
40 instance->cmd[1] = MX25R_BYTE_ADDR1(address);
41 instance->cmd[2] = MX25R_BYTE_ADDR2(address);
42 instance->cmd[3] = MX25R_BYTE_ADDR3(address);
43 instance->callback(instance->prv, instance->cmd, NULL, 4, false);
44 instance->callback(instance->prv, NULL, (uint8_t *)buffer, size, true);
45 return mx25r_err_ok;
46}
47
48/* no operation */
49mx25r_err_t mx25r_cmd_nop(struct mx25r_instance *instance)
50{
51 instance->callback(instance->prv, instance->cmd, NULL, 1, true);
52 return mx25r_err_ok;
53}
54
55/* read status register */
56mx25r_err_t mx25r_cmd_rdsr(struct mx25r_instance *instance, struct mx25r_rdsr_result *result)
57{
58 instance->cmd[0] = 0x05;
59 instance->callback(instance->prv, instance->cmd, NULL, 1, false);
60 instance->callback(instance->prv, NULL, (uint8_t *)result, sizeof(*result), true);
61 return mx25r_err_ok;
62}
63
64/* disable write operations */
65mx25r_err_t mx25r_cmd_wrdi(struct mx25r_instance *instance)
66{
67 instance->cmd[0] = 0x04;
68 instance->callback(instance->prv, instance->cmd, NULL, 1, true);
69 return mx25r_err_ok;
70}
71
72/* enable write operations */
73mx25r_err_t mx25r_cmd_wren(struct mx25r_instance *instance)
74{
75 instance->cmd[0] = 0x06;
76 instance->callback(instance->prv, instance->cmd, NULL, 1, true);
77 return mx25r_err_ok;
78}
79
80/* write n bytes (256 max) starting at 'address' aligned to 256 */
81mx25r_err_t mx25r_cmd_write(struct mx25r_instance *instance,
82 uint32_t address_256_align,
83 uint8_t *buffer,
84 uint32_t size_256_max)
85{
86 struct mx25r_rdsr_result result;
87 if (address_256_align & 0xFF000000U)
88 {
89 return mx25r_err_out_of_range;
90 }
91 if (address_256_align & 0xFFU)
92 {
93 return mx25r_err_alignement;
94 }
95 if (size_256_max > 256)
96 {
97 return mx25r_err_out_of_range;
98 }
99 /* enable write and wait until WEL is 1 */
100 mx25r_cmd_wren(instance);
101 do
102 {
103 mx25r_cmd_rdsr(instance, &result);
104 } while (!(result.sr0 & 0x2));
105 /* write sequence */
106 instance->cmd[0] = 0x02;
107 instance->cmd[1] = MX25R_BYTE_ADDR1(address_256_align);
108 instance->cmd[2] = MX25R_BYTE_ADDR2(address_256_align);
109 instance->cmd[3] = 0;
110 instance->callback(instance->prv, instance->cmd, NULL, 4, false);
111 instance->callback(instance->prv, (uint8_t *)buffer, NULL, size_256_max, true);
112 /* wait until WRI is 0 and WEL is 0 */
113 do
114 {
115 mx25r_cmd_rdsr(instance, &result);
116 } while (result.sr0 & 0x3);
117 return mx25r_err_ok;
118}
119
120/* erase sector at 'address' aligned to sector size = 4kB */
121mx25r_err_t mx25r_cmd_sector_erase(struct mx25r_instance *instance, uint32_t address)
122{
123 struct mx25r_rdsr_result result;
124 /* enable write and wait until WEL is 1 */
125 mx25r_cmd_wren(instance);
126 do
127 {
128 mx25r_cmd_rdsr(instance, &result);
129 } while (!(result.sr0 & 0x2));
130 /* write sequence */
131 instance->cmd[0] = 0x20;
132 instance->cmd[1] = MX25R_BYTE_ADDR1(address);
133 instance->cmd[2] = MX25R_BYTE_ADDR2(address);
134 instance->cmd[3] = MX25R_BYTE_ADDR3(address);
135 instance->callback(instance->prv, instance->cmd, NULL, 4, true);
136 /* wait until WRI is 0 and WEL is 0 */
137 do
138 {
139 mx25r_cmd_rdsr(instance, &result);
140 } while (result.sr0 & 0x3);
141 return mx25r_err_ok;
142}