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
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 "subsystems/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
47 #define ERASE_MEMORY_AT_START 0
49 #define SIZE_OF_LOGGED_VALUES 4
51 #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 
73 
77 
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
108 #define TOTAL_MEMORY_SIZE 32
110 #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_t 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 
204  msg[0] = 0x9F;
205 
208 
211 
213 
214  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
215 }
216 
221 {
223  msg[0] = 0x06;
224 
227 
230 
232 
233  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
234 }
235 
240 {
242  msg[0] = 0x04;
243 
246 
249 
251 
252  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
253 }
254 
259 {
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 
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 
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 
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 
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 
745 
746  while (uart_check_free_space(&HS_LOG_UART, 1)) {
747 
748  if (i >= msg_size) {
749 
753 
756  }
757  break;
758  }
759  uart_put_byte(&HS_LOG_UART, uart_read_buff[i]);
760  i++;
761  }
762 
763  } else {
764 
769  }
770  }
771 }
772 
773 
774 
786 {
787 
788  uint8_t return_code = 1;
789 
790  if (*size > 0) {
791  if (!append_values_to_memory(buffer, *size)) {
792  *size = 0;
793  return_code = 0;
794  }
795  } else {
796  return_code = 0;
797  }
798 
799  return return_code;
800 }
801 
802 
803 
804 
805 /******************************************************************/
806 /* */
807 /* High level function : local buffer management */
808 /* */
809 /******************************************************************/
810 
822 {
823  if (buffer_used) {
824 
825  if (nbr_values_in_buffer_sending < 0xFF) {
828  } else {
829  nbr_lost_values++;
830  }
831 
832  } else {
833 
834  if (nbr_values_in_buffer < 0xFF) {
837  } else {
838  nbr_lost_values++;
839  }
840  }
841 }
842 
854 {
855  uint8_t i;
856 
857  for (i = 0; i < size; i++) {
858  add_byte_to_buffer(array[i]);
859  }
860 }
861 
869 {
870  uint8_t return_code = 1;
871  uint8_t *log_value_tmp;
872 
873  if (buffer_used) {
874 
876 
877  buffer_used = 0;
878 
879  if (nbr_lost_values) {
880 
882 
883  log_value_tmp = (uint8_t *) &nbr_lost_values;
884  add_byte_to_buffer(log_value_tmp[0]);
885  add_byte_to_buffer(log_value_tmp[1]);
886  add_byte_to_buffer(log_value_tmp[2]);
887  add_byte_to_buffer(log_value_tmp[3]);
888 
890  nbr_lost_values = 0;
891  }
892 
893  return_code = 0;
894  }
895  } else {
896 
898 
899  buffer_used = 1;
900 
901  if (nbr_lost_values) {
902 
904 
905  log_value_tmp = (uint8_t *) &nbr_lost_values;
906  add_byte_to_buffer(log_value_tmp[0]);
907  add_byte_to_buffer(log_value_tmp[1]);
908  add_byte_to_buffer(log_value_tmp[2]);
909  add_byte_to_buffer(log_value_tmp[3]);
910 
912  nbr_lost_values = 0;
913  }
914 
915  return_code = 0;
916  }
917  }
918 
919  return return_code;
920 }
921 
922 
923 
928 {
929  uint8_t return_value = 0;
930 
931  if ((nbr_values_in_buffer == 0) && (nbr_values_in_buffer_sending == 0)) {
932  return_value = 1;
933  }
934 
935  return return_value;
936 }
937 
938 
939 
940 
941 /******************************************************************/
942 /* */
943 /* High level function : log management */
944 /* */
945 /******************************************************************/
946 
961 {
962 
963  static uint8_t start_log_status = 0;
964  uint8_t return_code = 1;
965 
966  char msg_names[(SIZE_OF_VALUES_NAMES + 1)*NBR_VALUES_TO_LOG] = "";
967  uint8_t i;
968 
969  for (i = 0; i < NBR_VALUES_TO_LOG; i++) {
970 
971  strcat(msg_names, name_of_the_values[i]);
972  if (i != (NBR_VALUES_TO_LOG - 1)) { strcat(msg_names, ";"); } //we don't put a ';' at the end of the list
973  }
974 
975  switch (start_log_status) {
976 
977  case 0 :
978  current_writting_addr = 0x00000000; //restart the writting at the begining of the memory
979  current_unerased_addr = 0x00000000;
980 
981  if (ERASE_MEMORY_AT_START) {
982 
984 
985  start_log_status = 1;
986  }
987  } else {
988 
989  start_log_status = 1;
990  }
991  break;
992 
993 
994  case 1 :
997  start_log_status = 2;
998  break;
999 
1000  case 2 :
1001  add_array_to_buffer((uint8_t *)msg_names, (SIZE_OF_VALUES_NAMES + 1)*NBR_VALUES_TO_LOG);
1002  start_log_status = 3;
1003  break;
1004 
1005  case 3 :
1007  start_log_status = 0;
1008  return_code = 0;
1009  break;
1010 
1011  default :
1012  break;
1013  }
1014 
1015  return return_code;
1016 }
1017 
1018 
1026 {
1027  uint8_t *log_value_tmp;
1028  uint8_t i, j;
1029 
1030  for (i = 0; i < NBR_VALUES_TO_LOG; i++) {
1031 
1032  log_value_tmp = (uint8_t *) values_to_log[i];
1033 
1034  for (j = 0; j < SIZE_OF_LOGGED_VALUES; j++) {
1035 
1036  add_byte_to_buffer(log_value_tmp[j]);
1037  }
1038  }
1039 }
1040 
1041 
1045 void run_logger(void)
1046 {
1047  static uint8_t i = 0;
1048  //useless variable. It simply remove a warning when SKIP_X_CALLS_BETWEEN_VALUES=0 and the test is always true
1050 
1051  if (i >= limit) { //3 with erase memory, 0 WITHOUT SKIP_X_CALLS_BETWEEN_VALUES
1053  i = 0;
1054  }
1055  i++;
1056 }
1057 
1058 
1070 {
1071  uint8_t return_value = 1;
1072 
1073  if (are_buffers_empty()) { //if the buffers are empty to prevent from writting during a buffer overflow
1075  return_value = 0;
1076  }
1077 
1078  return return_value;
1079 }
1080 
1081 
1082 
1083 
1084 /******************************************************************/
1085 /* */
1086 /* Module function */
1087 /* */
1088 /******************************************************************/
1089 
1090 
1095 {
1096  //init the SPI to communicat with the memory
1103  memory_transaction.slave_idx = HIGH_SPEED_LOGGER_DIRECT_MEMORY_SLAVE_NUMBER;
1110 
1111  spi_submit(&(HIGH_SPEED_LOGGER_DIRECT_MEMORY_DEVICE), &memory_transaction);
1112 
1113 
1120  memory_send_value_transaction.slave_idx = HIGH_SPEED_LOGGER_DIRECT_MEMORY_SLAVE_NUMBER;
1127 
1128 
1129 
1130  //init the UART to send the values back to the computer
1131  uart_periph_init(&HS_LOG_UART);
1132  uart_periph_set_bits_stop_parity(&HS_LOG_UART, 8, 1, 0);
1133 }
1134 
1135 
1136 
1141 {
1142  uint8_t uart_received;
1143 
1144  //UART part (communication with the computer to dump the memory)
1145  while (uart_char_available(&HS_LOG_UART)) {
1146 
1147  uart_received = uart_getch(&HS_LOG_UART);
1148 
1149  if (uart_received == 'A') {
1152 
1153  } else if (uart_received == 'B') {
1155  }
1156  }
1157 
1158 
1159  //SPI part (to log the values on the memory when in flight)
1160  if (memory_ready) {
1161 
1162  switch (logging_status_gui) {
1163 
1164  case 0 :
1165  //idle state, nothing to do
1166  break;
1167 
1168  case 1 :
1169  //start a new log
1170  if (!start_new_log()) { logging_status_gui = 0; }
1171  break;
1172 
1173  case 2 :
1174  //logging values
1175  run_logger();
1176  break;
1177 
1178  case 3 :
1179  //finishing the log
1180  if (!end_log()) { logging_status_gui = 0; }
1181  break;
1182 
1183  default :
1184  break;
1185  }
1186 
1188  }
1189 
1190  //this function regulats itself, we have to call it at every iteration of the module
1192 }
1193 
1194 
1195 
1196 /******************************************************************/
1197 /* */
1198 /* Other functions */
1199 /* */
1200 /******************************************************************/
1201 
1216 uint8_t is_sequence_in_array(uint8_t *array, uint8_t array_size, uint8_t *sequence, uint8_t sequence_size)
1217 {
1219  static uint8_t current_sequence_id = 0;
1220 
1221  for (i = MEMORY_READ_LATTENCY; i < array_size; i++) {
1222 
1223  if (array[i] == sequence[current_sequence_id]) {
1224  current_sequence_id++;
1225  if (current_sequence_id >= sequence_size) {
1226  current_sequence_id = 0;
1227  return 1;
1228  }
1229  } else {
1230  current_sequence_id = 0;
1231  }
1232  }
1233 
1234  return 0;
1235 }
1236 
1237 
1242 {
1244 }
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.
static void memory_transaction_done_cb(struct spi_transaction *trans)
generic allback function for SPI transactions
void high_speed_logger_direct_memory_init(void)
Function initialisating the module.
uint8_t start_values_sequence[3]
Start sequence written at the begining of the values of a log (after the header)
enum SPIClockPolarity cpol
clock polarity control
Definition: spi.h:149
uint8_t logging_status_gui
Status of the module.
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
uint8_t nbr_values_in_buffer
Number of Bytes in the first buffer (buffer_values_logged)
void high_speed_logger_direct_memory_handler(uint8_t val)
Function managing the interface with the user.
void memory_send_wren(void)
Function sending a request to set the writte enable flag in the memory.
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition: spi.h:153
uint8_t stop_log_sequence[6]
Stop sequence written at the end of the log.
uint16_t output_length
number of data words to write
Definition: spi.h:146
uint16_t value
Definition: adc_arch.c:586
uint8_t buffer_values_logged[256]
First local buffer for the log.
struct spi_transaction memory_transaction
Structure used for general comunication with the memory.
Periodic telemetry system header (includes downlink utility and generated code).
uint8_t ml_erase_completely_memory(void)
Function erasing the entire memory.
CPHA = 1.
Definition: spi.h:69
uint8_t buffer_values_sending[256]
Second local buffer for the log.
#define ERASE_MEMORY_AT_START
if we completly erase the memory at the start of the log.
void send_buffer_to_uart(void)
Function sending the read values from the memory to te UART.
uint32_t nbr_lost_values
Number of Bytes we have lost due to overflows (reseted each time we can write agin in the buffer) ...
uint16_t uart_char_available(struct uart_periph *p)
Check UART for available chars in receive buffer.
Definition: uart_arch.c:296
uint8_t buffer_used
Flag defining wich buffer is used.
#define SIZE_OF_VALUES_NAMES
size (in characters) of the nameof the logged values.
uint8_t continue_reading_memory
Flag defining if we need to keep reading the memory (if the PC asked for new values) ...
static void memory_read_status_cb(struct spi_transaction *trans)
Callback function decrypting the status Byte of the memory.
void memory_send_wrdi(void)
Function sending a request to clear the writte enable flag in the memory.
void memory_erase_4k(uint32_t mem_addr)
Function sending a request to erase 4KB of the memory.
SPI transaction structure.
Definition: spi.h:142
static volatile bool_t memory_ready
Flag stating if the memory is being used.
CPOL = 1.
Definition: spi.h:78
enum SPIBitOrder bitorder
MSB/LSB order.
Definition: spi.h:152
struct spi_transaction memory_send_value_transaction
Structure used for sending values to the memory.
uint8_t start_log_sequence[6]
Start sequence written at the begining of a log.
#define SIZE_OF_LOGGED_VALUES
size (in bytes) of the values we log.
uint8_t start_lost_values_sequence[6]
Start sequence indicating we have lost some Bytes due to overflows.
char ** name_of_the_values
list of the names of the messages you are logging
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition: spi.h:144
uint32_t current_writting_addr
The address at wich we will write next time.
uint8_t send_buffer_to_memory(uint8_t *buffer, uint8_t *size)
Function sending a buffer ot the memory.
void add_array_to_buffer(uint8_t *array, uint8_t size)
Function adding an array to the local buffer.
uint8_t are_buffers_empty(void)
Function returning true if the two local buffers are empty.
void memory_read_id(void)
Function sending a request for the ID of the memory chip.
enum SPISlaveSelect select
slave selection behavior
Definition: spi.h:148
#define TOTAL_MEMORY_SIZE
nbr of MB in the memory
#define FALSE
Definition: std.h:5
void high_speed_logger_direct_memory_periodic(void)
Main function of the module.
uint8_t stop_lost_values_sequence[6]
Stop sequence indicating we have lost some Bytes due to overflows.
uint32_t current_reading_addr
The address at wich we will read next time.
Architecture independent SPI (Serial Peripheral Interface) API.
struct Int32Vect3 mag_unscaled
unscaled magnetometer measurements
Definition: imu.h:52
enum SPIClockPhase cpha
clock phase control
Definition: spi.h:150
int32_t r
in rad/s with INT32_RATE_FRAC
struct Int32Rates gyro_unscaled
unscaled gyroscope measurements
Definition: imu.h:50
#define TRUE
Definition: std.h:4
#define READING_BLOCK_SIZE
size of the block that we read in the memory and send over UART. MAX = 250.
uint8_t run_memory_management(void)
Function sending the buffer to the memory when possible.
Definition: spi.h:84
uint8_t nbr_values_in_buffer_sending
Number of Bytes in the second buffer (nbr_values_in_buffer_sending)
#define NBR_VALUES_TO_LOG
nbr of messages you want to log
bool_t spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit a spi transaction.
Definition: spi_arch.c:48
uint8_t relaunch_reading_memory
Flag defining if we need to keep reading the memory (if the stop sequence is found we stop) ...
uint8_t ml_erase_4k_on_memory(uint32_t mem_addr)
Function erasing 4KB of the memory.
uint8_t sending_buffer_to_uart
Flag defining if we are sending values through the UART.
static void memory_read_values_cb(struct spi_transaction *trans)
Callback function decrypting the read values 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...
SPICallback after_cb
NULL or function called after the transaction.
Definition: spi.h:155
uint16_t val[TCOUPLE_NB]
struct Imu imu
global IMU state
Definition: imu_aspirin2.c:43
uint8_t uart_read_buff[READING_BLOCK_SIZE+MEMORY_READ_LATTENCY]
Buffer used to fetch the values from the memory.
void uart_periph_init(struct uart_periph *p)
Definition: uart.c:233
unsigned long uint32_t
Definition: types.h:18
void uart_periph_set_bits_stop_parity(struct uart_periph *p, uint8_t bits, uint8_t stop, uint8_t parity)
Definition: uart_arch.c:77
void ml_read_log_in_memory(void)
Function continuing the reading of the current log in memory.
uint8_t append_values_to_memory(uint8_t *values, uint8_t size)
Function adding a buffer of values to the memory.
uint8_t end_log(void)
Function ending the current log.
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.
Inertial Measurement Unit interface.
bool_t uart_check_free_space(struct uart_periph *p, uint8_t len)
Definition: uart.c:256
uint16_t input_length
number of data words to read
Definition: spi.h:145
uint8_t uart_getch(struct uart_periph *p)
Definition: uart_arch.c:287
void memory_completly_erase(void)
Function sending a request to erase the entire memory.
uint8_t values_send_buffer[256]
Buffer used for sending value to the memory.
uint8_t memory_status_byte
Last status Byte read from the memory.
unsigned char uint8_t
Definition: types.h:14
uint8_t wait_answear_from_reading_memory
Flag defining if we are waiting for an answear from the memory when reading values from it...
#define END_OF_MEMORY_THRESHOLD
the nbr of kilo Bytes left at the end of the memory before stoping the log automaticaly ...
slave is selected before transaction and unselected after
Definition: spi.h:57
#define SKIP_X_CALLS_BETWEEN_VALUES
Skip X values between write.
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.
uint32_t values_to_log[NBR_VALUES_TO_LOG]
list of the messages you want to log
void memory_read_values(uint32_t mem_addr, uint8_t size)
Function sending a request to read some values in memory.
enum SPIDataSizeSelect dss
data transfer word size
Definition: spi.h:151
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition: spi.h:147
int32_t p
in rad/s with INT32_RATE_FRAC
Definition: spi.h:119
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition: spi.h:143
struct Int32Vect3 accel_unscaled
unscaled accelerometer measurements
Definition: imu.h:51
void add_byte_to_buffer(uint8_t value)
Function adding a Byte to the local buffer.
uint8_t start_new_log(void)
Function starting a new log.
#define MEMORY_READ_LATTENCY
nbr of Bytes 0x00 received before the real values when reading the memory
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
void add_values_to_buffer(void)
Function adding the configured messages to the buffers of the values to be written in memory...
int32_t q
in rad/s with INT32_RATE_FRAC
uint8_t buff[25]
Buffer used for general comunication over SPI (in buffer)
void uart_put_byte(struct uart_periph *periph, uint8_t data)
Definition: uart_arch.c:243
void memory_read_status_1(void)
Function sending a request to fetch the status Byte of the memory.
uint32_t current_unerased_addr
The address of the next block to erase.