LCOV - code coverage report
Current view: top level - buffer - buffer.c (source / functions) Hit Total Coverage
Test: test-37de7e7-dirty-coverage.info Lines: 96 100 96.0 %
Date: 2019-04-16 Functions: 14 14 100.0 %

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

Generated by: LCOV version 1.10