GlobLib
HAL and API libraries for MCUs and hardware.
ucconfig.c
1 #include "ucconfig.h"
2 
3 //Flash read function pointer
4 static uint8_t (*ucconfig_fp_flashRead)(uint16_t address);
5 
6 //Flash write function pointer
7 static void (*ucconfig_fp_flashWrite)(uint8_t byte,uint16_t address);
8 
9 //Serial write function pointer
10 static void (*ucconfig_fp_serialWrite)(uint8_t byte);
11 
12 //Config mode exit function pointer
13 static void (*ucconfig_fp_onExit)(void);
14 
15 //Config mode enter function pointer
16 static void (*ucconfig_fp_onEnter)(void);
17 
18 //Config mode first write function pointer
19 static void (*ucconfig_fp_onFirstWrite)(void);
20 
21 //Keep track of number of varaibles written, used to determine when to call firstWrite FP
22 static uint16_t ucconfig_written;
23 
24 //True if in active config mode
25 static uint16_t ucconfig_activeMode;
26 
27 //Flash memory pointers
28 static uint16_t ucconfig_memPointer;
29 static uint16_t ucconfig_memPointerOffset;
30 
31 //FIFO used for serial communication
32 static FIFO8 ucconfig_fifo;
33 static uint8_t ucconfig_fifo_buffer[UCCONFIG_FIFO_SIZE];
34 
35 static void ucconfig_checkKey(uint8_t byte);
36 
37 //Main config loop, gets triggered by ucconfig_checkKey when a valid key is found
38 //The UC is 'Trapped' in this while(1) loop until a terminate command is sent or timeout occurs
39 static void ucconfig_active(void);
40 
41 //Determine if it is the first byte write operation
42 static void ucconfig_call_if_first(void);
43 
44 //Determine which command (if any) was sent
45 static void ucconfig_parseCommand();
46 
47 //A successful write data command was sent
48 static void ucconfig_write_data();
49 //A successful read data command was sent
50 static void ucconfig_read_data();
51 //A successful set address command was sent
52 static void ucconfig_set_address();
53 //A successful get address command was sent
54 static void ucconfig_get_address();
55 //Exits from config mode
56 static void ucconfig_terminate();
57 //Sent not acknowledge
58 static void ucconfig_sendNack();
59 //Sent acknowledge
60 static void ucconfig_sendAck();
61 //Sent not acknowledge
62 static void ucconfig_sendNack();
63 
64 //Send given data types back to PC when requested by read_data
65 static void ucconfig_send_u8(void);
66 static void ucconfig_send_8(void);
67 static void ucconfig_send_u16(void);
68 static void ucconfig_send_16(void);
69 static void ucconfig_send_u32(void);
70 static void ucconfig_send_32(void);
71 static void ucconfig_send_float(void);
72 static void ucconfig_send_char(void);
73 
74 //Write given data types to flash memory when requested by set_data
75 static void ucconfig_write_u8(char *data);
76 static void ucconfig_write_8(char *data);
77 static void ucconfig_write_u16(char *data);
78 static void ucconfig_write_16(char *data);
79 static void ucconfig_write_u32(char *data);
80 static void ucconfig_write_32(char *data);
81 static void ucconfig_write_float(char *data);
82 static void ucconfig_write_char(char *data);
83 
84 void UCCONFIG_loop(void){
85 
86  while(ucconfig_activeMode){
87 
88  for(volatile uint16_t i = 0; i < 0xFFF;i++);
89  ucconfig_activeMode--;
90  }
91 }
92 
93 /***********************************************************************/
94  //Function relating to the macro expansion of UCCONFIG_get()
95 /***********************************************************************/
96 
97 void UCCONFIG_setOnEnter(void (*on_enter)(void)){
98 
99  ucconfig_fp_onEnter = on_enter;
100 }
101 void UCCONFIG_setOnExit(void (*on_exit)(void)){
102 
103  ucconfig_fp_onExit = on_exit;
104 }
105 void UCCONFIG_setOnFirstWrite(void (*on_first)(void)){
106 
107  ucconfig_fp_onFirstWrite = on_first;
108 }
109 
110 void ucconfig_get_c(char *data,uint16_t address){
111 
112  ucconfig_memPointer = flash_get(data,address);
113  return;
114 }
115 
116 void ucconfig_get_u8(uint8_t *data,uint16_t address){
117 
118  ucconfig_memPointer = flash_get(data,address);
119  return;
120 }
121 
122 void ucconfig_get_8(int8_t *data,uint16_t address){
123 
124  ucconfig_memPointer = flash_get(data,address);
125  return;
126 }
127 
128 void ucconfig_get_u16(uint16_t *data,uint16_t address){
129 
130 
131  ucconfig_memPointer = flash_get(data,address);
132  return;
133 }
134 
135 void ucconfig_get_16(int16_t *data,uint16_t address){
136 
137  ucconfig_memPointer = flash_get(data,address);
138  return;
139 }
140 
141 void ucconfig_get_u32(uint32_t *data,uint16_t address){
142 
143  ucconfig_memPointer = flash_get(data,address);
144  return;
145 }
146 
147 void ucconfig_get_32(int32_t *data,uint16_t address){
148 
149  ucconfig_memPointer = flash_get(data,address);
150  return;
151 }
152 
153 void ucconfig_get_float(float *data,uint16_t address){
154 
155  ucconfig_memPointer = flash_get(data,address);
156  return;
157 }
158 
159 void UCCONFIG_setAddressOffset(uint16_t address){
160 
161  ucconfig_memPointerOffset = address;
162 }
163 
164 //Main config loop, gets triggered by ucconfig_checkKey when a valid key is found
165 void ucconfig_active(void){
166 
167  //Store the current function pointer for STRING11 output
168  void (*current_fp)(uint8_t) = STRING11_getOutput();
169 
170  //Store current flashwrite fp
171  void (*current_fw_fp)(uint8_t,uint16_t) = FLASHWRITE_getOutput();
172  uint8_t (*current_fr_fp)(uint16_t) = FLASHWRITE_getInput();
173 
174  //Set the output function for STRING_11 to serial fp, this allows use of all print functions
175  STRING11_setOutput(ucconfig_fp_serialWrite);
176 
177  //Setup flash output
178  FLASHWRITE_setOutput(ucconfig_fp_flashWrite);
179  FLASHWRITE_setInput(ucconfig_fp_flashRead);
180 
181  //Store the old FP in config fp for later resetting
182  ucconfig_fp_serialWrite = current_fp;
183  ucconfig_fp_flashWrite = current_fw_fp;
184  ucconfig_fp_flashRead = current_fr_fp;
185 
186  ucconfig_written = 0;
187 
188  ucconfig_sendAck();
189 
190  if(ucconfig_fp_onEnter != NULL){
191 
192  ucconfig_fp_onEnter();
193  }
194 
195  ucconfig_activeMode = UCCONFIG_ACTIVE_MODE_TIMEOUT;
196  return;
197 }
198 
199 //Called when a successful write command was initiated.
200 //If frame is valid writes the given data to flash
201 void ucconfig_write_data(){
202 
203  uint8_t dataLength;
204  uint8_t dataType;
205  char data[24]; //maximum size in characters of data i 24 bytes
206  uint8_t i;
207 
208  //Data type is checked later when branching to flash write functions
209  dataType = FIFO8_pop(&ucconfig_fifo);
210 
211  //Length is the capital letter of the aplphabet. eg. A = 1, C = 3
212  dataLength = FIFO8_pop(&ucconfig_fifo) - 64 ;
213 
214  //Check length, max length is 24
215  if((dataLength < 1) | (dataLength > 24)){
216 
217  ucconfig_sendNack();
218  return;
219  }
220 
221  //Next two should be not used charaters
222  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NOT_USED){
223  ucconfig_sendNack();
224  return;
225  }
226 
227  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NOT_USED){
228  ucconfig_sendNack();
229  return;
230  }
231 
232  for(i = 0; i < dataLength; i++){
233 
234  data[i] = FIFO8_pop(&ucconfig_fifo);
235 
236  //Check the data is only numbers
237  if((data[i] > 47) && (data[i] < 58)){
238 
239  }
240  //If there is a period, make sure the type is float
241  else if((data[i] == 46) && (dataType == UCCONFIG_TYPE_FLOAT)){
242 
243  }
244  //Check for minus for 8 bit
245  else if(data[i] == 45 && (dataType == UCCONFIG_TYPE_INT8_T)){
246 
247  }
248  //Check for minus for 16 bit
249  else if(data[i] == 45 && (dataType == UCCONFIG_TYPE_INT16_T)){
250 
251  }
252  //Check for minus for 32 bit
253  else if(data[i] == 45 && (dataType == UCCONFIG_TYPE_INT32_T)){
254 
255  }
256  //Check for minus for float
257  else if(data[i] == 45 && (dataType == UCCONFIG_TYPE_FLOAT)){
258 
259  }
260  //Char can be anything
261  else if(dataType == UCCONFIG_TYPE_CHAR){
262 
263  }
264  else{
265  //Not a valid data value
266  ucconfig_sendNack();
267  return;
268  }
269  }
270 
271  //Null should follow data
272  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NULL){
273  ucconfig_sendNack();
274  return;
275  }
276 
277  //Make sure data is correct length
278  if(i != dataLength){
279 
280  ucconfig_sendNack();
281  return;
282  }
283 
284  //Add a null character
285  data[i] = 0;
286 
287  //Branch and write data if the type was valid
288  switch(dataType){
289 
290  case UCCONFIG_TYPE_UINT8_T:
291  ucconfig_call_if_first();
292  ucconfig_write_u8(data);
293  break;
294  case UCCONFIG_TYPE_INT8_T:
295  ucconfig_call_if_first();
296  ucconfig_write_8(data);
297  break;
299  ucconfig_call_if_first();
300  ucconfig_write_u16(data);
301  break;
302  case UCCONFIG_TYPE_INT16_T:
303  ucconfig_call_if_first();
304  ucconfig_write_16(data);
305  break;
307  ucconfig_call_if_first();
308  ucconfig_write_u32(data);
309  break;
310  case UCCONFIG_TYPE_INT32_T:
311  ucconfig_call_if_first();
312  ucconfig_write_32(data);
313  break;
314  case UCCONFIG_TYPE_FLOAT:
315  ucconfig_call_if_first();
316  ucconfig_write_float(data);
317  break;
318  case UCCONFIG_TYPE_CHAR:
319  ucconfig_call_if_first();
320  ucconfig_write_char(data);
321  break;
322  default:
323  ucconfig_sendNack();
324  return;
325 
326  }
327 
328  ucconfig_written++;
329 
330  //All good, let PC know write is finished.
331  ucconfig_sendAck();
332 
333 }
334 static void ucconfig_call_if_first(void){
335 
336  if(ucconfig_written == 0){
337  ucconfig_fp_onFirstWrite();
338  }
339 
340  return;
341 
342 }
343 
344 /**************************************************************************/
345  //Individual data type writes to flash, called by ucconfig_write_data()
346 /**************************************************************************/
347 static void ucconfig_write_u8(char *data){
348 
349  uint8_t toWrite;
350  toWrite = str2uint(data);
351  ucconfig_memPointer = flash_put(toWrite,ucconfig_memPointer);
352 }
353 
354 static void ucconfig_write_8(char *data){
355 
356  int8_t toWrite;
357  toWrite = str2int(data);
358  ucconfig_memPointer = flash_put(toWrite,ucconfig_memPointer);
359 }
360 
361 static void ucconfig_write_u16(char *data){
362 
363  uint16_t toWrite;
364  toWrite = str2uint(data);
365  ucconfig_memPointer = flash_put(toWrite,ucconfig_memPointer);
366 }
367 
368 static void ucconfig_write_16(char *data){
369 
370  int16_t toWrite;
371  toWrite = str2int(data);
372  ucconfig_memPointer = flash_put(toWrite,ucconfig_memPointer);
373 }
374 
375 static void ucconfig_write_u32(char *data){
376 
377  uint32_t toWrite;
378  toWrite = str2uint(data);
379  ucconfig_memPointer = flash_put(toWrite,ucconfig_memPointer);
380 }
381 
382 static void ucconfig_write_32(char *data){
383 
384  int32_t toWrite;
385  toWrite = str2int(data);
386  ucconfig_memPointer = flash_put(toWrite,ucconfig_memPointer);
387 }
388 
389 static void ucconfig_write_float(char *data){
390 
391  float toWrite;
392  toWrite = str2float(data);
393  ucconfig_memPointer = flash_put(toWrite,ucconfig_memPointer);
394 }
395 
396 static void ucconfig_write_char(char *data){
397 
398  ucconfig_memPointer = flash_put((char)data[0],ucconfig_memPointer);
399 }
400 
401 //Called when a successful read data command was sent
402 //If frame is valid, sends read data to PC
403 //Responds with Nack frame is invalid
404 void ucconfig_read_data(){
405 
406  uint8_t dataType = FIFO8_pop(&ucconfig_fifo);
407 
408  //Length should be zero for get data
409  if((FIFO8_pop(&ucconfig_fifo) != UCCONFIG_LENGTH_ZERO)){
410 
411  ucconfig_sendNack();
412  return;
413  }
414 
415  //Next two should be not used charaters
416  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NOT_USED){
417  ucconfig_sendNack();
418  return;
419  }
420 
421  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NOT_USED){
422  ucconfig_sendNack();
423  return;
424  }
425 
426  //Last is Null character
427  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NULL){
428  ucconfig_sendNack();
429  return;
430  }
431 
432  switch(dataType){
433 
435  ucconfig_send_u8();
436  break;
438  ucconfig_send_8();
439  break;
441  ucconfig_send_u16();
442  break;
444  ucconfig_send_16();
445  break;
447  ucconfig_send_u32();
448  break;
450  ucconfig_send_32();
451  break;
452  case UCCONFIG_TYPE_FLOAT:
453  ucconfig_send_float();
454  break;
455  case UCCONFIG_TYPE_CHAR:
456  ucconfig_send_char();
457  break;
458  default:
459  ucconfig_sendNack();
460  break;
461  }
462 
463 }
464 /*****************************************************************************/
465  //These fectch a given data type from flash and send it to PC
466  //Called by ucconfig_read_data()
467 /*****************************************************************************/
468 void ucconfig_send_u8(void){
469 
470  //get data
471  uint8_t data;
472  ucconfig_memPointer = flash_get(&data,ucconfig_memPointer);
473 
474  print((char)UCCONFIG_READ_FRAME);
475  print((char)UCCONFIG_NULL);
478  print((char)UCCONFIG_NOT_USED);
479  print((char)UCCONFIG_NOT_USED);
480  print(data);
481  print((char)UCCONFIG_NULL);
482  print((char)UCCONFIG_FRAME_END);
483  print((char)UCCONFIG_NEWLINE);
484  return;
485 }
486 
487 void ucconfig_send_8(void){
488 
489  //get data
490  int8_t data;
491  ucconfig_memPointer = flash_get(&data,ucconfig_memPointer);
492 
493  print((char)UCCONFIG_READ_FRAME);
494  print((char)UCCONFIG_NULL);
497  print((char)UCCONFIG_NOT_USED);
498  print((char)UCCONFIG_NOT_USED);
499  print((int8_t)data);
500  print((char)UCCONFIG_NULL);
501  print((char)UCCONFIG_FRAME_END);
502  print((char)UCCONFIG_NEWLINE);
503  return;
504 }
505 
506 void ucconfig_send_u16(void){
507 
508  //get data
509  uint16_t data;
510  ucconfig_memPointer = flash_get(&data,ucconfig_memPointer);
511 
512  print((char)UCCONFIG_READ_FRAME);
513  print((char)UCCONFIG_NULL);
516  print((char)UCCONFIG_NOT_USED);
517  print((char)UCCONFIG_NOT_USED);
518  print(data);
519  print((char)UCCONFIG_NULL);
520  print((char)UCCONFIG_FRAME_END);
521  print((char)UCCONFIG_NEWLINE);
522  return;
523 }
524 
525 void ucconfig_send_16(void){
526 
527  //get data
528  int16_t data;
529  ucconfig_memPointer = flash_get(&data,ucconfig_memPointer);
530 
531  print((char)UCCONFIG_READ_FRAME);
532  print((char)UCCONFIG_NULL);
535  print((char)UCCONFIG_NOT_USED);
536  print((char)UCCONFIG_NOT_USED);
537  print(data);
538  print((char)UCCONFIG_NULL);
539  print((char)UCCONFIG_FRAME_END);
540  print((char)UCCONFIG_NEWLINE);
541  return;
542 }
543 
544 void ucconfig_send_u32(void){
545 
546  //get data
547  uint32_t data;
548  ucconfig_memPointer = flash_get(&data,ucconfig_memPointer);
549 
550  print((char)UCCONFIG_READ_FRAME);
551  print((char)UCCONFIG_NULL);
554  print((char)UCCONFIG_NOT_USED);
555  print((char)UCCONFIG_NOT_USED);
556  print(data);
557  print((char)UCCONFIG_NULL);
558  print((char)UCCONFIG_FRAME_END);
559  print((char)UCCONFIG_NEWLINE);
560  return;
561 }
562 
563 void ucconfig_send_32(void){
564 
565  //get data
566  int32_t data;
567  ucconfig_memPointer = flash_get(&data,ucconfig_memPointer);
568 
569  print((char)UCCONFIG_READ_FRAME);
570  print((char)UCCONFIG_NULL);
573  print((char)UCCONFIG_NOT_USED);
574  print((char)UCCONFIG_NOT_USED);
575  print(data);
576  print((char)UCCONFIG_NULL);
577  print((char)UCCONFIG_FRAME_END);
578  print((char)UCCONFIG_NEWLINE);
579  return;
580 }
581 
582 void ucconfig_send_float(void){
583 
584  //get data
585  float data;
586  ucconfig_memPointer = flash_get(&data,ucconfig_memPointer);
587 
588  print((char)UCCONFIG_READ_FRAME);
589  print((char)UCCONFIG_NULL);
590  print((char)UCCONFIG_TYPE_FLOAT);
592  print((char)UCCONFIG_NOT_USED);
593  print((char)UCCONFIG_NOT_USED);
594  print(data);
595  print((char)UCCONFIG_NULL);
596  print((char)UCCONFIG_FRAME_END);
597  print((char)UCCONFIG_NEWLINE);
598  return;
599 }
600 
601 void ucconfig_send_char(void){
602 
603  //get data
604  char data;
605  ucconfig_memPointer = flash_get(&data,ucconfig_memPointer);
606 
607  print((char)UCCONFIG_READ_FRAME);
608  print((char)UCCONFIG_NULL);
609  print((char)UCCONFIG_TYPE_CHAR);
611  print((char)UCCONFIG_NOT_USED);
612  print((char)UCCONFIG_NOT_USED);
613  print(data);
614  print((char)UCCONFIG_NULL);
615  print((char)UCCONFIG_FRAME_END);
616  print((char)UCCONFIG_NEWLINE);
617  return;
618 }
619 
620 //Sets the current memeory address of the flash pointer + offset
621 //Responds with ack if ok or nack if error in received frame.
622 void ucconfig_set_address(){
623 
624  uint8_t addressLength;
625  char address[6]; //maximum size in characters of 16 bit number is 5. +1 for NULL terminator
626  uint8_t i;
627 
628  //Frame pos 3 is type, should be none for address
629  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_TYPE_NONE){
630  ucconfig_sendNack();
631  return;
632  }
633 
634  //Length is the capital letter of the aplphabet. eg. A = 1, C = 3
635  addressLength = FIFO8_pop(&ucconfig_fifo) - 64 ;
636 
637  //Check length, a 16 bit number won't be longer than 5 digits
638  if((addressLength < 1) | (addressLength > 5)){
639 
640  ucconfig_sendNack();
641  return;
642  }
643 
644  //Next two should be not used charaters
645  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NOT_USED){
646  ucconfig_sendNack();
647  return;
648  }
649 
650  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NOT_USED){
651  ucconfig_sendNack();
652  return;
653  }
654 
655 
656  //Address should only contain numbers
657  for(i = 0; i < addressLength; i++){
658 
659  address[i] = FIFO8_pop(&ucconfig_fifo);
660 
661  if((address[i] < 48) | (address[i] > 57)){
662 
663  ucconfig_sendNack();
664  return;
665  }
666  }
667 
668  //Make sure the lenght of the address maches the acual data
669  if(i != addressLength){
670 
671  ucconfig_sendNack();
672  return;
673 
674  }
675 
676  //Null character last
677  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NULL){
678  ucconfig_sendNack();
679  return;
680  }
681 
682  address[i] = 0;
683 
684  //Set the memeory pointer address plus the offset.
685  ucconfig_memPointer = (uint16_t)str2int(address) + ucconfig_memPointerOffset;
686 
687  //All good
688  ucconfig_sendAck();
689 }
690 
691 //Sends the current memeory address of the flash to the PC
692 //Responds with Nack if received request frame is invalid.
693 void ucconfig_get_address(){
694 
695  //Frame pos 3 is type, should be none for getAddress
696  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_TYPE_NONE){
697  ucconfig_sendNack();
698  return;
699  }
700 
701  //Length should be zero for get address
702  if((FIFO8_pop(&ucconfig_fifo) != UCCONFIG_LENGTH_ZERO)){
703 
704  ucconfig_sendNack();
705  return;
706  }
707 
708  //Next two should be not used charaters
709  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NOT_USED){
710  ucconfig_sendNack();
711  return;
712  }
713 
714  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NOT_USED){
715  ucconfig_sendNack();
716  return;
717  }
718 
719  //Last is Null character
720  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NULL){
721  ucconfig_sendNack();
722  return;
723  }
724 
725  //Send that puppy
726  print((char)UCCONFIG_AT_ADDRESS);
727  print((char)UCCONFIG_NULL);
728  print((char)UCCONFIG_TYPE_NONE);
730  print((char)UCCONFIG_NOT_USED);
731  print((char)UCCONFIG_NOT_USED);
732  print(ucconfig_memPointer);
733  print((char)UCCONFIG_NULL);
734  print((char)UCCONFIG_FRAME_END);
735  print((char)UCCONFIG_NEWLINE);
736 }
737 
738 //Exit from config mode if the terminate frame was valid.
739 void ucconfig_terminate(){
740 
741  //Frame pos 3 is type, should be none for terminate
742  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_TYPE_NONE){
743  ucconfig_sendNack();
744  return;
745  }
746 
747  //Length should be zero for terminate
748  if((FIFO8_pop(&ucconfig_fifo) != UCCONFIG_LENGTH_ZERO)){
749 
750  ucconfig_sendNack();
751  return;
752  }
753 
754  //Next two should be not used charaters
755  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NOT_USED){
756  ucconfig_sendNack();
757  return;
758  }
759 
760  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NOT_USED){
761  ucconfig_sendNack();
762  return;
763  }
764 
765  //Last is Null character
766  if(FIFO8_pop(&ucconfig_fifo) != UCCONFIG_NULL){
767  ucconfig_sendNack();
768  return;
769  }
770 
771  //Everythin good send the acknowledge
772  ucconfig_sendAck();
773 
774  //Store the current function pointer for STRING11 output
775  void (*current_fp)(uint8_t) = STRING11_getOutput();
776 
777  //Store current flashwrite fp
778  void (*current_fw_fp)(uint8_t,uint16_t) = FLASHWRITE_getOutput();
779  uint8_t (*current_fr_fp)(uint16_t) = FLASHWRITE_getInput();
780 
781  //Set the output function for STRING_11 to serial fp, this allows use of all print functions
782  STRING11_setOutput(ucconfig_fp_serialWrite);
783 
784  //Setup flash output
785  FLASHWRITE_setOutput(ucconfig_fp_flashWrite);
786  FLASHWRITE_setInput(ucconfig_fp_flashRead);
787 
788  //Store the old FP in config fp for later resetting
789  ucconfig_fp_serialWrite = current_fp;
790  ucconfig_fp_flashWrite = current_fw_fp;
791  ucconfig_fp_flashRead = current_fr_fp;
792 
793  if(ucconfig_fp_onExit != NULL){
794 
795  ucconfig_fp_onExit();
796  }
797 
798  //Set the flag so active mode loop terminates
799  ucconfig_activeMode = 0;
800 }
801 
802 //Send not acknowledge
803 void ucconfig_sendNack(){
804 
805  print((char)UCCONFIG_NACK);
806  print((char)UCCONFIG_NULL);
807  print((char)UCCONFIG_FRAME_END);
808  print((char)UCCONFIG_NEWLINE);
809 }
810 
811 //Send acknowledge
812 void ucconfig_sendAck(){
813 
814  print((char)UCCONFIG_ACK);
815  print((char)UCCONFIG_NULL);
816  print((char)UCCONFIG_FRAME_END);
817  print((char)UCCONFIG_NEWLINE);
818 }
819 
820 //A frame end character was received
821 //Check the fifo buffer the see if a valid command exists
822 void ucconfig_parseCommand(){
823 
824  while(FIFO8_size(&ucconfig_fifo) > 0){
825 
826  switch(FIFO8_pop(&ucconfig_fifo)){
827 
828  case UCCONFIG_FRAME_END:
829 
830  //Nothing valid in the frame
831  return;
832  break;
833 
835 
836  if(FIFO8_pop(&ucconfig_fifo) == UCCONFIG_NULL){
837 
838  ucconfig_set_address();
839 
840  //Flush the rest of the FIFO
841  while(FIFO8_size(&ucconfig_fifo) > 0){
842 
843  FIFO8_pop(&ucconfig_fifo);
844  }
845  return;
846  }
847  break;
848 
850 
851  if(FIFO8_pop(&ucconfig_fifo) == UCCONFIG_NULL){
852 
853  ucconfig_write_data();
854 
855  //Flush the rest of the FIFO
856  while(FIFO8_size(&ucconfig_fifo) > 0){
857 
858  FIFO8_pop(&ucconfig_fifo);
859  }
860  return;
861  }
862  break;
863 
864  case UCCONFIG_READ_FRAME:
865 
866  if(FIFO8_pop(&ucconfig_fifo) == UCCONFIG_NULL){
867 
868  ucconfig_read_data();
869 
870  //Flush the rest of the FIFO
871  while(FIFO8_size(&ucconfig_fifo) > 0){
872 
873  FIFO8_pop(&ucconfig_fifo);
874  }
875  return;
876  }
877  break;
878 
879  case UCCONFIG_AT_ADDRESS:
880 
881  if(FIFO8_pop(&ucconfig_fifo) == UCCONFIG_NULL){
882 
883  ucconfig_get_address();
884 
885  //Flush the rest of the FIFO
886  while(FIFO8_size(&ucconfig_fifo) > 0){
887 
888  FIFO8_pop(&ucconfig_fifo);
889  }
890  return;
891  }
892  break;
893 
894  case UCCONFIG_TERMINATE:
895 
896  if(FIFO8_pop(&ucconfig_fifo) == UCCONFIG_NULL){
897  ucconfig_terminate();
898  return;
899  }
900  break;
901 
902  default:
903  break;
904  }
905  }
906 }
907 
908 //Setup the module
909 void UCCONFIG_setup(uint8_t (*flash_read)(uint16_t address),void (*flash_write)(uint8_t byte, uint16_t address),void (*serial_write)(uint8_t byte)){
910 
911  //Assign Function pointers for flash operations
912  ucconfig_fp_flashRead = flash_read;
913  ucconfig_fp_flashWrite = flash_write;
914 
915  //Assign function pointer for serial write
916  ucconfig_fp_serialWrite = serial_write;
917 
918  //Setup the received FIFO Object
919  FIFO8_init(&ucconfig_fifo,FIFO8_TRIGGER,ucconfig_fifo_buffer,UCCONFIG_FIFO_SIZE,&ucconfig_checkKey);
920 
921  FLASHWRITE_setOutput(flash_write);
922  FLASHWRITE_setInput(flash_read);
923 
924  //Initially inactive (running in background)
925  ucconfig_activeMode = 0;
926 }
927 
928 //This is called each time a byte is flushed from the FIFO
929 //Triggered by the UCCONFIG_listen when the FIFO has at least UCCONFIG_KEY_LENGTH bytes of key bytes
930 //If the key combination is found calls ucconfig_active()
931 void ucconfig_checkKey(uint8_t received){
932 
933  static uint8_t dump_pos = UCCONFIG_KEY_LENGTH;
934 
935  if(FIFO8_size(&ucconfig_fifo) > UCCONFIG_KEY_LENGTH){
936 
937  dump_pos = UCCONFIG_KEY_LENGTH;
938  return;
939  }
940 
941  switch(dump_pos){
942 
943  case 4:
944  if(received == UCCONFIG_KEY_1){
945 
946  if(FIFO8_size(&ucconfig_fifo) > UCCONFIG_KEY_LENGTH -1){
947  dump_pos--;
948  }
949  else{
950 
951  dump_pos = UCCONFIG_KEY_LENGTH;
952  }
953  }
954  else{
955  dump_pos = UCCONFIG_KEY_LENGTH;
956  }
957  break;
958  case 3:
959  if(received == UCCONFIG_KEY_2){
960 
961  if(FIFO8_size(&ucconfig_fifo) > UCCONFIG_KEY_LENGTH -2){
962  dump_pos--;
963  }
964  else{
965 
966  dump_pos = UCCONFIG_KEY_LENGTH;
967  }
968  }
969  else{
970  dump_pos = UCCONFIG_KEY_LENGTH;
971  }
972  break;
973  case 2:
974  if(received == UCCONFIG_KEY_3){
975 
976  if(FIFO8_size(&ucconfig_fifo) > UCCONFIG_KEY_LENGTH -3){
977  dump_pos--;
978  }
979  else{
980 
981  dump_pos = UCCONFIG_KEY_LENGTH;
982  }
983  }
984  else{
985  dump_pos = UCCONFIG_KEY_LENGTH;
986  }
987  break;
988  case 1:
989  if(received == UCCONFIG_KEY_4){
990 
991  //Sucsess
992  ucconfig_activeMode = UCCONFIG_ACTIVE_MODE_TIMEOUT;
993  dump_pos = UCCONFIG_KEY_LENGTH;
994  ucconfig_active();
995  }
996  else{
997  dump_pos = UCCONFIG_KEY_LENGTH;
998  }
999  break;
1000 
1001  default:
1002  dump_pos = UCCONFIG_KEY_LENGTH;
1003  break;
1004  }
1005 }
1006 
1007 void UCCONFIG_listen(uint8_t received){
1008 
1009  //If in active mode, check if a frame end character was received.
1010  if(ucconfig_activeMode){
1011 
1012  //Reload the timeout
1013  ucconfig_activeMode = UCCONFIG_ACTIVE_MODE_TIMEOUT;
1014 
1015  //Frame end receive, check if a valid command existed
1016  if(received == UCCONFIG_FRAME_END){
1017 
1018  FIFO8_put(&ucconfig_fifo,received);
1019  ucconfig_parseCommand();
1020  }
1021  else{
1022 
1023  //No frame end just fill the FIFO
1024  FIFO8_put(&ucconfig_fifo,received);
1025  }
1026  return;
1027  }
1028 
1029  //Check if the character received is at the end of the key. If it is make sure
1030  //There is enough characters in the fifo
1031  if((received == UCCONFIG_KEY_4) && (FIFO8_size(&ucconfig_fifo) >= (UCCONFIG_KEY_LENGTH-1))){
1032 
1033  FIFO8_put(&ucconfig_fifo,received);
1034  FIFO8_flush(&ucconfig_fifo);
1035  }
1036  //Not enough characters, only append to the FIFO characters which are part of the key
1037  else{
1038 
1039  switch(received){
1040 
1041  case UCCONFIG_KEY_1:
1042  FIFO8_put(&ucconfig_fifo,received);
1043  break;
1044  case UCCONFIG_KEY_2:
1045  FIFO8_put(&ucconfig_fifo,received);
1046  break;
1047  case UCCONFIG_KEY_3:
1048  FIFO8_put(&ucconfig_fifo,received);
1049  break;
1050  case UCCONFIG_KEY_4:
1051  FIFO8_put(&ucconfig_fifo,received);
1052  break;
1053  default:
1054  break;
1055  }
1056  }
1057  return;
1058 }
void ucconfig_get_u32(uint32_t *data, uint16_t address)
Get a uint32 from the given memory address.
Definition: ucconfig.c:141
float str2float(char *buffer)
Convert a null terminated string to a float.
Definition: string11.c:76
void UCCONFIG_setAddressOffset(uint16_t address)
Set the memory address offset of the flash memory pointer (optional)
Definition: ucconfig.c:159
#define UCCONFIG_KEY_3
Key character 3.
Definition: ucconfig.h:71
#define UCCONFIG_KEY_4
Key character 4.
Definition: ucconfig.h:75
#define UCCONFIG_TYPE_CHAR
ASCII character used for char types.
Definition: ucconfig.h:165
void UCCONFIG_loop(void)
Runs config mode if the key has been received.
Definition: ucconfig.c:84
void ucconfig_get_u16(uint16_t *data, uint16_t address)
Get a uint16 from the given memory address.
Definition: ucconfig.c:128
void UCCONFIG_setOnExit(void(*on_exit)(void))
Sets the function which is called when config mode is exited (optional)
Definition: ucconfig.c:101
void ucconfig_get_u8(uint8_t *data, uint16_t address)
Get a uint8 from the given memory address.
Definition: ucconfig.c:116
void FLASHWRITE_setInput(uint8_t(*in_fun)(uint16_t))
Set the target input stream for flash_get functions.
Definition: flashWrite.c:28
void ucconfig_get_16(int16_t *data, uint16_t address)
Get a int16 from the given memory address.
Definition: ucconfig.c:135
void UCCONFIG_setOnEnter(void(*on_enter)(void))
Sets the function which is called when config mode is entered (optional)
Definition: ucconfig.c:97
#define UCCONFIG_NACK
Command used to not acknowledge a command.
Definition: ucconfig.h:112
#define print(X)
Print a given datatype to the output stream.
Definition: string11.h:60
void STRING11_setOutput(void(*out_fun)(uint8_t))
Set the target output stream for print functions.
Definition: string11.c:122
v_fp_u8_u16 FLASHWRITE_getOutput(void)
Get the current target output stream.
Definition: flashWrite.c:34
v_fp_u8 STRING11_getOutput(void)
Get the current target output stream.
Definition: string11.c:128
#define UCCONFIG_TERMINATE
Command used to exit from commmand mode.
Definition: ucconfig.h:100
#define UCCONFIG_ACTIVE_MODE_TIMEOUT
Number of loop iterratios before automattically exits from active mode.
Definition: ucconfig.h:169
#define UCCONFIG_KEY_LENGTH
The length of the key which the PC needs to send to enter Config mode.
Definition: ucconfig.h:59
void UCCONFIG_setOnFirstWrite(void(*on_first)(void))
Sets the function which is called when the first byte is written to the UC from PC.
Definition: ucconfig.c:105
#define UCCONFIG_TYPE_INT16_T
ASCII character used for int16_t types.
Definition: ucconfig.h:149
#define UCCONFIG_TYPE_FLOAT
ASCII character used for float types.
Definition: ucconfig.h:161
#define UCCONFIG_TYPE_UINT8_T
ASCII character used for uint8_t types.
Definition: ucconfig.h:137
#define UCCONFIG_SET_MEMORY_ADDRESS
Command used to initiate setting the memory address pointer.
Definition: ucconfig.h:88
uint16_t FIFO8_size(FIFO8 *target)
Return the size in bytes of the FIFO8 buffer.
Definition: fifo8.c:90
#define flash_put(DATA, ADDRESS)
Flash a given datatype to the output stream.
Definition: flashWrite.h:56
void FLASHWRITE_setOutput(void(*out_fun)(uint8_t, uint16_t))
Set the target output stream for flash_put functions.
Definition: flashWrite.c:22
#define UCCONFIG_LENGTH_ZERO
ASCII character used for zero length data frames.
Definition: ucconfig.h:129
fifo8_error_t FIFO8_put(FIFO8 *target, uint8_t byte)
Adds a character to the buffer.
Definition: fifo8.c:20
int32_t str2int(char *buffer)
Convert a null terminated string to an integer.
Definition: string11.c:21
#define UCCONFIG_READ_FRAME
Command used to initial reading data.
Definition: ucconfig.h:96
#define UCCONFIG_SET_WRITE_FRAME
Command used to initial writing data.
Definition: ucconfig.h:92
uint8_t FIFO8_pop(FIFO8 *target)
Reset the fifo buffer and set its size to 0.
Definition: fifo8.c:108
fifo8_error_t FIFO8_init(FIFO8 *target, fifo8_mode_t mode, uint8_t *buffer, uint16_t size, void(*output)(uint8_t byte))
Initializes the FIFO8 buffer.
Definition: fifo8.c:64
u8_fp_u16 FLASHWRITE_getInput(void)
Get the current target input stream.
Definition: flashWrite.c:43
fifo8_error_t FIFO8_flush(FIFO8 *target)
Flush all contents of the FIFO8 to the output function.
Definition: fifo8.c:95
void ucconfig_get_8(int8_t *data, uint16_t address)
Get a int8 from the given memory address.
Definition: ucconfig.c:122
#define UCCONFIG_TYPE_UINT16_T
ASCII character used for uint16_t types.
Definition: ucconfig.h:145
#define UCCONFIG_TYPE_NONE
ASCII character used for none types.
Definition: ucconfig.h:133
void ucconfig_get_c(char *data, uint16_t address)
Get a character from the given memory address.
Definition: ucconfig.c:110
#define flash_get(DATA, ADDRESS)
Read a given datatype from the input stream.
Definition: flashWrite.h:70
void ucconfig_get_32(int32_t *data, uint16_t address)
Get a int32 from the given memory address.
Definition: ucconfig.c:147
Header file for UCConfig module.
#define UCCONFIG_TYPE_UINT32_T
ASCII character used for uint32_t types.
Definition: ucconfig.h:153
#define UCCONFIG_NULL
ASCII character used for NULL.
Definition: ucconfig.h:116
#define UCCONFIG_KEY_2
Key character 2.
Definition: ucconfig.h:67
#define UCCONFIG_KEY_1
Key character 1.
Definition: ucconfig.h:63
#define UCCONFIG_FIFO_SIZE
The size of the FIFO used by the module, don&#39;t change this.
Definition: ucconfig.h:79
void ucconfig_get_float(float *data, uint16_t address)
Get a float from the given memory address.
Definition: ucconfig.c:153
#define UCCONFIG_NEWLINE
ASCII character used for new line, UC needs to send this so python module can easly pick end of comma...
Definition: ucconfig.h:125
#define UCCONFIG_FRAME_END
The frame and character.
Definition: ucconfig.h:84
uint32_t str2uint(char *buffer)
Convert a null terminated string to an unsigned integer.
Definition: string11.c:56
#define UCCONFIG_TYPE_INT32_T
ASCII character used for int32_t types.
Definition: ucconfig.h:157
Fifo content flushed to output function on call FIFO_flush()
Definition: fifo8.h:48
#define UCCONFIG_TYPE_INT8_T
ASCII character used for int8_t types.
Definition: ucconfig.h:141
Data structure for FIFO8 perihperal interface.
Definition: fifo8.h:75
void UCCONFIG_listen(uint8_t received)
Listens to serial communication and sets module in config mode if correct key is sent.
Definition: ucconfig.c:1007
#define UCCONFIG_AT_ADDRESS
Command used get the current memory addresss pointer.
Definition: ucconfig.h:104
#define UCCONFIG_NOT_USED
ASCII character used for Not used.
Definition: ucconfig.h:120
#define UCCONFIG_ACK
Command used to acknowledge a command.
Definition: ucconfig.h:108
void UCCONFIG_setup(uint8_t(*flash_read)(uint16_t address), void(*flash_write)(uint8_t byte, uint16_t adrress), void(*serial_write)(uint8_t byte))
Set up the module, this should be called before any other module function will work.