Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
direct_memory_logger.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  */
22 
28 #include "direct_memory_logger.h"
29 #include "mcu_periph/uart.h"
30 #include "modules/imu/imu.h"
31 #include "stabilization.h"
32 
33 struct DirectMemoryLogger dml;
34 static void direct_memory_spi_cb(struct spi_transaction *trans);
35 static int32_t seq_in_array(uint8_t *array, uint16_t array_size, uint8_t *sequence, uint16_t sequence_size);
36 
37 // Different sequences
38 static uint8_t start_log_sequence[6] = {0xAA, 0x55, 0xFF, 0x00, 0x55, 0xAA};
39 static uint8_t stop_log_sequence[6] = {0xFF, 0x00, 0x55, 0xAA, 0x10, 0xFF};
40 
41 
42 // Logging struct
43 struct LogStruct {
50 } __attribute__((packed));
51 static struct LogStruct log_struct;
52 static uint32_t dm_counter = 0;
53 
54 static int32_t seq_in_array(uint8_t *array, uint16_t array_size, uint8_t *sequence, uint16_t sequence_size)
55 {
56  uint16_t i;
57  static uint16_t current_sequence_id = 0;
58  static uint16_t count_ff = 0;
59 
60  for (i = 0; i < array_size; i++) {
61 
62  // Detect stop sequence
63  if (array[i] == sequence[current_sequence_id]) {
64  current_sequence_id++;
65  if (current_sequence_id >= sequence_size) {
66  count_ff = 0;
67  current_sequence_id = 0;
68  return i;
69  }
70  } else {
71  current_sequence_id = 0;
72  }
73 
74  // Detect ff sequence
75  if (array[i] == 0xFF) {
76  count_ff++;
77 
78  if (count_ff >= 1000) {
79  count_ff = 0;
80  current_sequence_id = 0;
81  return i;
82  }
83  } else {
84  count_ff = 0;
85  }
86  }
87 
88  return -1;
89 }
90 
92 {
94 
95  // Initialize the sst chip
96  sst25vfxxxx_init(&dml.sst, &(DM_LOG_SPI_DEV), DM_LOG_SPI_SLAVE_IDX, &direct_memory_spi_cb);
97 }
98 
100 {
101  int32_t seq_idx;
102  uint16_t i, end_idx;
103 
104  // Switch the different statusses
105  switch (dml.status) {
106  case DML_IDLE:
107  // Do nothing
108  break;
109 
110  // Stopping
111  case DML_STOP:
112  if (dml.sst.status != SST25VFXXXX_IDLE) {
113  break;
114  }
115 
116  dml.status = DML_IDLE;
119  break;
120 
121  // Logging
122  case DML_START:
123  dm_counter = 0;
125  case DML_LOGGING:
126  // Check if too slow TODO fix error
127  dm_counter++;
128  if (dml.sst.status != SST25VFXXXX_IDLE) {
129  break;
130  }
131 
132  // Set the log values
134  log_struct.accel_z = imu.accel.z;
135  log_struct.gyro_p = imu.gyro.p;
136  log_struct.gyro_q = imu.gyro.q;
137  log_struct.gyro_r = imu.gyro.r;
138  log_struct.thrust = stabilization.cmd[COMMAND_THRUST];
139 
140  sst25vfxxxx_write(&dml.sst, (uint8_t *) &log_struct, sizeof(struct LogStruct));
141  break;
142 
143  // Reading
144  case DML_READ:
146  case DML_READING:
147 
148  if (DM_LOG_UART.tx_running || dml.sst.status != SST25VFXXXX_IDLE) {
149  break;
150  }
151 
152  // Detect end sequence
153  seq_idx = seq_in_array(&(dml.buffer[5]), DML_BUF_SIZE - 5, stop_log_sequence, 6);
154  if (seq_idx < 0) {
155  end_idx = DML_BUF_SIZE;
156  } else {
157  end_idx = seq_idx + 5;
158  dml.status = DML_IDLE;
159  }
160 
161  for (i = 5; i < end_idx; i++) {
162  uart_put_byte(&DM_LOG_UART, 0, dml.buffer[i]);
163  }
164 
165  // Read next bytes
166  dml.sst.flash_addr += end_idx - 5;
167  if (seq_idx < 0) {
169  }
170  break;
171 
172  default:
173  if (dml.sst.status == SST25VFXXXX_IDLE) {
174  dml.status = DML_IDLE;
175  }
176  break;
177  }
178 }
179 
181 {
182  // First handle stopping while logging
183  if (dml.status == DML_LOGGING && val == DML_STOP) {
184  dml.status = DML_STOP;
185  return;
186  }
187 
188  // Handle only while idle
189  if (dml.status != DML_IDLE) {
190  return;
191  }
192 
193  // Handle all the statuses
194  dml.status = val;
195  switch (dml.status) {
196  case DML_ERASE:
197  dml.sst.flash_addr = 0x0;
198  dml.write_addr = 0x0;
200  break;
201  case DML_START:
204  break;
205  case DML_READ:
206  dml.sst.flash_addr = 0x0;
208  break;
209  default:
210  break;
211  }
212 }
213 
214 static void direct_memory_spi_cb(__attribute__((unused)) struct spi_transaction *trans)
215 {
217 }
static int32_t seq_in_array(uint8_t *array, uint16_t array_size, uint8_t *sequence, uint16_t sequence_size)
void direct_memory_logger_periodic(void)
static struct LogStruct log_struct
static void direct_memory_spi_cb(struct spi_transaction *trans)
void direct_memory_logger_set(uint8_t val)
static uint8_t stop_log_sequence[6]
static uint32_t dm_counter
static uint8_t start_log_sequence[6]
void direct_memory_logger_init(void)
struct DirectMemoryLogger dml
Write logs directly to flash memory chips.
#define DML_BUF_SIZE
The read buffer size.
enum DMLStatus status
The status of the Direct Memory Logger.
uint8_t buffer[DML_BUF_SIZE]
The buffer for writing and reading.
@ DML_START
The DML is starting the logger.
@ DML_STOP
The DML is busy stopping.
@ DML_INIT
The DML is initializing.
@ DML_IDLE
The DML is idle.
@ DML_ERASE
The DML is busy erasing itself.
@ DML_READ
The DML is busy starting read.
@ DML_LOGGING
The DML is busy logging.
@ DML_READING
The DML is busy reading.
struct SST25VFxxxx sst
The memory chip.
SPI transaction structure.
Definition: spi.h:148
struct Imu imu
global IMU state
Definition: imu.c:422
Inertial Measurement Unit interface.
void uart_put_byte(struct uart_periph *periph, long fd, uint8_t data)
Definition: uart_arch.c:306
int * array
void sst25vfxxxx_write(struct SST25VFxxxx *sst, uint8_t *transfer_buffer, uint8_t transfer_length)
Write bytes.
Definition: sst25vfxxxx.c:276
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.
Definition: sst25vfxxxx.c:300
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.
Definition: sst25vfxxxx.c:258
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
@ SST25VFXXXX_IDLE
The chip is idle and can be used.
Definition: sst25vfxxxx.h:54
uint32_t flash_addr
The flash address to write at.
Definition: sst25vfxxxx.h:70
enum SST25VFxxxxStatus status
The status of the SST25VFxxxx flash chip.
Definition: sst25vfxxxx.h:64
struct Stabilization stabilization
Definition: stabilization.c:41
General stabilization interface for rotorcrafts.
int32_t cmd[COMMANDS_NB]
output command vector, range from [-MAX_PPRZ:MAX_PPRZ] (store for messages)
uint16_t val[TCOUPLE_NB]
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
int int32_t
Typedef defining 32 bit int type.
Definition: vl53l1_types.h:83
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98