UoS³ Flight Computer Firmware
 All Data Structures Files Functions Groups Pages
buffer.c
1 
9 #include "../firmware.h"
10 
11 static buffer_cache_t buffer_cache = { false, 0, 0, {0}, {0}, 0x0000 };
12 
13 void Buffer_init(void)
14 {
15  if(buffer_cache.initialised && !Buffer_verify_cache())
16  {
17  /* TODO: SEU Detected, REBOOT! */
18  Mission_SEU();
19  }
20  else if(!buffer_cache.initialised)
21  {
22  if(!Buffer_FRAM_cache_read(&buffer_cache))
23  {
24  /* Stored FRAM header fails CRC, so reset the buffer */
25  /* TODO: Increment a Counter in health data */
26  Buffer_reset();
27  }
28 
29  buffer_cache.initialised = true;
30  }
31 }
32 
33 bool Buffer_verify_cache(void)
34 {
35  return (buffer_cache.crc == Util_crc16((uint8_t *)&buffer_cache, sizeof(buffer_cache_t) - sizeof(uint16_t)));
36 }
37 
38 void Buffer_reset(void)
39 {
40  buffer_cache.last_index_stored = 0;
41  Buffer_FRAM_write_last_index_stored(&buffer_cache);
42 
43  buffer_cache.last_slot_transmitted = (BUFFER_SLOTS-1);
44  Buffer_FRAM_write_last_slot_transmitted(&buffer_cache);
45 
46  memset(buffer_cache.occupancy, 0x00, BUFFER_FRAM_SIZE_OCCUPANCY);
47  Buffer_FRAM_write_occupancy(&buffer_cache);
48 
49  memset(buffer_cache.indexes, 0x00, BUFFER_FRAM_SIZE_INDEXES);
50  Buffer_FRAM_write_indexes(&buffer_cache);
51 
52  /* CRC is automatically updated on each FRAM write */
53 }
54 
55 void Buffer_store_new_data(uint8_t *data_payload)
56 {
57  Buffer_init();
58 
59  uint16_t new_slot;
60  uint16_t new_index;
61 
62  new_index = (uint16_t)(buffer_cache.last_index_stored + 1);
63 
64  Buffer_find_new_slot(&new_slot);
65  Buffer_FRAM_write_data(new_slot, data_payload);
66  Buffer_set_index(new_slot, new_index);
67  Buffer_set_occupancy(new_slot, true);
68 }
69 
70 void Buffer_set_index(uint16_t slot, uint16_t index)
71 {
72  buffer_cache.indexes[slot] = index;
73  Buffer_FRAM_write_indexes(&buffer_cache);
74 }
75 
76 bool Buffer_get_next_data(uint8_t *data_payload)
77 {
78  Buffer_init();
79 
80  if(Buffer_get_next_slot(&(buffer_cache.last_slot_transmitted)))
81  {
82  Buffer_FRAM_read_data(buffer_cache.last_slot_transmitted, data_payload);
83  return true;
84  }
85  return false;
86 }
87 
88 bool Buffer_get_next_slot(uint16_t *slot)
89 {
90  uint16_t new_slot = *slot;
91 
92  if(++new_slot >= BUFFER_SLOTS)
93  {
94  /* Wrap search */
95  new_slot = 0;
96  }
97 
98  while(new_slot != *slot)
99  {
100  /* Check if slot is occupied */
101  if(0x00 != (buffer_cache.occupancy[new_slot>>3] & (0x80 >> (new_slot & 0x07))))
102  {
103  *slot = new_slot;
104  return true;
105  }
106 
107  if(++new_slot >= BUFFER_SLOTS)
108  {
109  /* Wrap search */
110  new_slot = 0;
111  }
112  }
113 
114  if(0x00 != (buffer_cache.occupancy[new_slot>>3] & (0x80 >> (new_slot & 0x07))))
115  {
116  *slot = new_slot;
117  return true;
118  }
119 
120  return false;
121 }
122 
123 void Buffer_remove_index(uint16_t index)
124 {
125  uint16_t slot;
126  if(Buffer_find_index(index, &slot))
127  {
128  Buffer_set_occupancy(slot, false);
129  }
130 }
131 
132 bool Buffer_find_index(uint16_t index, uint16_t *slot)
133 {
134  *slot = 0;
135  while(buffer_cache.indexes[*slot] != index)
136  {
137  if(++*slot >= BUFFER_SLOTS)
138  {
139  return false;
140  }
141  }
142  return true;
143 }
144 
145 void Buffer_find_new_slot(uint16_t *slot)
146 {
147  *slot = 0;
148  while (buffer_cache.occupancy[*slot>>3] & (0x80 >> (*slot & 0x07)))
149  {
150  if(++*slot >= BUFFER_SLOTS)
151  {
152  /* No unoccupied slots, so find slot with oldest index */
153  Buffer_find_oldest_slot(slot);
154  return;
155  }
156  }
157 }
158 
159 void Buffer_find_oldest_slot(uint16_t *slot)
160 {
161  uint16_t oldest_slot, oldest_index = buffer_cache.last_index_stored;
162 
163  *slot = 0;
164  while(++*slot < BUFFER_SLOTS)
165  {
166  if(oldest_index <= buffer_cache.last_index_stored)
167  {
168  if(buffer_cache.indexes[*slot] < oldest_index)
169  {
170  oldest_index = buffer_cache.indexes[*slot];
171  oldest_slot = *slot;
172  }
173  else if(buffer_cache.indexes[*slot] > buffer_cache.last_index_stored)
174  {
175  oldest_index = buffer_cache.indexes[*slot];
176  oldest_slot = *slot;
177  }
178  }
179  else if(buffer_cache.indexes[*slot] > buffer_cache.last_index_stored)
180  {
181  if(buffer_cache.indexes[*slot] < oldest_index)
182  {
183  oldest_index = buffer_cache.indexes[*slot];
184  oldest_slot = *slot;
185  }
186  }
187  }
188 
189  *slot = oldest_slot;
190  return;
191 }
192 
193 bool Buffer_get_occupancy(uint16_t slot)
194 {
195  return buffer_cache.occupancy[slot>>3] & (0x80 >> (slot & 0x07));
196 }
197 
198 void Buffer_set_occupancy(uint16_t slot, bool value)
199 {
200  if(value)
201  {
202  /* Set the corresponding bit */
203  buffer_cache.occupancy[slot>>3] = (uint8_t)(buffer_cache.occupancy[slot>>3] | (0x80 >> (slot & 0x07)));
204  }
205  else
206  {
207  /* Reset the corresponding bit */
208  buffer_cache.occupancy[slot>>3] = (uint8_t)(buffer_cache.occupancy[slot>>3] & ~(0x80 >> (slot & 0x07)));
209  }
210  Buffer_FRAM_write_occupancy(&buffer_cache);
211 }
212 
213 uint16_t Buffer_count_occupied(void)
214 {
215  Buffer_init();
216 
217  uint16_t i;
218  uint16_t result = 0;
219 
220  for(i=0; i<BUFFER_SLOTS; i++)
221  {
222  if(buffer_cache.occupancy[i>>3] & (0x80 >> (i & 0x07)))
223  {
224  result++;
225  }
226  }
227  return result;
228 }
229 
uint16_t Util_crc16(const uint8_t *buf, uint32_t size)
Definition: crc.c:100