Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
sst25vfxxxx.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2014 Freek van Tienen <freek.v.tienen@gmail.com>
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
27#include "sst25vfxxxx.h"
28
29/* Static function defines */
30
34void sst25vfxxxx_init(struct SST25VFxxxx *sst, struct spi_periph *spi_p, const uint8_t slave_idx, SPICallback spi_cb)
35{
36 /* Set spi_peripheral and start flash address */
37 sst->spi_p = spi_p;
38 sst->flash_addr = 0x0;
39
40 /* Set the spi transaction */
42 sst->spi_t.cpha = SPICphaEdge1;
43 sst->spi_t.dss = SPIDss8bit;
45 sst->spi_t.cdiv = SPIDiv32;
46
47 sst->spi_t.input_length = 0;
48 sst->spi_t.output_length = 0;
49 sst->spi_t.input_buf = sst->input_buf;
50 sst->spi_t.output_buf = sst->output_buf;
51 sst->spi_t.slave_idx = slave_idx;
54 sst->spi_t.after_cb = spi_cb;
55
56 /* Update the status and start with enabling writing */
59}
60
65{
66 switch (sst->status) {
67 // Enabling writing to blocks
69 // When last transmit is done
70 if (sst->status_idx >= 1) {
72 break;
73 }
74
75 // Write to the status register
76 sst->status_idx = 1;
78 sst->output_buf[1] = 0x0;
79 sst->spi_t.output_length = 2;
80 sst->spi_t.input_length = 0;
81 spi_submit(sst->spi_p, &sst->spi_t);
82 break;
83
84 // Erase the full chip
86 switch (sst->status_idx) {
87 // Execute full erase command
88 case 0:
89 sst->status_idx = 1;
91 sst->spi_t.output_length = 1;
92 sst->spi_t.input_length = 0;
93 spi_submit(sst->spi_p, &sst->spi_t);
94 break;
95
96 // Wait for chip to finish
97 case 1:
98 // Disable writing when finished erasing
99 if (sst->spi_t.input_length == 2 && !(sst->input_buf[1] & 0x1)) {
100 sst->status_idx = 2;
102 sst->spi_t.output_length = 1;
103 sst->spi_t.input_length = 0;
104 spi_submit(sst->spi_p, &sst->spi_t);
105 break;
106 }
107 sst->status_idx = 1;
109 sst->spi_t.output_length = 1;
110 sst->spi_t.input_length = 2;
111 spi_submit(sst->spi_p, &sst->spi_t);
112 break;
113
114 // Goto idle
115 default:
117 break;
118 }
119 break;
120
121 // Write bytes to flash
123 switch (sst->status_idx) {
124 // Send the address with 2 or 1 byte(s) of data
125 case 0:
126 sst->status_idx = 1;
127
128 if ((sst->transfer_length - sst->transfer_idx) > 1) {
130 } else {
132 }
133 sst->output_buf[1] = (sst->flash_addr >> 16) & 0xFF;
134 sst->output_buf[2] = (sst->flash_addr >> 8) & 0xFF;
135 sst->output_buf[3] = sst->flash_addr & 0xFF;
136 sst->output_buf[4] = sst->transfer_buf[sst->transfer_idx++];
137
138 if ((sst->transfer_length - sst->transfer_idx) > 1) {
139 sst->output_buf[5] = sst->transfer_buf[sst->transfer_idx++];
140 sst->spi_t.output_length = 6;
141 } else {
142 sst->spi_t.output_length = 5;
143 }
144
145 sst->spi_t.input_length = 0;
146 spi_submit(sst->spi_p, &sst->spi_t);
147 break;
148
149 // Read the status register
150 case 1:
151 sst->status_idx = 2;
153 sst->spi_t.output_length = 1;
154 sst->spi_t.input_length = 2;
155 spi_submit(sst->spi_p, &sst->spi_t);
156 break;
157
158 // Check the status register and send new bytes if possible
159 case 2:
160 // Still busy
161 if (sst->input_buf[1] & 0x1) {
163 sst->spi_t.output_length = 1;
164 sst->spi_t.input_length = 2;
165 spi_submit(sst->spi_p, &sst->spi_t);
166 break;
167 }
168
169 // Write disabeling
170 if ((sst->transfer_length - sst->transfer_idx) <= 0) {
171 sst->status_idx = 3;
173 sst->spi_t.output_length = 1;
174 sst->spi_t.input_length = 0;
175 spi_submit(sst->spi_p, &sst->spi_t);
176 break;
177 }
178
179 // Transfer new bytes
180 sst->status_idx = 1;
182 sst->output_buf[1] = sst->transfer_buf[sst->transfer_idx++];
183
184 if ((sst->transfer_length - sst->transfer_idx) <= 0) {
185 sst->output_buf[2] = sst->transfer_buf[sst->transfer_idx++]; //FIXME: uneven packets!!!!!
186 } else {
187 sst->output_buf[2] = 0x0;
188 }
189
190 sst->spi_t.output_length = 3;
191 sst->spi_t.input_length = 0;
192 spi_submit(sst->spi_p, &sst->spi_t);
193 break;
194
195 // Goto idle and update the flash address
196 default:
197 sst->flash_addr += sst->transfer_length;
199 break;
200 }
201 break;
202
203 // Read bytes from flash memory
205 // Reset the buffer pointer and goto idle
206 sst->spi_t.input_buf = sst->input_buf;
208 break;
209
210 // Default goto idle
211 default:
213 break;
214 }
215}
216
221{
222 if (sst->status != SST25VFXXXX_IDLE) {
223 return;
224 }
225
226 // Write the read id command to the chip
229 sst->output_buf[1] = 0x0;
230 sst->output_buf[2] = 0x0;
231 sst->output_buf[3] = 0x0; //READ the MFG ID first
232 sst->spi_t.output_length = 4;
233 sst->spi_t.input_length = 8;
234 spi_submit(sst->spi_p, &sst->spi_t);
235}
236
241{
242 if (sst->status != SST25VFXXXX_IDLE) {
243 return;
244 }
245
246 // Enable writing to the status register
248 sst->status_idx = 0;
250 sst->spi_t.output_length = 1;
251 sst->spi_t.input_length = 0;
252 spi_submit(sst->spi_p, &sst->spi_t);
253}
254
259{
260 if (sst->status != SST25VFXXXX_IDLE) {
261 return;
262 }
263
264 // Enable writing
266 sst->status_idx = 0;
268 sst->spi_t.output_length = 1;
269 sst->spi_t.input_length = 0;
270 spi_submit(sst->spi_p, &sst->spi_t);
271}
272
276void sst25vfxxxx_write(struct SST25VFxxxx *sst, uint8_t *transfer_buffer, uint8_t transfer_length)
277{
278 if (sst->status != SST25VFXXXX_IDLE) {
279 return;
280 }
281
282 // Set the transfer buffer
283 sst->transfer_buf = transfer_buffer; // Not copied so keep buffer available!
284 sst->transfer_idx = 0;
285 sst->transfer_length = transfer_length;
286
287 // Enable writing
289 sst->status_idx = 0;
291 sst->spi_t.output_length = 1;
292 sst->spi_t.input_length = 0;
293 spi_submit(sst->spi_p, &sst->spi_t);
294}
295
300void sst25vfxxxx_read(struct SST25VFxxxx *sst, uint8_t *transfer_buffer, uint8_t transfer_length)
301{
302 if (sst->status != SST25VFXXXX_IDLE) {
303 return;
304 }
305
306 // Read all bytes at once
308 sst->status_idx = 0;
310 sst->output_buf[1] = (sst->flash_addr >> 16) & 0xFF;
311 sst->output_buf[2] = (sst->flash_addr >> 8) & 0xFF;
312 sst->output_buf[3] = sst->flash_addr & 0xFF;
313 sst->output_buf[4] = 0x0;
314 sst->spi_t.output_length = 5;
315 sst->spi_t.input_buf = transfer_buffer; // Need to reset this afterwards
316 sst->spi_t.input_length = transfer_length + 5;
317 spi_submit(sst->spi_p, &sst->spi_t);
318}
enum SPIClockPolarity cpol
clock polarity control
Definition spi.h:155
enum SPIClockPhase cpha
clock phase control
Definition spi.h:156
enum SPISlaveSelect select
slave selection behavior
Definition spi.h:154
SPICallback after_cb
NULL or function called after the transaction.
Definition spi.h:161
enum SPIDataSizeSelect dss
data transfer word size
Definition spi.h:157
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition spi.h:150
uint16_t input_length
number of data words to read
Definition spi.h:151
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition spi.h:159
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition spi.h:149
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition spi.h:153
enum SPIBitOrder bitorder
MSB/LSB order.
Definition spi.h:158
uint16_t output_length
number of data words to write
Definition spi.h:152
enum SPITransactionStatus status
Definition spi.h:162
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition spi_arch.c:533
void(* SPICallback)(struct spi_transaction *trans)
SPI Callback function.
Definition spi.h:136
@ SPICphaEdge1
CPHA = 0.
Definition spi.h:74
@ SPITransDone
Definition spi.h:101
@ SPICpolIdleLow
CPOL = 0.
Definition spi.h:83
@ SPISelectUnselect
slave is selected before transaction and unselected after
Definition spi.h:63
@ SPIMSBFirst
Definition spi.h:112
@ SPIDiv32
Definition spi.h:124
@ SPIDss8bit
Definition spi.h:90
SPI peripheral structure.
Definition spi.h:174
uint16_t foo
Definition main_demo5.c:58
void sst25vfxxxx_write(struct SST25VFxxxx *sst, uint8_t *transfer_buffer, uint8_t transfer_length)
Write bytes.
void sst25vfxxxx_block_write_en(struct SST25VFxxxx *sst)
Enable block writing.
void sst25vfxxxx_read_id(struct SST25VFxxxx *sst)
Read the chip identifier.
void sst25vfxxxx_read(struct SST25VFxxxx *sst, uint8_t *transfer_buffer, uint8_t transfer_length)
Read bytes Need 5 more extra bytes because of SPI overhead.
void sst25vfxxxx_init(struct SST25VFxxxx *sst, struct spi_periph *spi_p, const uint8_t slave_idx, SPICallback spi_cb)
Initializing the sst25vfxxxx chip.
Definition sst25vfxxxx.c:34
void sst25vfxxxx_chip_erase(struct SST25VFxxxx *sst)
Full chip erase.
void sst25vfxxxx_after_cb(struct SST25VFxxxx *sst)
Callback of the SPI after going one level higher for gathering the sst pointer.
Definition sst25vfxxxx.c:64
Driver for the SST25Vxxxx flash chips.
@ SST25VFXXXX_READ_ID
The chip is busy with getting the chip ID.
Definition sst25vfxxxx.h:55
@ SST25VFXXXX_READ_BYTES
The chip is busy reading bytes.
Definition sst25vfxxxx.h:59
@ SST25VFXXXX_WRITE_BYTES
The chip is busy writing bytes.
Definition sst25vfxxxx.h:58
@ SST25VFXXXX_CHIP_ERASE
The chip is busy erasing itself.
Definition sst25vfxxxx.h:57
@ SST25VFXXXX_IDLE
The chip is idle and can be used.
Definition sst25vfxxxx.h:54
@ SST25VFXXXX_WRITE_EN
The chip is busy enabeling writing to blocks.
Definition sst25vfxxxx.h:56
uint8_t transfer_idx
The transfer idx is used for counting input/output bytes.
Definition sst25vfxxxx.h:73
#define SST25VFXXXX_AAI_PROG
Definition sst25vfxxxx.h:40
#define SST25VFXXXX_RDID
Definition sst25vfxxxx.h:46
uint32_t flash_addr
The flash address to write at.
Definition sst25vfxxxx.h:70
uint8_t output_buf[16]
The output buffer for the SPI transaction.
Definition sst25vfxxxx.h:69
#define SST25VFXXXX_HGIH_SPEAD_READ
Definition sst25vfxxxx.h:34
#define SST25VFXXXX_WRSR
Definition sst25vfxxxx.h:43
struct spi_transaction spi_t
The SPI transaction used for the writing and reading of registers.
Definition sst25vfxxxx.h:67
uint8_t transfer_length
The transfer buffer length.
Definition sst25vfxxxx.h:74
#define SST25VFXXXX_WRDI
Definition sst25vfxxxx.h:45
uint8_t * transfer_buf
The transfer buffer.
Definition sst25vfxxxx.h:72
uint8_t input_buf[16]
The input buffer for the SPI transaction.
Definition sst25vfxxxx.h:68
#define SST25VFXXXX_EWSR
Definition sst25vfxxxx.h:42
#define SST25VFXXXX_WREN
Definition sst25vfxxxx.h:44
#define SST25VFXXXX_ERASE_CHIP
Definition sst25vfxxxx.h:38
uint8_t status_idx
The counter of substatuses.
Definition sst25vfxxxx.h:65
enum SST25VFxxxxStatus status
The status of the SST25VFxxxx flash chip.
Definition sst25vfxxxx.h:64
#define SST25VFXXXX_BYTE_PROG
Definition sst25vfxxxx.h:39
struct spi_periph * spi_p
The SPI peripheral for the connection.
Definition sst25vfxxxx.h:66
#define SST25VFXXXX_RDSR
Definition sst25vfxxxx.h:41
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.