Paparazzi UAS  v5.8.2_stable-0-g6260b7c
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
sdlogger_spi_direct.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) Bart Slinger
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, see
18  * <http://www.gnu.org/licenses/>.
19  */
30 #define PERIODIC_C_LOGGER
31 
36 #include "led.h"
37 
38 #ifdef LOGGER_LED
39 #define LOGGER_LED_ON LED_ON(LOGGER_LED);
40 #define LOGGER_LED_OFF LED_OFF(LOGGER_LED);
41 #else
42 #define LOGGER_LED_ON {}
43 #define LOGGER_LED_OFF {}
44 #endif
45 
46 #ifndef TELEMETRY_MODE_Main_empty
47 #warning You need to define a main telemetry mode named "empty" without any \
48  messages in your config file in /conf/telemetry/<your_config.xml>. \
49  \
50  Add <mode name="empty"></mode> to your main telemetry process.
51 #endif
52 
53 #ifndef TELEMETRY_PROCESS_Logger
54 #error "You need to use a telemetry xml file with Logger process!"
55 #endif
56 
57 #ifndef DOWNLINK_DEVICE
58 #warning This module can only be used with uart downlink for now.
59 #endif
60 
62 
68 {
69  /* Initialize the SD Card */
70  sdcard_spi_init(&sdcard1, &(SDLOGGER_SPI_LINK_DEVICE),
71  SDLOGGER_SPI_LINK_SLAVE_NUMBER);
72 
73  /* Set values in the struct to their defaults */
78 
79  /* Fill internal buffer with zeros */
80  for (uint8_t i = 0; i < sizeof(sdlogger_spi.buffer); i++) {
81  sdlogger_spi.buffer[i] = 0;
82  }
83  sdlogger_spi.idx = 0;
89 
90  /* Set function pointers in link_device to the logger functions */
97 
98  /* Init pprzlog_tp */
100 }
101 
107 {
109 
110  switch (sdlogger_spi.status) {
112  if (sdcard1.status == SDCard_Idle) {
115  }
116  break;
117 
118  case SDLogger_Ready:
119  if (radio_control.values[SDLOGGER_CONTROL_SWITCH] > 0 &&
124  }
125  break;
126 
127  case SDLogger_Logging:
128  /* This line is NOT unit-tested because it is an inline function */
129  #if PERIODIC_TELEMETRY
130  periodic_telemetry_send_Logger(DefaultPeriodic,
133  #endif
134  /* Check if SD Card buffer is full and SD Card is ready for new data */
135  if (sdlogger_spi.sdcard_buf_idx > 512 &&
138  }
139  /* Check if switch is flipped to stop logging */
140  if (radio_control.values[SDLOGGER_CONTROL_SWITCH] < 0) {
142  }
143  break;
144 
147  if (sdlogger_spi.sdcard_buf_idx > 512) {
149  }
150  else if (sdlogger_spi.sdcard_buf_idx > 1) {
151  /* Fill with trailing zero's */
152  for (uint16_t i = sdlogger_spi.sdcard_buf_idx; i < (SD_BLOCK_SIZE+1); i++) {
153  sdcard1.output_buf[i] = 0x00;
154  }
156  }
157  else if (sdlogger_spi.sdcard_buf_idx == 1) {
160  }
161  }
162  break;
163 
165  if (sdcard1.status == SDCard_Idle) {
168  }
169  break;
170 
172  if (sdcard1.status == SDCard_Idle) {
175  }
176  break;
177 
179  if (sdcard1.status == SDCard_Idle) {
180  /* Put bytes to the buffer until all is written or buffer is full */
181  for (uint16_t i = sdlogger_spi.sdcard_buf_idx; i < SD_BLOCK_SIZE; i++) {
184  }
185  else {
186  /* No free space left, abort for-loop */
187  break;
188  }
190  }
191  /* Request next block if entire buffer was written to uart */
193  if (sdlogger_spi.download_length > 0) {
197  }
198  else {
201  }
203  }
204  }
205  break;
206 
207  default:
208  break;
209  }
210 }
211 
214 
220 {
221 
222  switch (sdlogger_spi.status) {
226  /* Save data for later use
227  sdlogger_spi.next_available_address = (sdcard1.input_buf[0] << 24) |
228  (sdcard1.input_buf[1] << 16) |
229  (sdcard1.input_buf[2] << 8) |
230  (sdcard1.input_buf[3]);
231  sdlogger_spi.last_completed = sdcard1.input_buf[4];
232  */
233 
234  /* Ready to start logging */
236  break;
237 
239  /* Copy input buffer to output buffer */
240  for (uint16_t i = 0; i < SD_BLOCK_SIZE; i++) {
242  }
243 
244  /* Increment last completed log */
246  /* Write log info at dedicated location */
247  {
248  uint16_t log_idx_start = 5 + 6 + (sdlogger_spi.last_completed - 1) * 12;
249 
250  /* Set start address and length at location that belongs to the log nr */
251  sdcard1.output_buf[log_idx_start+0] = sdlogger_spi.next_available_address >> 24;
252  sdcard1.output_buf[log_idx_start+1] = sdlogger_spi.next_available_address >> 16;
253  sdcard1.output_buf[log_idx_start+2] = sdlogger_spi.next_available_address >> 8;
254  sdcard1.output_buf[log_idx_start+3] = sdlogger_spi.next_available_address >> 0;
255  sdcard1.output_buf[log_idx_start+4] = sdlogger_spi.log_len >> 24;
256  sdcard1.output_buf[log_idx_start+5] = sdlogger_spi.log_len >> 16;
257  sdcard1.output_buf[log_idx_start+6] = sdlogger_spi.log_len >> 8;
258  sdcard1.output_buf[log_idx_start+7] = sdlogger_spi.log_len >> 0;
259  }
260 
261  /* Increment and update the next available address */
267 
268  sdcard_spi_write_block(&sdcard1, 0x00002000);
269  /* Reset log length */
270  sdlogger_spi.log_len = 0;
272  break;
273 
275  {
276  uint16_t info_idx = 5 + (sdlogger_spi.download_id - 1) * 12;
277  sdlogger_spi.download_address = (sdcard1.input_buf[info_idx+0] << 24) |
278  (sdcard1.input_buf[info_idx+1] << 16) |
279  (sdcard1.input_buf[info_idx+2] << 8) |
280  (sdcard1.input_buf[info_idx+3] << 0);
281  sdlogger_spi.download_length = (sdcard1.input_buf[info_idx+4] << 24) |
282  (sdcard1.input_buf[info_idx+5] << 16) |
283  (sdcard1.input_buf[info_idx+6] << 8) |
284  (sdcard1.input_buf[info_idx+7] << 0);
285  if (sdlogger_spi.download_length > 0) {
286  /* Request the first block */
288  /* After each read block, incr address, decr length */
292  }
293  else {
296  }
298  }
299  break;
300 
301  default:
302  break;
303  }
304 
305 }
306 
313 {
314  /* Increment log length */
316 
317  /* Copy data from logger buffer to SD Card buffer */
318  for (uint8_t i = 0; i < sdlogger_spi.idx; i++) {
320  }
321  /* Set sdcard buffer index to new value */
323  /* And reset the logger buffer index */
324  sdlogger_spi.idx = 0;
325 }
326 
328 {
330  sdlogger_spi.command < 43) {
332  sdcard_spi_read_block(&sdcard1, 0x00002000,
336  }
337  else if (sdcard1.status == SDCard_Idle && sdlogger_spi.command == 255) {
338  telemetry_mode_Main = TELEMETRY_MODE_Main_empty;
340  sdcard_spi_read_block(&sdcard1, 0x00002000, NULL);
344  }
345  /* Always reset command value back to zero */
346  sdlogger_spi.command = 0;
347 }
348 
350 {
351  if (p->status == SDLogger_Logging) {
352  /* Calculating free space in both buffers */
353  if ( (513 - p->sdcard_buf_idx) + (SDLOGGER_BUFFER_SIZE - p->idx) >= len) {
354  return TRUE;
355  }
356  }
357  return FALSE;
358 }
359 
361 {
362  /* SD Buffer full, write in logger buffer */
363  if (p->sdcard_buf_idx > 512) {
364  if (p->idx < SDLOGGER_BUFFER_SIZE) {
365  p->buffer[p->idx++] = data;
366  }
367  /* else: data lost */
368  }
369  /* Writing directly to SD Card buffer */
370  else {
371  sdcard1.output_buf[p->sdcard_buf_idx++] = data;
372 
373  /* Flush buffer */
374  if (p->sdcard_buf_idx > 512 && sdcard1.status == SDCard_MultiWriteIdle) {
376  }
377  }
378 }
379 
381 {
382  (void) p;
383 }
384 
386  (void) p;
387  return 0;
388 }
389 
391 {
392  (void) p;
393  return 0;
394 }
395 
396 
397 
enum SDLoggerStatus status
unsigned short uint16_t
Definition: types.h:16
Initialization sequence succesful.
Definition: sdcard_spi.h:58
uint8_t buffer[SDLOGGER_BUFFER_SIZE]
struct link_device device
uint8_t input_buf[SD_BLOCK_SIZE+10]
The input buffer for the SPI transaction.
Definition: sdcard_spi.h:113
uint8_t sdlogger_spi_direct_get_byte(void *p)
#define DOWNLINK_DEVICE
void sdcard_spi_write_block(struct SDCard *sdcard, uint32_t addr)
Write a single block (512 bytes) to the SDCard at a given address.
Definition: sdcard_spi.c:560
Periodic telemetry system header (includes downlink utility and generated code).
void sdlogger_spi_direct_init(void)
sdlogger_spi_direct_init Initialize the logger and SD Card.
int sdlogger_spi_direct_char_available(void *p)
enum SDCardStatus status
The status of the SD card.
Definition: sdcard_spi.h:112
void sdcard_spi_init(struct SDCard *sdcard, struct spi_periph *spi_p, const uint8_t slave_idx)
Configure initial values for SDCard.
Definition: sdcard_spi.c:74
void sdcard_spi_read_block(struct SDCard *sdcard, uint32_t addr, SDCardCallback callback)
Read a single block (512 bytes) from the SDCard at a given address.
Definition: sdcard_spi.c:587
uint8_t output_buf[SD_BLOCK_SIZE+10]
The output buffer for the SPI transaction.
Definition: sdcard_spi.h:114
pprz_t values[RADIO_CONTROL_NB_CHANNEL]
Definition: radio_control.h:58
#define SDLOGGER_BUFFER_SIZE
void sdcard_spi_multiwrite_stop(struct SDCard *sdcard)
Stop with multiwrite procedure.
Definition: sdcard_spi.c:666
void sdcard_spi_multiwrite_next(struct SDCard *sdcard, SDCardCallback callback)
Write a(nother) data block (512 bytes) to the SDCard.
Definition: sdcard_spi.c:638
void sdlogger_spi_direct_stop(void)
void sdcard_spi_periodic(struct SDCard *sdcard)
Periodic function of the SDCard.
Definition: sdcard_spi.c:99
#define FALSE
Definition: std.h:5
void sdlogger_spi_direct_send_message(void *p)
#define LOGGER_LED_OFF
#define TRUE
Definition: std.h:4
struct sdlogger_spi_periph sdlogger_spi
#define SD_BLOCK_SIZE
Definition: sdcard_spi.h:38
void pprzlog_transport_init(void)
struct pprzlog_transport pprzlog_tp
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
bool_t sdlogger_spi_direct_check_free_space(struct sdlogger_spi_periph *p, uint8_t len)
struct RadioControl radio_control
Definition: radio_control.c:30
void sdlogger_spi_direct_multiwrite_written(void)
sdlogger_spi_direct_multiwrite_written Called when a multiwrite is complete.
void sdcard_spi_multiwrite_start(struct SDCard *sdcard, uint32_t addr)
Start writing multiple blocks of 512 bytes to the SDCard.
Definition: sdcard_spi.c:616
bool_t uart_check_free_space(struct uart_periph *p, uint8_t len)
Definition: uart.c:256
void sdlogger_spi_direct_periodic(void)
sdlogger_spi_direct_periodic Periodic function called at module frequency
Protocol for on-board data logger with timestamp.
void sdlogger_spi_direct_start(void)
struct SDCard sdcard1
This is the definition of the SD card.
Definition: sdcard_spi.c:56
unsigned char uint8_t
Definition: types.h:14
void sdlogger_spi_direct_index_received(void)
sdlogger_spi_direct_index_received Callback from SD Card when block at index location is received...
void sdlogger_spi_direct_put_byte(struct sdlogger_spi_periph *p, uint8_t data)
void sdlogger_spi_direct_command(void)
arch independent LED (Light Emitting Diodes) API
static float p[2][2]
#define LOGGER_LED_ON
CMD25 complete, ready to sent blocks.
Definition: sdcard_spi.h:84
struct transport_tx trans_tx
void uart_put_byte(struct uart_periph *periph, uint8_t data)
Definition: uart_arch.c:243