Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
high_speed_logger_direct_memory.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Clement Roblot
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  */
20 
29 
30 #include <string.h>
31 
32 #include "modules/imu/imu.h"
33 #include "mcu_periph/spi.h"
34 #include "mcu_periph/uart.h"
35 
38 
39 
40 /******************************************************************/
41 /* */
42 /* Config values, go crazy */
43 /* */
44 /******************************************************************/
46 #define READING_BLOCK_SIZE 200
48 #define ERASE_MEMORY_AT_START 0
50 #define SIZE_OF_LOGGED_VALUES 4
52 #define SIZE_OF_VALUES_NAMES 10
53 
58 #define SKIP_X_CALLS_BETWEEN_VALUES 0
59 
61 #define NBR_VALUES_TO_LOG 9
62 
65 
67  //That list must be pointers to the variables
68  //you want to log
69 
70  (uint32_t) &imu.accel_unscaled.x,
71  (uint32_t) &imu.accel_unscaled.y,
72  (uint32_t) &imu.accel_unscaled.z,
73 
74  (uint32_t) &imu.gyro_unscaled.p,
75  (uint32_t) &imu.gyro_unscaled.q,
76  (uint32_t) &imu.gyro_unscaled.r,
77 
78  (uint32_t) &imu.mag_unscaled.x,
79  (uint32_t) &imu.mag_unscaled.y,
80  (uint32_t) &imu.mag_unscaled.z
81 };
82 
83 
84 
87 {
88  "acc x",
89  "acc y",
90  "acc z",
91  "gyro p",
92  "gyro q",
93  "gyro r",
94  "mag x",
95  "mag y",
96  "mag z"
97 };
98 
99 
100 
101 /******************************************************************/
102 /* */
103 /* Fixed values, do not touch */
104 /* */
105 /******************************************************************/
107 #define MEMORY_READ_LATTENCY 5
109 #define TOTAL_MEMORY_SIZE 32
111 #define END_OF_MEMORY_THRESHOLD 10
112 
113 
114 //log start-start_of_values-end flags
116 uint8_t start_log_sequence[6] = {0xAA, 0x55, 0xFF, 0x00, 0x55, 0xAA};
118 uint8_t start_values_sequence[3] = {0xF0, 0xF0, 0xA5};
120 uint8_t start_lost_values_sequence[6] = {0x42, 0x0F, 0X42, 0X00, 0XFF, 0xAA};
122 uint8_t stop_lost_values_sequence[6] = {0xAA, 0xFF, 0x00, 0x42, 0x0F, 0x42};
123 
124 
126 uint8_t stop_log_sequence[6] = {0xFF, 0x00, 0x55, 0xAA, 0x00, 0xFF};
127 
128 //low level buffers used to communicate over SPI
130 uint8_t buff[25]; //25 is enough even for the reading of the ID (24 values)
137 
138 //local buffer used to log values
149 
150 //local status flags
161 
162 
163 //memory management variables
171 static volatile bool memory_ready = true;
178 
179 
182 
183 
184 
185 static void memory_transaction_done_cb(struct spi_transaction *trans);
186 static void memory_read_status_cb(struct spi_transaction *trans);
187 static void memory_read_values_cb(struct spi_transaction *trans);
188 
189 
190 /******************************************************************/
191 /* */
192 /* Low level function, directly acting with the SPI */
193 /* */
194 /******************************************************************/
195 
200 void memory_read_id(void)
201 {
202 
203  memory_ready = false;
204  msg[0] = 0x9F;
205 
208 
211 
213 
214  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
215 }
216 
221 {
222  memory_ready = false;
223  msg[0] = 0x06;
224 
227 
230 
232 
233  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
234 }
235 
240 {
241  memory_ready = false;
242  msg[0] = 0x04;
243 
246 
249 
251 
252  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
253 }
254 
259 {
260  memory_ready = false;
261  msg[0] = 0x05;
262 
265 
268 
270 
271  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
272 }
273 
279 static void memory_read_status_cb(struct spi_transaction *trans __attribute__((unused)))
280 {
281 
282  memory_ready = true;
283 
286 }
287 
293 void memory_erase_4k(uint32_t mem_addr)
294 {
295 
296  uint8_t *addr = (uint8_t *) &mem_addr;
297 
298  memory_ready = false;
299  msg[0] = 0x21;
300  msg[1] = addr[3];
301  msg[2] = addr[2];
302  msg[3] = addr[1];
303  msg[4] = addr[0];
304 
307 
310 
312 
313  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
314 }
315 
320 {
321 
322  memory_ready = false;
323  msg[0] = 0xC7;
324 
327 
330 
332 
333  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
334 }
335 
343 void memory_write_values(uint32_t mem_addr, uint8_t *values, uint8_t size)
344 {
345 
346  uint8_t *addr = (uint8_t *) &mem_addr;
347  uint8_t i;
348 
349  memory_ready = false;
350  values_send_buffer[0] = 0x12;
351  values_send_buffer[1] = addr[3];
352  values_send_buffer[2] = addr[2];
353  values_send_buffer[3] = addr[1];
354  values_send_buffer[4] = addr[0];
355 
356  for (i = 0; i < size; i++) {
357  values_send_buffer[i + 5] = values[i];
358  }
359 
362 
365 
367 
368  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_send_value_transaction);
369 }
370 
377 void memory_read_values(uint32_t mem_addr, uint8_t size)
378 {
379 
380  uint8_t *addr = (uint8_t *) &mem_addr;
381 
382  memory_ready = false;
383  msg[0] = 0x13;
384  msg[1] = addr[3];
385  msg[2] = addr[2];
386  msg[3] = addr[1];
387  msg[4] = addr[0];
388 
391 
394  MEMORY_READ_LATTENCY; //the first MEMORY_READ_LATTENCY Bytes are lost because of reading to soon
395 
397 
398  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
399 }
400 
406 static void memory_read_values_cb(struct spi_transaction *trans __attribute__((unused)))
407 {
408 
410 
411  memory_ready = true;
412 
413  if (msg_size) {
414 
415  if (is_sequence_in_array(uart_read_buff, msg_size, stop_log_sequence, 6)) { //this is the end of the log
416 
419 
420  } else { //this is not the end of the log
421 
423  }
424 
427  }
428 }
429 
435 static void memory_transaction_done_cb(struct spi_transaction *trans __attribute__((unused)))
436 {
437  memory_ready = true;
438 }
439 
440 
441 
442 
443 /******************************************************************/
444 /* */
445 /* Mid low level functions, abstracting the low SPI layer */
446 /* */
447 /******************************************************************/
448 
463 {
464  static uint8_t ml_write_values_to_memory_status = 0;
465  static uint32_t previus_mem_addr = 0;
466  static uint8_t *previus_values = NULL;
467  static uint8_t previus_size = 0;
468 
469 
470  //test if we are stating a new writting cicle
471  if ((ml_write_values_to_memory_status == 0) &&
472  ((previus_mem_addr != mem_addr) || (previus_values != values) || (previus_size != size))) {
473 
474  ml_write_values_to_memory_status = 1;
475  previus_mem_addr = mem_addr;
476  previus_values = values;
477  previus_size = size;
478  }
479 
480  switch (ml_write_values_to_memory_status) {
481 
482  case 0 :
483  //waiting for something to do
484  break;
485 
486  case 1 :
488  ml_write_values_to_memory_status = 2;
489  //break;
490  //we imediatly send the values after this message.
491  //The low level functions are not using the same buffers
492  //so we can do it
493 
494  case 2 :
495  memory_write_values(mem_addr, values, size);
496  ml_write_values_to_memory_status = 3;
498  break;
499 
500  case 3 :
501  memory_read_status_1(); //we wait for the writting to be done
503  ml_write_values_to_memory_status = 3;
504  } else { //the writting has been completed
505  ml_write_values_to_memory_status = 0;
506  }
507  break;
508 
509  default :
510  break;
511  }
512 
513  return ml_write_values_to_memory_status;
514 }
515 
516 
529 {
530 
531  static uint8_t ml_erase_4k_on_memory_status = 0;
532 
533  switch (ml_erase_4k_on_memory_status) {
534 
535  case 0 :
537  ml_erase_4k_on_memory_status = 1;
538  break;
539 
540  case 1 :
541  memory_erase_4k(mem_addr);
542  ml_erase_4k_on_memory_status = 2;
544  break;
545 
546  case 2 :
547  memory_read_status_1(); //we wait for the writting to be done
549  ml_erase_4k_on_memory_status = 2;
550  } else { //the erasing have been completed
551  ml_erase_4k_on_memory_status = 0;
552  }
553  break;
554 
555  default :
556  break;
557  }
558 
559  return ml_erase_4k_on_memory_status;
560 }
561 
562 
574 {
575 
576  static uint8_t ml_erase_memory_status = 0;
577 
578  switch (ml_erase_memory_status) {
579 
580  case 0 :
582  ml_erase_memory_status = 1;
583  break;
584 
585  case 1 :
587  ml_erase_memory_status = 2;
589  break;
590 
591  case 2 :
592  memory_read_status_1(); //we wait for the writting to be done
594  ml_erase_memory_status = 2;
595  } else { //the erasing have been completed
596  ml_erase_memory_status = 0;
597  }
598  break;
599 
600  default : break;
601  }
602 
603  return ml_erase_memory_status;
604 }
605 
606 
614 {
617 }
618 
619 
620 
621 
622 
623 /******************************************************************/
624 /* */
625 /* Mid high level function : memory management */
626 /* */
627 /******************************************************************/
628 
644 {
645 
646  static uint8_t append_to_memory_status = 0;
647  static uint8_t index_value_unwritten = 0;
648  uint8_t return_code = 1;
649  uint8_t size_data_left_to_write;
650  uint8_t wait_for_SPI = 0;
651 
652  uint32_t size_used_in_current_page, size_left_current_page, size_to_write;
653 
654  while (!wait_for_SPI) {
655 
656  switch (append_to_memory_status) {
657 
658  case 0 :
659  if (!ERASE_MEMORY_AT_START) {
660  if ((current_unerased_addr - current_writting_addr) > size) { //we got enough cleared space to write the value
661 
662  append_to_memory_status = 1;
663  } else {
664 
666 
667  current_unerased_addr += 4096; //65536
668  } else {
669 
670  wait_for_SPI = 1;
671  }
672  }
673  } else {
674 
675  append_to_memory_status = 1;
676  }
677  break;
678 
679 
680  case 1 :
681  //we start writting the values
682  //need to fit the values in pages of 4K
683 
684  //256 bytes per pages
685  size_used_in_current_page = (current_writting_addr & 0x000000FF);
686  size_left_current_page = 0x00000100 - size_used_in_current_page;
687 
688  size_data_left_to_write = size - index_value_unwritten;
689  if (size_left_current_page > size_data_left_to_write) { size_to_write = size_data_left_to_write; }
690  else { size_to_write = size_left_current_page; }
691 
692  if (size_to_write > 250) { size_to_write = 250; } //protection against overflows in the lower levels
693 
694  if (size_to_write > 0) {
695 
696  if (!ml_write_values_to_memory(current_writting_addr, &values[index_value_unwritten], size_to_write)) {
697 
698  index_value_unwritten += size_to_write;
699  current_writting_addr += size_to_write;
700 
701  if (index_value_unwritten == size) {
702 
703  append_to_memory_status = 0;
704  index_value_unwritten = 0;
705  return_code = 0;
706  }
707 
708  //test is we are close to the end of the memory
710  //if we got less than END_OF_MEMORY_THRESHOLD kilo Bytes of mem left
711 
712  logging_status_gui = 3; //we stop the logging
713  }
714 
715 
716  }
717 
718  wait_for_SPI = 1;
719  }
720  break;
721 
722  default:
723  break;
724  }
725  }
726 
727  return return_code;
728 }
729 
730 
731 
739 {
740 
742  static uint8_t i = MEMORY_READ_LATTENCY;
743  long fd = 0;
744 
746 
747  while (uart_check_free_space(&HS_LOG_UART, &fd, 1)) {
748 
749  if (i >= msg_size) {
750 
754 
757  }
758  break;
759  }
760  uart_put_byte(&HS_LOG_UART, fd, uart_read_buff[i]);
761  i++;
762  }
763 
764  } else {
765 
770  }
771  }
772 }
773 
774 
775 
787 {
788 
789  uint8_t return_code = 1;
790 
791  if (*size > 0) {
792  if (!append_values_to_memory(buffer, *size)) {
793  *size = 0;
794  return_code = 0;
795  }
796  } else {
797  return_code = 0;
798  }
799 
800  return return_code;
801 }
802 
803 
804 
805 
806 /******************************************************************/
807 /* */
808 /* High level function : local buffer management */
809 /* */
810 /******************************************************************/
811 
823 {
824  if (buffer_used) {
825 
826  if (nbr_values_in_buffer_sending < 0xFF) {
829  } else {
830  nbr_lost_values++;
831  }
832 
833  } else {
834 
835  if (nbr_values_in_buffer < 0xFF) {
838  } else {
839  nbr_lost_values++;
840  }
841  }
842 }
843 
855 {
856  uint8_t i;
857 
858  for (i = 0; i < size; i++) {
860  }
861 }
862 
870 {
871  uint8_t return_code = 1;
872  uint8_t *log_value_tmp;
873 
874  if (buffer_used) {
875 
877 
878  buffer_used = 0;
879 
880  if (nbr_lost_values) {
881 
883 
884  log_value_tmp = (uint8_t *) &nbr_lost_values;
885  add_byte_to_buffer(log_value_tmp[0]);
886  add_byte_to_buffer(log_value_tmp[1]);
887  add_byte_to_buffer(log_value_tmp[2]);
888  add_byte_to_buffer(log_value_tmp[3]);
889 
891  nbr_lost_values = 0;
892  }
893 
894  return_code = 0;
895  }
896  } else {
897 
899 
900  buffer_used = 1;
901 
902  if (nbr_lost_values) {
903 
905 
906  log_value_tmp = (uint8_t *) &nbr_lost_values;
907  add_byte_to_buffer(log_value_tmp[0]);
908  add_byte_to_buffer(log_value_tmp[1]);
909  add_byte_to_buffer(log_value_tmp[2]);
910  add_byte_to_buffer(log_value_tmp[3]);
911 
913  nbr_lost_values = 0;
914  }
915 
916  return_code = 0;
917  }
918  }
919 
920  return return_code;
921 }
922 
923 
924 
929 {
930  uint8_t return_value = 0;
931 
932  if ((nbr_values_in_buffer == 0) && (nbr_values_in_buffer_sending == 0)) {
933  return_value = 1;
934  }
935 
936  return return_value;
937 }
938 
939 
940 
941 
942 /******************************************************************/
943 /* */
944 /* High level function : log management */
945 /* */
946 /******************************************************************/
947 
962 {
963 
964  static uint8_t start_log_status = 0;
965  uint8_t return_code = 1;
966 
967  char msg_names[(SIZE_OF_VALUES_NAMES + 1)*NBR_VALUES_TO_LOG] = "";
968  uint8_t i;
969 
970  for (i = 0; i < NBR_VALUES_TO_LOG; i++) {
971 
972  strcat(msg_names, name_of_the_values[i]);
973  if (i != (NBR_VALUES_TO_LOG - 1)) { strcat(msg_names, ";"); } //we don't put a ';' at the end of the list
974  }
975 
976  switch (start_log_status) {
977 
978  case 0 :
979  current_writting_addr = 0x00000000; //restart the writting at the begining of the memory
980  current_unerased_addr = 0x00000000;
981 
982  if (ERASE_MEMORY_AT_START) {
983 
985 
986  start_log_status = 1;
987  }
988  } else {
989 
990  start_log_status = 1;
991  }
992  break;
993 
994 
995  case 1 :
998  start_log_status = 2;
999  break;
1000 
1001  case 2 :
1003  start_log_status = 3;
1004  break;
1005 
1006  case 3 :
1008  start_log_status = 0;
1009  return_code = 0;
1010  break;
1011 
1012  default :
1013  break;
1014  }
1015 
1016  return return_code;
1017 }
1018 
1019 
1027 {
1028  uint8_t *log_value_tmp;
1029  uint8_t i, j;
1030 
1031  for (i = 0; i < NBR_VALUES_TO_LOG; i++) {
1032 
1033  log_value_tmp = (uint8_t *) values_to_log[i];
1034 
1035  for (j = 0; j < SIZE_OF_LOGGED_VALUES; j++) {
1036 
1037  add_byte_to_buffer(log_value_tmp[j]);
1038  }
1039  }
1040 }
1041 
1042 
1046 void run_logger(void)
1047 {
1048  static uint8_t i = 0;
1049  //useless variable. It simply remove a warning when SKIP_X_CALLS_BETWEEN_VALUES=0 and the test is always true
1051 
1052  if (i >= limit) { //3 with erase memory, 0 WITHOUT SKIP_X_CALLS_BETWEEN_VALUES
1054  i = 0;
1055  }
1056  i++;
1057 }
1058 
1059 
1071 {
1072  uint8_t return_value = 1;
1073 
1074  if (are_buffers_empty()) { //if the buffers are empty to prevent from writting during a buffer overflow
1076  return_value = 0;
1077  }
1078 
1079  return return_value;
1080 }
1081 
1082 
1083 
1084 
1085 /******************************************************************/
1086 /* */
1087 /* Module function */
1088 /* */
1089 /******************************************************************/
1090 
1091 
1096 {
1097  //init the SPI to communicat with the memory
1104  memory_transaction.slave_idx = HIGH_SPEED_LOGGER_DIRECT_MEMORY_SLAVE_NUMBER;
1111 
1112  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
1113 
1114 
1121  memory_send_value_transaction.slave_idx = HIGH_SPEED_LOGGER_DIRECT_MEMORY_SLAVE_NUMBER;
1128 
1129 
1130 
1131  //init the UART to send the values back to the computer
1132  uart_periph_init(&HS_LOG_UART);
1133  uart_periph_set_bits_stop_parity(&HS_LOG_UART, 8, 1, 0);
1134 }
1135 
1136 
1137 
1142 {
1143  uint8_t uart_received;
1144 
1145  //UART part (communication with the computer to dump the memory)
1146  while (uart_char_available(&HS_LOG_UART)) {
1147 
1148  uart_received = uart_getch(&HS_LOG_UART);
1149 
1150  if (uart_received == 'A') {
1153 
1154  } else if (uart_received == 'B') {
1156  }
1157  }
1158 
1159 
1160  //SPI part (to log the values on the memory when in flight)
1161  if (memory_ready) {
1162 
1163  switch (logging_status_gui) {
1164 
1165  case 0 :
1166  //idle state, nothing to do
1167  break;
1168 
1169  case 1 :
1170  //start a new log
1171  if (!start_new_log()) { logging_status_gui = 0; }
1172  break;
1173 
1174  case 2 :
1175  //logging values
1176  run_logger();
1177  break;
1178 
1179  case 3 :
1180  //finishing the log
1181  if (!end_log()) { logging_status_gui = 0; }
1182  break;
1183 
1184  default :
1185  break;
1186  }
1187 
1189  }
1190 
1191  //this function regulats itself, we have to call it at every iteration of the module
1193 }
1194 
1195 
1196 
1197 /******************************************************************/
1198 /* */
1199 /* Other functions */
1200 /* */
1201 /******************************************************************/
1202 
1217 uint8_t is_sequence_in_array(uint8_t *array, uint8_t array_size, uint8_t *sequence, uint8_t sequence_size)
1218 {
1220  static uint8_t current_sequence_id = 0;
1221 
1222  for (i = MEMORY_READ_LATTENCY; i < array_size; i++) {
1223 
1224  if (array[i] == sequence[current_sequence_id]) {
1225  current_sequence_id++;
1226  if (current_sequence_id >= sequence_size) {
1227  current_sequence_id = 0;
1228  return 1;
1229  }
1230  } else {
1231  current_sequence_id = 0;
1232  }
1233  }
1234 
1235  return 0;
1236 }
1237 
1238 
1243 {
1245 }
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
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition: spi_arch.c:533
@ SPICphaEdge2
CPHA = 1.
Definition: spi.h:75
@ SPICpolIdleHigh
CPOL = 1.
Definition: spi.h:84
@ SPISelectUnselect
slave is selected before transaction and unselected after
Definition: spi.h:63
@ SPIMSBFirst
Definition: spi.h:112
@ SPIDiv64
Definition: spi.h:125
@ SPIDss8bit
Definition: spi.h:90
SPI transaction structure.
Definition: spi.h:148
void memory_write_values(uint32_t mem_addr, uint8_t *values, uint8_t size)
Function sending a request to write a buffer of values to the memory.
static void memory_read_values_cb(struct spi_transaction *trans)
Callback function decrypting the read values from the memory.
char ** name_of_the_values
list of the names of the messages you are logging
uint8_t start_new_log(void)
Function starting a new log.
#define READING_BLOCK_SIZE
size of the block that we read in the memory and send over UART. MAX = 250.
void ml_read_log_in_memory(void)
Function continuing the reading of the current log in memory.
uint8_t run_memory_management(void)
Function sending the buffer to the memory when possible.
static void memory_read_status_cb(struct spi_transaction *trans)
Callback function decrypting the status Byte of the memory.
void high_speed_logger_direct_memory_init(void)
Function initialisating the module.
uint8_t end_log(void)
Function ending the current log.
void memory_erase_4k(uint32_t mem_addr)
Function sending a request to erase 4KB of the memory.
uint32_t current_writting_addr
The address at wich we will write next time.
uint8_t sending_buffer_to_uart
Flag defining if we are sending values through the UART.
void add_array_to_buffer(uint8_t *array, uint8_t size)
Function adding an array to the local buffer.
#define TOTAL_MEMORY_SIZE
nbr of MB in the memory
void memory_read_values(uint32_t mem_addr, uint8_t size)
Function sending a request to read some values in memory.
uint8_t uart_read_buff[READING_BLOCK_SIZE+MEMORY_READ_LATTENCY]
Buffer used to fetch the values from the memory.
struct spi_transaction memory_send_value_transaction
Structure used for sending values to the memory.
uint8_t are_buffers_empty(void)
Function returning true if the two local buffers are empty.
#define SIZE_OF_VALUES_NAMES
size (in characters) of the nameof the logged values.
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
struct spi_transaction memory_transaction
Structure used for general comunication with the memory.
uint32_t nbr_lost_values
Number of Bytes we have lost due to overflows (reseted each time we can write agin in the buffer)
uint8_t start_lost_values_sequence[6]
Start sequence indicating we have lost some Bytes due to overflows.
#define SKIP_X_CALLS_BETWEEN_VALUES
Skip X values between write.
static volatile bool memory_ready
Flag stating if the memory is being used.
void memory_read_status_1(void)
Function sending a request to fetch the status Byte of the memory.
uint8_t nbr_values_in_buffer
Number of Bytes in the first buffer (buffer_values_logged)
void memory_completly_erase(void)
Function sending a request to erase the entire memory.
#define MEMORY_READ_LATTENCY
nbr of Bytes 0x00 received before the real values when reading the memory
uint8_t ml_erase_completely_memory(void)
Function erasing the entire memory.
void add_values_to_buffer(void)
Function adding the configured messages to the buffers of the values to be written in memory.
void memory_read_id(void)
Function sending a request for the ID of the memory chip.
#define NBR_VALUES_TO_LOG
nbr of messages you want to log
uint8_t start_values_sequence[3]
Start sequence written at the begining of the values of a log (after the header)
uint8_t ml_write_values_to_memory(uint32_t mem_addr, uint8_t *values, uint8_t size)
Function writting a buffer of values to the memory.
#define SIZE_OF_LOGGED_VALUES
size (in bytes) of the values we log.
static void memory_transaction_done_cb(struct spi_transaction *trans)
generic allback function for SPI transactions
uint8_t values_send_buffer[256]
Buffer used for sending value to the memory.
uint8_t buff[25]
Buffer used for general comunication over SPI (in buffer)
uint8_t stop_log_sequence[6]
Stop sequence written at the end of the log.
void high_speed_logger_direct_memory_periodic(void)
Main function of the module.
void memory_send_wren(void)
Function sending a request to set the writte enable flag in the memory.
uint8_t buffer_values_sending[256]
Second local buffer for the log.
uint32_t values_to_log[NBR_VALUES_TO_LOG]
list of the messages you want to log
void send_buffer_to_uart(void)
Function sending the read values from the memory to te UART.
uint8_t ml_erase_4k_on_memory(uint32_t mem_addr)
Function erasing 4KB of the memory.
uint8_t start_log_sequence[6]
Start sequence written at the begining of a log.
uint8_t send_buffer_to_memory(uint8_t *buffer, uint8_t *size)
Function sending a buffer ot the memory.
#define ERASE_MEMORY_AT_START
if we completly erase the memory at the start of the log.
uint8_t relaunch_reading_memory
Flag defining if we need to keep reading the memory (if the stop sequence is found we stop)
#define END_OF_MEMORY_THRESHOLD
the nbr of kilo Bytes left at the end of the memory before stoping the log automaticaly
void memory_send_wrdi(void)
Function sending a request to clear the writte enable flag in the memory.
uint8_t is_sequence_in_array(uint8_t *array, uint8_t array_size, uint8_t *sequence, uint8_t sequence_size)
Function testing if a sequence is in a buffer of values.
uint32_t current_unerased_addr
The address of the next block to erase.
uint8_t logging_status_gui
Status of the module.
uint8_t nbr_values_in_buffer_sending
Number of Bytes in the second buffer (nbr_values_in_buffer_sending)
uint8_t wait_answear_from_reading_memory
Flag defining if we are waiting for an answear from the memory when reading values from it.
uint8_t buffer_values_logged[256]
First local buffer for the log.
uint8_t buffer_used
Flag defining wich buffer is used.
uint8_t stop_lost_values_sequence[6]
Stop sequence indicating we have lost some Bytes due to overflows.
uint8_t memory_status_byte
Last status Byte read from the memory.
void run_logger(void)
Funcion called to add the values to log to the buffer with a frequency divider in order to not overfl...
void high_speed_logger_direct_memory_handler(uint8_t val)
Function managing the interface with the user.
void add_byte_to_buffer(uint8_t value)
Function adding a Byte to the local buffer.
uint32_t current_reading_addr
The address at wich we will read next time.
uint8_t append_values_to_memory(uint8_t *values, uint8_t size)
Function adding a buffer of values to the memory.
uint8_t continue_reading_memory
Flag defining if we need to keep reading the memory (if the PC asked for new values)
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 uart_char_available(struct uart_periph *p)
Check UART for available chars in receive buffer.
Definition: uart_arch.c:357
void uart_periph_set_bits_stop_parity(struct uart_periph *periph, uint8_t bits, uint8_t stop, uint8_t parity)
Definition: uart_arch.c:296
uint8_t uart_getch(struct uart_periph *p)
Definition: uart_arch.c:348
int fd
Definition: serial.c:26
int * array
Architecture independent SPI (Serial Peripheral Interface) API.
Periodic telemetry system header (includes downlink utility and generated code).
uint16_t val[TCOUPLE_NB]
void uart_periph_init(struct uart_periph *p)
Definition: uart.c:231
int WEAK uart_check_free_space(struct uart_periph *p, long *fd, uint16_t len)
Definition: uart.c:256
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
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