summaryrefslogtreecommitdiffhomepage
path: root/digital/avr/modules/flash/flash.c
blob: dd1bfd4144478ec0ad45691d91d9443f80a78e22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/* flash.c */
/* avr.flash - AVR Flash SPI use. {{{
 *
 * Copyright (C) 2009 Nélio Laranjeiro
 *
 * APBTeam:
 *        Web: http://apbteam.org/
 *      Email: team AT apbteam DOT org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * }}} */
#include "flash.h"
#include "flash_sst.h"
#include "flash_at.h"
#include "modules/proto/proto.h"

/** Erase the memory.
  * \param  erase_type  the erase type..
  * \param  start_addr  the start address.
  */
typedef void
(*flash_erase_t) (flash_erase_cmd_t cmd, uint32_t start_addr);

/* Send a flash command to the flash memory (only a command).
 * \param  cmd  the command to send.
 */
typedef void
(*flash_send_command_t) (flash_cmd_t cmd);

/** Read the busy bit in the Software Status Register of the flash memory.
  * \return  the status register.
  */
typedef uint8_t
(*flash_read_status_t) (void);

/** Read the busy bit in the Software Status Register of the flash memory.
  * \return  the busy bit state.
  */
typedef uint8_t
(*flash_is_busy_t) (void);

/** Write in the flash byte provided in parameter.
  * \param  data  the buffer to store the data.
  */
typedef void
(*flash_write_t) (uint32_t addr, uint8_t data);

/** Read the data at the address provided.
  * \param  addr  the address of the data to read.
  * \return  the data read.
  */
typedef uint8_t
(*flash_read_t) (uint32_t addr);

/** Read a data from the flash memory from the address provided and for a
 * length of the number of bytes provided.
 * \param  address at which the data should be read.
 * \param  buffer  the buffer to fill with the read data.
 * \param  length  the length of the data to read.
 */
typedef void
(*flash_read_array_t) (uint32_t addr, uint8_t *buffer, uint32_t length);

/** Write in the flash byte provided in parameter.
  * \param  addr  the address to store the data.
  * \param  data  the array to store.
  * \param  length  the array length
  */
typedef void
(*flash_write_array_t) (uint32_t addr, uint8_t *data, uint32_t length);

/** Get the flash size.
  * \return  the flash size.
  */
typedef uint32_t
(*flash_size_t) (void);

/** Get the flash block size.
  * \return  the flash block size.
  */
typedef uint32_t
(*flash_block_size_t) (void);

struct flash_t
{
    /** Erase function. */
    flash_erase_t erase_func;
    /** Send command function. */
    flash_send_command_t send_cmd_func;
    /** Read status function. */
    flash_read_status_t read_status_func;
    /** Is busy function. */
    flash_is_busy_t is_busy_func;
    /** Write function. */
    flash_write_t write_func;
    /** Read function. */
    flash_read_t read_func;
    /** Read array function. */
    flash_read_array_t read_array_func;
    /** Write array function. */
    flash_write_array_t write_array_func;
    /** Flash size function. */
    flash_size_t flash_size_func;
    /** Flash block size function. */
    flash_block_size_t flash_block_size_func;
};
typedef struct flash_t flash_t;

/** Static variable. */
static flash_t flash;

void
flash_erase (flash_erase_cmd_t cmd, uint32_t start_addr)
{
    flash.erase_func (cmd, start_addr);
}

void
flash_send_command (flash_cmd_t cmd)
{
    flash.send_cmd_func (cmd);
}

uint8_t
flash_read_status (void)
{
    return flash.read_status_func ();
}

uint8_t
flash_is_busy (void)
{
    return flash.is_busy_func ();
}

void
flash_write (uint32_t addr, uint8_t data)
{
    flash.write_func (addr, data);
}

uint8_t
flash_read (uint32_t addr)
{
    return flash.read_func (addr);
}

void
flash_read_array (uint32_t addr, uint8_t *buffer, uint32_t length)
{
    flash.read_array_func (addr, buffer, length);
}

void
flash_write_array (uint32_t addr, uint8_t *data, uint32_t length)
{
    flash.write_array_func (addr, data, length);
}

int8_t
flash_log (uint8_t size, uint8_t *args)
{
    uint8_t buf[FLASH_LOG_BUFFER_SIZE+1];
    int8_t error = 0x0;
    uint32_t addr = 0;

    if (size >= 4)
	addr = (((uint32_t) args[1]) << 16)
	    | (((uint32_t) args[2]) << 8) | args[3];

    switch (args[0])
      {
      case FLASH_CMD_INIT:
	error = !flash_init ();
	proto_send1b ('s', error ? 0 : 1);
	break;
      case FLASH_CMD_READ:
	if ((size == 5)
	    && (args[4] <= sizeof(buf)))
	  {
	    flash_read_array (addr, buf, args[4]);
	    proto_send4b ('a', 0, addr >> 16, addr >> 8, addr);
	    proto_send ('r', args[4], buf);
	  }
      case FLASH_CMD_READ_BYTE:
	if (size == 4)
	  {
	    proto_send1b ('r', flash_read (addr));
	  }
	break;
      case FLASH_CMD_WRITE_BYTE:
	if (size == 5)
	  {
	    proto_send1b ('w', args[4]);
	    flash_write (addr, args[4]);
	  }
	break;
      case FLASH_CMD_WRITE:
	if ((size == 5)
	    && (args[4] <= sizeof(buf)))
	  {
	    flash_write_array (addr, buf, args[4]);
	    proto_send ('w', args[4], buf);
	  }
	break;
      }

    return error;
}

uint32_t
flash_size (void)
{
    return flash.flash_size_func ();
}

uint32_t
flash_block_size (void)
{
    return flash.flash_block_size_func ();
}

void
flash_init_sst (void)
{
    FLASH_DRV_INIT (sst);
}

void
flash_init_at (void)
{
    FLASH_DRV_INIT (at);
}