PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Committer:
Pokitto
Date:
Sun Jul 01 06:32:10 2018 +0000
Revision:
51:113b1d84c34f
Child:
58:5f58a2846a20
PokittoCookie and faster Mode2 and Mode13 added

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pokitto 51:113b1d84c34f 1 /**************************************************************************/
Pokitto 51:113b1d84c34f 2 /*!
Pokitto 51:113b1d84c34f 3 @file PokittoCookie.cpp
Pokitto 51:113b1d84c34f 4 @author Jonne Valola
Pokitto 51:113b1d84c34f 5
Pokitto 51:113b1d84c34f 6 @section LICENSE
Pokitto 51:113b1d84c34f 7
Pokitto 51:113b1d84c34f 8 Software License Agreement (BSD License)
Pokitto 51:113b1d84c34f 9
Pokitto 51:113b1d84c34f 10 Copyright (c) 2018, Jonne Valola
Pokitto 51:113b1d84c34f 11 All rights reserved.
Pokitto 51:113b1d84c34f 12
Pokitto 51:113b1d84c34f 13 Redistribution and use in source and binary forms, with or without
Pokitto 51:113b1d84c34f 14 modification, are permitted provided that the following conditions are met:
Pokitto 51:113b1d84c34f 15 1. Redistributions of source code must retain the above copyright
Pokitto 51:113b1d84c34f 16 notice, this list of conditions and the following disclaimer.
Pokitto 51:113b1d84c34f 17 2. Redistributions in binary form must reproduce the above copyright
Pokitto 51:113b1d84c34f 18 notice, this list of conditions and the following disclaimer in the
Pokitto 51:113b1d84c34f 19 documentation and/or other materials provided with the distribution.
Pokitto 51:113b1d84c34f 20 3. Neither the name of the copyright holders nor the
Pokitto 51:113b1d84c34f 21 names of its contributors may be used to endorse or promote products
Pokitto 51:113b1d84c34f 22 derived from this software without specific prior written permission.
Pokitto 51:113b1d84c34f 23
Pokitto 51:113b1d84c34f 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
Pokitto 51:113b1d84c34f 25 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Pokitto 51:113b1d84c34f 26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Pokitto 51:113b1d84c34f 27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
Pokitto 51:113b1d84c34f 28 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
Pokitto 51:113b1d84c34f 29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
Pokitto 51:113b1d84c34f 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
Pokitto 51:113b1d84c34f 31 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Pokitto 51:113b1d84c34f 32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Pokitto 51:113b1d84c34f 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Pokitto 51:113b1d84c34f 34 */
Pokitto 51:113b1d84c34f 35 /**************************************************************************/
Pokitto 51:113b1d84c34f 36
Pokitto 51:113b1d84c34f 37 #include "Pokitto_settings.h"
Pokitto 51:113b1d84c34f 38 #include "Pokitto.h"
Pokitto 51:113b1d84c34f 39 #include "PokittoCookie.h"
Pokitto 51:113b1d84c34f 40
Pokitto 51:113b1d84c34f 41 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 42 #else
Pokitto 51:113b1d84c34f 43 #include "PokittoSimulator.h"
Pokitto 51:113b1d84c34f 44 #endif
Pokitto 51:113b1d84c34f 45
Pokitto 51:113b1d84c34f 46 using namespace Pokitto;
Pokitto 51:113b1d84c34f 47
Pokitto 51:113b1d84c34f 48 //char Cookie::_key[SBKEYSIZE];
Pokitto 51:113b1d84c34f 49 //char Cookie::_keyorder;
Pokitto 51:113b1d84c34f 50 //bool Cookie::_status;
Pokitto 51:113b1d84c34f 51
Pokitto 51:113b1d84c34f 52 #define HARDCODEDOFFSET 25 //bypasses Cookie parent instance general data (that does not need to be saved in EEPROM)
Pokitto 51:113b1d84c34f 53
Pokitto 51:113b1d84c34f 54 Cookie::Cookie() {
Pokitto 51:113b1d84c34f 55 _status = false;
Pokitto 51:113b1d84c34f 56 _keyorder = SBINVALIDSLOT;
Pokitto 51:113b1d84c34f 57 }
Pokitto 51:113b1d84c34f 58
Pokitto 51:113b1d84c34f 59 int Cookie::initialize() {
Pokitto 51:113b1d84c34f 60 //initialize is called from begin() and can be called several times during program run
Pokitto 51:113b1d84c34f 61 int datasize = _datasize;
Pokitto 51:113b1d84c34f 62 // check if key already exists
Pokitto 51:113b1d84c34f 63 _keyorder = exists(_key);
Pokitto 51:113b1d84c34f 64 if (_keyorder < SBMAXKEYS) {
Pokitto 51:113b1d84c34f 65 // key already exists
Pokitto 51:113b1d84c34f 66 // check amount of existing storage reserved for cookie
Pokitto 51:113b1d84c34f 67 datasize -= getAssignedBlocks()*SBBLOCKSIZE;
Pokitto 51:113b1d84c34f 68 if (datasize<=0) {
Pokitto 51:113b1d84c34f 69 // the size of data matches the size requested
Pokitto 51:113b1d84c34f 70 // therefore retrieve data from storage
Pokitto 51:113b1d84c34f 71 _status = true; //were good to go
Pokitto 51:113b1d84c34f 72 loadCookie();
Pokitto 51:113b1d84c34f 73 } else {
Pokitto 51:113b1d84c34f 74 // if that does not cover the whole size (maybe a newer version of program, who knows)
Pokitto 51:113b1d84c34f 75 // then do not load but reserve more blocks and store a new version
Pokitto 51:113b1d84c34f 76 while (datasize>0) {
Pokitto 51:113b1d84c34f 77 if(reserveBlock()) datasize -= SBBLOCKSIZE;
Pokitto 51:113b1d84c34f 78 else return SBNOTENOUGHBLOCKSFREE; //no space to allocate
Pokitto 51:113b1d84c34f 79 }
Pokitto 51:113b1d84c34f 80 _status = true; //were good to go
Pokitto 51:113b1d84c34f 81 eraseKeytableEntry(_keyorder);
Pokitto 51:113b1d84c34f 82 writeKeyToKeytable(_key,_keyorder); // write the key in the key table in EEPROM
Pokitto 51:113b1d84c34f 83 saveCookie();
Pokitto 51:113b1d84c34f 84 }
Pokitto 51:113b1d84c34f 85 } else {
Pokitto 51:113b1d84c34f 86 // new key needed
Pokitto 51:113b1d84c34f 87 // check if we have free keyslots
Pokitto 51:113b1d84c34f 88 _keyorder = getFreeKeytableSlot();
Pokitto 51:113b1d84c34f 89 if (_keyorder>=SBMAXKEYS) return SBNOMOREKEYS; //no space for key
Pokitto 51:113b1d84c34f 90 // check if we have free storage blocks
Pokitto 51:113b1d84c34f 91 if (getFreeBlocks()*SBBLOCKSIZE<datasize) return SBNOTENOUGHBLOCKSFREE; //no space to allocate
Pokitto 51:113b1d84c34f 92 while (datasize>0) {
Pokitto 51:113b1d84c34f 93 //reserve enough blocks for the data until all data can fit
Pokitto 51:113b1d84c34f 94 if(reserveBlock()) datasize -= SBBLOCKSIZE;
Pokitto 51:113b1d84c34f 95 else return SBNOTENOUGHBLOCKSFREE; //no space to allocate
Pokitto 51:113b1d84c34f 96 }
Pokitto 51:113b1d84c34f 97 }
Pokitto 51:113b1d84c34f 98 _status = true; //were good to go
Pokitto 51:113b1d84c34f 99 eraseKeytableEntry(_keyorder);
Pokitto 51:113b1d84c34f 100 writeKeyToKeytable(_key,_keyorder); // write the key in the key table in EEPROM
Pokitto 51:113b1d84c34f 101 return 0;
Pokitto 51:113b1d84c34f 102 }
Pokitto 51:113b1d84c34f 103
Pokitto 51:113b1d84c34f 104 int Cookie::begin(const char* idkey, int datasize, char* ptr) {
Pokitto 51:113b1d84c34f 105 _status=false;
Pokitto 51:113b1d84c34f 106 _datasize=datasize-HARDCODEDOFFSET;// warning! hardcoded! sizeof(this); //do not include the data of the parent Cookie instance
Pokitto 51:113b1d84c34f 107 _pointer = ptr + HARDCODEDOFFSET;// warning! hardcoded! sizeof(this); //point to the beginning of the inherited instance
Pokitto 51:113b1d84c34f 108 char _idkey[8];
Pokitto 51:113b1d84c34f 109 // make _idkey exactly 8 readable characters long
Pokitto 51:113b1d84c34f 110 for (int t = 0 ; t < 8 ; t++) _idkey[t]=' ';
Pokitto 51:113b1d84c34f 111 for (int t = 0 ; t < 8 ; t++) {if (idkey[t]==0) break; _idkey[t]=idkey[t];}
Pokitto 51:113b1d84c34f 112 // clean Keytable of keys with no storage
Pokitto 51:113b1d84c34f 113 cleanKeytable();
Pokitto 51:113b1d84c34f 114 memcpy(_key, _idkey, SBKEYSIZE); //store name of key
Pokitto 51:113b1d84c34f 115 initialize();
Pokitto 51:113b1d84c34f 116 return 0; //success
Pokitto 51:113b1d84c34f 117 }
Pokitto 51:113b1d84c34f 118
Pokitto 51:113b1d84c34f 119 bool Cookie::saveCookie() {
Pokitto 51:113b1d84c34f 120 if (!_status || !_pointer) initialize(); //reinitialize if needed
Pokitto 51:113b1d84c34f 121 if (!_status || !_pointer) return false; //return if initialize still failed
Pokitto 51:113b1d84c34f 122 char* p = _pointer;
Pokitto 51:113b1d84c34f 123 _head=0;
Pokitto 51:113b1d84c34f 124 _block=0;
Pokitto 51:113b1d84c34f 125 _block=findMyNextBlock();
Pokitto 51:113b1d84c34f 126 for (int i=0; i<_datasize; i++) writeQueue(*p++);
Pokitto 51:113b1d84c34f 127 }
Pokitto 51:113b1d84c34f 128
Pokitto 51:113b1d84c34f 129 bool Cookie::loadCookie() {
Pokitto 51:113b1d84c34f 130 if (!_status || !_pointer) return false;
Pokitto 51:113b1d84c34f 131 char* p = _pointer;
Pokitto 51:113b1d84c34f 132 _head=0;
Pokitto 51:113b1d84c34f 133 _block=0;
Pokitto 51:113b1d84c34f 134 _block=findMyNextBlock();
Pokitto 51:113b1d84c34f 135 for (int i=0; i<_datasize; i++) *p++ = readQueue();
Pokitto 51:113b1d84c34f 136 }
Pokitto 51:113b1d84c34f 137
Pokitto 51:113b1d84c34f 138 void Cookie::deleteCookie() {
Pokitto 51:113b1d84c34f 139 if (!_status) return;
Pokitto 51:113b1d84c34f 140 // free all blocks held by Cookie
Pokitto 51:113b1d84c34f 141 for (int i=0; i<SBMAXBLOCKS; i++) {
Pokitto 51:113b1d84c34f 142 if (isMyBlock(i)) freeBlock(i);
Pokitto 51:113b1d84c34f 143 }
Pokitto 51:113b1d84c34f 144 // erase Cookie entry from keytable
Pokitto 51:113b1d84c34f 145 eraseKeytableEntry(_keyorder);
Pokitto 51:113b1d84c34f 146 // set status to deleted
Pokitto 51:113b1d84c34f 147 _status = false;
Pokitto 51:113b1d84c34f 148 }
Pokitto 51:113b1d84c34f 149
Pokitto 51:113b1d84c34f 150 int Cookie::exists(const char* idkey) {
Pokitto 51:113b1d84c34f 151 for (int i=0; i< SBMAXKEYS; i++) {
Pokitto 51:113b1d84c34f 152 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 153 if(eeprom_read_byte((uint16_t*)(i*SBKEYSIZE))==idkey[0]) {
Pokitto 51:113b1d84c34f 154 int total=0;
Pokitto 51:113b1d84c34f 155 for (int j=0; j<SBKEYSIZE;j++) {
Pokitto 51:113b1d84c34f 156 if(eeprom_read_byte((uint16_t*)(i*SBKEYSIZE+j))==idkey[j]) total++;
Pokitto 51:113b1d84c34f 157 }
Pokitto 51:113b1d84c34f 158 if (total==SBKEYSIZE) return i; // return the keyslot number where key exists
Pokitto 51:113b1d84c34f 159 }
Pokitto 51:113b1d84c34f 160 #endif
Pokitto 51:113b1d84c34f 161 }
Pokitto 51:113b1d84c34f 162 return SBINVALIDSLOT; //not found
Pokitto 51:113b1d84c34f 163 }
Pokitto 51:113b1d84c34f 164
Pokitto 51:113b1d84c34f 165 int Cookie::getFreeKeytableSlot() {
Pokitto 51:113b1d84c34f 166 int freeslot=SBINVALIDSLOT;
Pokitto 51:113b1d84c34f 167 for (int i=0; i<SBMAXKEYS; i++) {
Pokitto 51:113b1d84c34f 168 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 169 if (eeprom_read_byte((uint16_t*)(i*SBKEYSIZE))==0) {freeslot=i; break;}
Pokitto 51:113b1d84c34f 170 #endif
Pokitto 51:113b1d84c34f 171 }
Pokitto 51:113b1d84c34f 172 return freeslot;
Pokitto 51:113b1d84c34f 173 }
Pokitto 51:113b1d84c34f 174
Pokitto 51:113b1d84c34f 175 int Cookie::getAssignedBlocks() {
Pokitto 51:113b1d84c34f 176 int assignedblocks=0;
Pokitto 51:113b1d84c34f 177 for (int i=0;i<SBMAXBLOCKS;i++) {
Pokitto 51:113b1d84c34f 178 if (isMyBlock(i)) assignedblocks++;
Pokitto 51:113b1d84c34f 179 }
Pokitto 51:113b1d84c34f 180 return assignedblocks;
Pokitto 51:113b1d84c34f 181 }
Pokitto 51:113b1d84c34f 182
Pokitto 51:113b1d84c34f 183 int Cookie::getFreeBlocks() {
Pokitto 51:113b1d84c34f 184 int freeblocks=0;
Pokitto 51:113b1d84c34f 185 for (int i=0;i<SBMAXBLOCKS;i++) {
Pokitto 51:113b1d84c34f 186 if (isFreeBlock(i)) freeblocks++;
Pokitto 51:113b1d84c34f 187 }
Pokitto 51:113b1d84c34f 188 return freeblocks;
Pokitto 51:113b1d84c34f 189 }
Pokitto 51:113b1d84c34f 190
Pokitto 51:113b1d84c34f 191 bool Cookie::isFreeBlock(int n) {
Pokitto 51:113b1d84c34f 192 if (n>=SBMAXBLOCKS) return false;
Pokitto 51:113b1d84c34f 193 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 194 if (!(eeprom_read_byte((uint16_t*)(SBMAXKEYS*SBKEYSIZE+n))&0x80)) return true; //highest bit 0, its free
Pokitto 51:113b1d84c34f 195 #endif
Pokitto 51:113b1d84c34f 196 return false; //its not free
Pokitto 51:113b1d84c34f 197 }
Pokitto 51:113b1d84c34f 198
Pokitto 51:113b1d84c34f 199 bool Cookie::isMyBlock(int n) {
Pokitto 51:113b1d84c34f 200 if (n>=SBMAXBLOCKS) return false;
Pokitto 51:113b1d84c34f 201 if (isFreeBlock(n)) return false; //"free" blocks can not be "reserved" at the same time!
Pokitto 51:113b1d84c34f 202 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 203 char temp; int address;
Pokitto 51:113b1d84c34f 204 address = (SBMAXKEYS*SBKEYSIZE+n);
Pokitto 51:113b1d84c34f 205 temp = eeprom_read_byte((uint16_t*)address);
Pokitto 51:113b1d84c34f 206 if ((temp&0x7F) ==_keyorder) return true;
Pokitto 51:113b1d84c34f 207 #endif
Pokitto 51:113b1d84c34f 208 return false; //its not your block
Pokitto 51:113b1d84c34f 209 }
Pokitto 51:113b1d84c34f 210
Pokitto 51:113b1d84c34f 211 bool Cookie::blockIsOwnedBy(int n, int k) {
Pokitto 51:113b1d84c34f 212 if (n>=SBMAXBLOCKS) return false;
Pokitto 51:113b1d84c34f 213 if (k>=SBMAXKEYS) return false;
Pokitto 51:113b1d84c34f 214 if (isFreeBlock(n)) return false; //"free" blocks can not be "owned" by anyone
Pokitto 51:113b1d84c34f 215 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 216 char temp; int address;
Pokitto 51:113b1d84c34f 217 address = (SBMAXKEYS*SBKEYSIZE+n);
Pokitto 51:113b1d84c34f 218 temp = eeprom_read_byte((uint16_t*)address);
Pokitto 51:113b1d84c34f 219 if ((temp&0x7F) == k) return true;
Pokitto 51:113b1d84c34f 220 #endif
Pokitto 51:113b1d84c34f 221 return false; //its not your block
Pokitto 51:113b1d84c34f 222 }
Pokitto 51:113b1d84c34f 223
Pokitto 51:113b1d84c34f 224 void Cookie::writeKeyToKeytable(const char* key, int slot) {
Pokitto 51:113b1d84c34f 225 for (int i=0; i<SBKEYSIZE; i++) {
Pokitto 51:113b1d84c34f 226 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 227 if (key[i]) eeprom_write_byte((uint16_t*)(slot*SBKEYSIZE+i),key[i]);
Pokitto 51:113b1d84c34f 228 else eeprom_write_byte((uint16_t*)(slot*SBKEYSIZE+i),0);
Pokitto 51:113b1d84c34f 229 #endif
Pokitto 51:113b1d84c34f 230 }
Pokitto 51:113b1d84c34f 231 }
Pokitto 51:113b1d84c34f 232
Pokitto 51:113b1d84c34f 233 void Cookie::readKeytableEntry(int n, char* answer) {
Pokitto 51:113b1d84c34f 234 answer[8]=0;
Pokitto 51:113b1d84c34f 235 if (n >= SBMAXKEYS) n=SBMAXKEYS-1;
Pokitto 51:113b1d84c34f 236 for (int i=0; i<SBKEYSIZE; i++) {
Pokitto 51:113b1d84c34f 237 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 238 answer[i] = eeprom_read_byte((uint16_t*)(n*SBKEYSIZE+i));
Pokitto 51:113b1d84c34f 239 #endif
Pokitto 51:113b1d84c34f 240 }
Pokitto 51:113b1d84c34f 241 }
Pokitto 51:113b1d84c34f 242
Pokitto 51:113b1d84c34f 243 char Cookie::getBlockTableEntry(int n) {
Pokitto 51:113b1d84c34f 244 if (n>=SBMAXBLOCKS) return 0x80; // out of bounds will return a reserved block marker
Pokitto 51:113b1d84c34f 245 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 246 return eeprom_read_byte((uint16_t*)(SBKEYSIZE*SBMAXKEYS+n));
Pokitto 51:113b1d84c34f 247 #endif
Pokitto 51:113b1d84c34f 248 return 0x80;
Pokitto 51:113b1d84c34f 249 }
Pokitto 51:113b1d84c34f 250
Pokitto 51:113b1d84c34f 251 void Cookie::readBlock(int n, char* data) {
Pokitto 51:113b1d84c34f 252 for (int i=0; i<SBBLOCKSIZE; i++) {
Pokitto 51:113b1d84c34f 253 data[i]=0;
Pokitto 51:113b1d84c34f 254 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 255 if (n < SBMAXBLOCKS) data[i] = eeprom_read_byte((uint16_t*)(SBKEYSIZE*SBMAXKEYS+SBMAXBLOCKS+n*SBBLOCKSIZE+i));
Pokitto 51:113b1d84c34f 256 #endif
Pokitto 51:113b1d84c34f 257 }
Pokitto 51:113b1d84c34f 258 }
Pokitto 51:113b1d84c34f 259
Pokitto 51:113b1d84c34f 260 void Cookie::formatKeytable() {
Pokitto 51:113b1d84c34f 261 for (int j=0; j<SBMAXKEYS; j++) {
Pokitto 51:113b1d84c34f 262 for (int i=0; i<SBKEYSIZE; i++) {
Pokitto 51:113b1d84c34f 263 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 264 eeprom_write_byte((uint16_t*)(j*SBKEYSIZE+i),0);
Pokitto 51:113b1d84c34f 265 #endif
Pokitto 51:113b1d84c34f 266 }
Pokitto 51:113b1d84c34f 267 }
Pokitto 51:113b1d84c34f 268 }
Pokitto 51:113b1d84c34f 269
Pokitto 51:113b1d84c34f 270 void Cookie::freeBlock(int n) {
Pokitto 51:113b1d84c34f 271 if (n >= SBMAXBLOCKS) return; //out of bounds
Pokitto 51:113b1d84c34f 272 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 273 // delete entry from blocktable
Pokitto 51:113b1d84c34f 274 eeprom_write_byte((uint16_t*)(SBKEYSIZE*SBMAXKEYS+n),0);
Pokitto 51:113b1d84c34f 275 #endif
Pokitto 51:113b1d84c34f 276 for (int i=0; i<SBBLOCKSIZE;i++) {
Pokitto 51:113b1d84c34f 277 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 278 // wipe data in the block
Pokitto 51:113b1d84c34f 279 eeprom_write_byte((uint16_t*)(SBKEYSIZE*SBMAXKEYS+SBMAXBLOCKS+n*SBBLOCKSIZE+i),0);
Pokitto 51:113b1d84c34f 280 #endif
Pokitto 51:113b1d84c34f 281 }
Pokitto 51:113b1d84c34f 282 }
Pokitto 51:113b1d84c34f 283
Pokitto 51:113b1d84c34f 284 bool Cookie::reserveBlock() {
Pokitto 51:113b1d84c34f 285 for (int i=0; i<SBMAXBLOCKS;i++) {
Pokitto 51:113b1d84c34f 286 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 287 // reserve block from blocktable
Pokitto 51:113b1d84c34f 288 if (isFreeBlock(i)) {
Pokitto 51:113b1d84c34f 289 //free block found, mark it for us in the blocktable
Pokitto 51:113b1d84c34f 290 eeprom_write_byte((uint16_t*)(SBKEYSIZE*SBMAXKEYS+i),_keyorder | 0x80);
Pokitto 51:113b1d84c34f 291 return true;
Pokitto 51:113b1d84c34f 292 }
Pokitto 51:113b1d84c34f 293 #endif
Pokitto 51:113b1d84c34f 294 }
Pokitto 51:113b1d84c34f 295 return false; // no free block found
Pokitto 51:113b1d84c34f 296 }
Pokitto 51:113b1d84c34f 297
Pokitto 51:113b1d84c34f 298 void Cookie::eraseKeytableEntry(int n) {
Pokitto 51:113b1d84c34f 299 if (n >= SBMAXKEYS) n=SBMAXKEYS-1;
Pokitto 51:113b1d84c34f 300 for (int i=0; i<SBKEYSIZE; i++) {
Pokitto 51:113b1d84c34f 301 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 302 eeprom_write_byte((uint16_t*)(n*SBKEYSIZE+i),0);
Pokitto 51:113b1d84c34f 303 #endif
Pokitto 51:113b1d84c34f 304 }
Pokitto 51:113b1d84c34f 305 }
Pokitto 51:113b1d84c34f 306
Pokitto 51:113b1d84c34f 307 void Cookie::cleanKeytable() {
Pokitto 51:113b1d84c34f 308 //Remove any keys without blocks
Pokitto 51:113b1d84c34f 309 for (int entry=0; entry<SBMAXKEYS; entry++) {
Pokitto 51:113b1d84c34f 310 if (eeprom_read_byte((uint16_t*)(entry*SBKEYSIZE))) {
Pokitto 51:113b1d84c34f 311 bool isEmpty=true;
Pokitto 51:113b1d84c34f 312 for (int block=0; block<SBMAXBLOCKS; block++) if (blockIsOwnedBy(block,entry)) {isEmpty=false;break;}
Pokitto 51:113b1d84c34f 313 //this entry has no blocks reserved, so lets clean it from the keytable
Pokitto 51:113b1d84c34f 314 if (isEmpty) eraseKeytableEntry(entry);
Pokitto 51:113b1d84c34f 315 }
Pokitto 51:113b1d84c34f 316 }
Pokitto 51:113b1d84c34f 317 for (int block=0;block<SBMAXBLOCKS;block++) {
Pokitto 51:113b1d84c34f 318 int blockentry = eeprom_read_byte((uint16_t*)(SBMAXKEYS*SBKEYSIZE+block));
Pokitto 51:113b1d84c34f 319 if (blockentry&0x80) {
Pokitto 51:113b1d84c34f 320 blockentry &= 0x7F;
Pokitto 51:113b1d84c34f 321 bool isEmpty=true;
Pokitto 51:113b1d84c34f 322 for (int key=0;key<SBMAXKEYS;key++) {
Pokitto 51:113b1d84c34f 323 if (eeprom_read_byte((uint16_t*)(key*SBKEYSIZE))) {isEmpty=false;break;}
Pokitto 51:113b1d84c34f 324 }
Pokitto 51:113b1d84c34f 325 if (isEmpty) eeprom_write_byte((uint16_t*)(SBMAXKEYS*SBKEYSIZE+block),0);
Pokitto 51:113b1d84c34f 326 }
Pokitto 51:113b1d84c34f 327 }
Pokitto 51:113b1d84c34f 328 }
Pokitto 51:113b1d84c34f 329
Pokitto 51:113b1d84c34f 330 char Cookie::readQueue() {
Pokitto 51:113b1d84c34f 331 char data=0;
Pokitto 51:113b1d84c34f 332 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 333 int address;
Pokitto 51:113b1d84c34f 334 address = SBMAXKEYS*SBKEYSIZE+SBMAXBLOCKS+SBBLOCKSIZE*_block+_head%SBBLOCKSIZE;
Pokitto 51:113b1d84c34f 335 data=eeprom_read_byte((uint16_t*)address);
Pokitto 51:113b1d84c34f 336 #endif
Pokitto 51:113b1d84c34f 337 _head++;
Pokitto 51:113b1d84c34f 338 if (_head%SBBLOCKSIZE==0 && _head) {
Pokitto 51:113b1d84c34f 339 _block++;
Pokitto 51:113b1d84c34f 340 _block=findMyNextBlock();
Pokitto 51:113b1d84c34f 341 }
Pokitto 51:113b1d84c34f 342 return data;
Pokitto 51:113b1d84c34f 343 }
Pokitto 51:113b1d84c34f 344
Pokitto 51:113b1d84c34f 345 void Cookie::writeQueue(char data) {
Pokitto 51:113b1d84c34f 346 #ifndef POK_SIM
Pokitto 51:113b1d84c34f 347 eeprom_write_byte((uint16_t*)(SBMAXKEYS*SBKEYSIZE+SBMAXBLOCKS+SBBLOCKSIZE*_block+_head%SBBLOCKSIZE),data);
Pokitto 51:113b1d84c34f 348 #endif
Pokitto 51:113b1d84c34f 349 _head++;
Pokitto 51:113b1d84c34f 350 if (_head%SBBLOCKSIZE==0 && _head) {
Pokitto 51:113b1d84c34f 351 _block++;
Pokitto 51:113b1d84c34f 352 _block=findMyNextBlock();
Pokitto 51:113b1d84c34f 353 }
Pokitto 51:113b1d84c34f 354 }
Pokitto 51:113b1d84c34f 355
Pokitto 51:113b1d84c34f 356 int Cookie::findMyNextBlock() {
Pokitto 51:113b1d84c34f 357 if (!_status) return SBINVALIDBLOCK;
Pokitto 51:113b1d84c34f 358 for (int i=_block; i<SBMAXBLOCKS;i++) if (isMyBlock(i)) return i;
Pokitto 51:113b1d84c34f 359 }
Pokitto 51:113b1d84c34f 360
Pokitto 51:113b1d84c34f 361
Pokitto 51:113b1d84c34f 362