UoS³ Flight Computer Firmware
 All Data Structures Files Functions Groups Pages
camtest.c
1 //
2 // camera test
3 //
4 // Suzanna Lucarotti (c) 22/09/2017
5 //
6 // for use with the UoS3 Cubesat
7 //
8 
9 #include "../firmware.h"
10 
11 #include "inc/hw_memmap.h"
12 #include "inc/hw_types.h"
13 
14 #include "driverlib/gpio.h"
15 #include "driverlib/i2c.h"
16 #include "driverlib/pin_map.h"
17 #include "driverlib/sysctl.h"
18 
19 #include <stdlib.h>
20 #include <stdarg.h>
21 
22 //#define DEBUG_SERIAL UART_CAMERA // this is the serial port debug messages will come through (UART_CAMERA or UART_GNSS)
23 #define GPS_SERIAL UART_GNSS
24 #define CAM_SERIAL UART_CAMERA
25 
26 #define DEBUG_SERIAL GPS_SERIAL
27 
28 #define sz(a) a,sizeof(a)
29 
30 
31 //LK_POWERUP[] = {0x0a, 0x49, 0x6e, 0x69, 0x74, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a};
32 char LK_POWERUP[] = {0x0d, 0x0a, 0x00, 0x0d, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a}; // Init end
33 //LK_POWERUP[] = {0x0d,0x0a,0,4,0,0x49,0x68,0x69,0x68,0x20,0x65,0xc,0};
34 
35 char LK_BAUDRATE_19200[] ={0x56, 0x00, 0x24, 0x03, 0x01, 0x56, 0xe4};
36 char LK_BAUDRATE_38400[] = {0x56, 0x00, 0x24, 0x03, 0x01, 0x2a, 0xf2};
37 char LK_BAUDRATE_RE[] = {0x76, 0x00, 0x24, 0x00, 0x00};
38 
39 char LK_RESOLUTION_VGA[] = {0x56, 0x00, 0x54, 0x01, 0x00};
40 char LK_RESOLUTION_800[] = {0x56, 0x00, 0x54, 0x01, 0x1D};
41 char LK_RESOLUTION_1280[] = {0x56, 0x00, 0x54, 0x01, 0x1B};
42 char LK_RESOLUTION_1600[] = {0x56, 0x00, 0x54, 0x01, 0x21};
43 char LK_RESOLUTION_RE[] = {0x76, 0x00, 0x54, 0x00, 0x00}; // v T
44 
45 char LK_COMPRESSION[] = {0x56, 0x00, 0x31, 0x05, 0x01, 0x01, 0x12, 0x04};
46 char LK_COMPRESSION_RE[] = {0x76, 0x00, 0x31, 0x00, 0x00}; // v 1
47 
48 char LK_RESET[] = {0x56, 0x00, 0x26, 0x00};
49 // OLD: LK_RESET_RE[] = a2s([0x0d, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a])
50 // LEGIT: LK_RESET_RE[] = a2s([0x76,0x00,0x31,0x00,0x00])
51 char LK_RESET_RE[] = {0x0d, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x20, 0x65, 0x6e, 0x64, 0x0d, 0x0a};
52 
53 char LK_PICTURE[] = {0x56, 0x00, 0x36, 0x01, 0x00};
54 char LK_PICTURE_RE[] = {0x76, 0x00, 0x36, 0x00, 0x00};
55 char LK_JPEGSIZE[] = {0x56, 0x00, 0x34, 0x01, 0x00};
56 char LK_JPEGSIZE_RE[] = {0x76, 0x00, 0x34, 0x00, 0x04}; //, 0x00, 0x00, 0x00, 0x00}; // then XH XL // assumption is last 4 bytes are size
57 char LK_STOP[] = {0x56, 0x00, 0x36, 0x01, 0x03};
58 char LK_STOP_RE[] = {0x76, 0x00, 0x36, 0x00, 0x00};
59 
60 char LK_READPICTURE[] = {0x56, 0x00, 0x32, 0x0C, 0x00, 0x0A};
61 char LK_PICTURE_TIME[] = {0x00, 0x0A}; // .1 ms
62 char LK_READPICTURE_RE[] = {0x76, 0x00, 0x32, 0x00, 0x00};
63 char JPEG_START[] = {0xFF, 0xD8};
64 char JPEG_END[] = {0xFF, 0xD9};
65 
66 
67 
68 // Wrappers for printing to serial port - always to the one specified as output, placed here close to code for clarity
69 
70 #define STRING_BUFFER_LENGTH 20 // rough hack for testing
71 
72 static char string_buffer[STRING_BUFFER_LENGTH];
73 static char string_buffer2[STRING_BUFFER_LENGTH];
74 
75 static void UART_putnum(unsigned int serialport,signed long x)
76  {
77  itoa(abs(x),string_buffer,16); // 16 for hex, 10 for decimal
78  unsigned int len=strlen(string_buffer);
79  unsigned int targetlen=6-len;
80  strcpy(string_buffer2,"+00000");
81  strcpy(string_buffer2+targetlen,string_buffer);
82  if (x<0) string_buffer2[0]='-';
83  UART_puts(serialport,string_buffer2);
84 }
85 
86 static void UART_putstr(unsigned int serialport, char *s1,signed long x, char *s2)
87  {
88  if (s1!=NULL) UART_puts(serialport,s1);
89  UART_putnum(serialport,x);
90  if (s2!=NULL) UART_puts(serialport,s2);
91  }
92 
93 #define DISP3(x,y,z) UART_putstr(DEBUG_SERIAL,x,y,z); // x and z are strings, y is a number shown as signed base10 16bit
94 #define DISP2(y,z) UART_putstr(DEBUG_SERIAL,NULL,y,z);
95 #define DISP1(x) UART_puts(DEBUG_SERIAL,x);
96 
98  // the actual main code
100 
101 unsigned int UART_getw(long int serial)
102  {
103  char c1=UART_getc(serial),c2=UART_getc(serial);
104  return (c1<<8)|c2;
105  }
106 
107 unsigned int UART_getw4(long int serial)
108  {
109  char c1=UART_getc(serial),c2=UART_getc(serial),c3=UART_getc(serial),c4=UART_getc(serial);
110  return (c1<<24)|(c2<<16)|(c3<<8)|(c4<<0);
111  }
112 
113 
114 void mem_packet_send (char *start_addr, unsigned int len) // this copied over from mem_debug
115  {
116  // send byte data from a given address and send down serial line DEBUG_SERIAL
117  // will hang processor if address wrong
118  // lets put a CRC check on the packet
119  // for CRC gonna use xor initially for speed of implementation
120 
121  UART_putc(DEBUG_SERIAL,'@');
122 
123  unsigned char x=0;
124  for (char *addr=start_addr;addr<start_addr+len;addr++)
125  {
126  unsigned int s_addr= (int) start_addr;
127  char c=*addr;
128  UART_putc(DEBUG_SERIAL,c);
129  x=x ^ c;
130  }
131  UART_putc(DEBUG_SERIAL,'|');
132  UART_putc(DEBUG_SERIAL,x); // write the check byte
133 
134  }
135 
136 bool match_string(char *data, unsigned int len) // packed to call with sz(data)
137  {
138  // DISP1("Matching '");UART_putb(DEBUG_SERIAL,data,len);DISP1("'\n\r");
139  for (int i=0;i<len;i++) { char c=UART_getc(CAM_SERIAL); /*DISP3("*",c,"*"); */ if (c!=data[i]) return false; }
140 return true;
141  }
142 
143  unsigned int getcamword()
144  {
145  return UART_getw4(CAM_SERIAL);
146 // char c1=UART_getc(CAM_SERIAL),c2=UART_getc(CAM_SERIAL),c3=UART_getc(CAM_SERIAL),c4=UART_getc(CAM_SERIAL);
147 // return c1<<24|c2<<16|c3<<8|c4;
148  }
149 
150  void writeword4(int serial,unsigned int w)
151  {
152  UART_putc(serial,(w>>24)&255);UART_putc(serial,(w>>16)&255);UART_putc(serial,(w>>8)&255);UART_putc(serial,w & 255);
153 // DISP3("Just pasted0 ",(w>>24)&255,"\r\n");
154 // DISP3("Just pasted1 ",(w>>16)&255,"\r\n");
155 // DISP3("Just pasted2 ",(w>>8)&255,"\r\n");
156 // DISP3("Just pasted3 ",(w)&255,"\r\n");
157  }
158 
159  void writecamword(unsigned int w)
160  {
161  writeword4(CAM_SERIAL,w);
162  }
163 
164  #define CAMWRITE(a) UART_putb(CAM_SERIAL,a,sizeof(a)); // send this message
165 
166  #define CAMREAD(a) while (!match_string(a,sizeof(a))) {/*UART_putc(DEBUG_SERIAL,'.');*/} // wait for this sequence (forever if necessary)
167 
168 unsigned int get_picture_part(unsigned int offset, unsigned int len, char *storage_addr)
169  {
170  if (((((int)storage_addr)>>10)*1024)!=storage_addr) DISP3("Bad storage address for picture part",storage_addr,"\n\r");
171  // offset=offset; // must be 8 byte boundary
172  //DISP1("GET PICTURE PART\r\n");
173  //DISP3("Offset: ",offset,"\r\n");
174  //DISP3("Length: ",len,"\r\n");
175  //DISP3("Storage Addr: ",storage_addr,"\r\n");
176 
177  unsigned int pages_to_clear=(len+1023)>>10; // this processor's flash is in 1k blocks, these need to be erased before writing to
178 
179  //DISP3("Pages to clear",pages_to_clear,"\r\n");
180  for (int i=0;i<pages_to_clear;i++)
181  if (FlashErase(storage_addr+i*1024)==-1) DISP1("PROTECTED FLASH!");
182 
183  //DISP1("Erased\r\n");
184 
185  char flash_word_size=4;
186  char flash_buffer[flash_word_size];
187 
188  char endfoundcount=0;
189  unsigned int i=0;
190  unsigned int j=0; // counter for flash writes
191 
192  //DISP1("Preparing buffers")
193 
194  //while (UART_busy(DEBUG_SERIAL) || UART_busy(CAM_SERIAL)) {} // wait for tx buffer clear
195 
196  //while (UART_charsAvail(CAM_SERIAL)) {char c=UART_getc(CAM_SERIAL);} // empty receive buffer
197 
198 // Delay_ms(100); // is this a speed thing? - too fast and it crashes after 3 calls
199 
200  DISP1("Sending message.\n")
201 
202  CAMWRITE(LK_READPICTURE);
203  writecamword(offset); // offset in file start (0 here)
204  writecamword(len-1); // write length to obtain +8 bytes?
205  CAMWRITE(LK_PICTURE_TIME);//DISP1("awaiting read response\n\r");
206  CAMREAD(LK_READPICTURE_RE);//DISP1("PICTURE READ part requested\n\r");
207 
208  i=0;
209  char c;
210 
211  // DISP1("Copying to flash\r\n");
212 
213  while ((endfoundcount<2) && (i<len))
214  {
215  // DISP3("i = ",i,"\r\n")
216 // DISP3("j = ",j,"\r\n")
217  // DISP3("efc = ",endfoundcount,"\r\n")
218  char c=UART_getc(CAM_SERIAL);
219  if (c==JPEG_END[endfoundcount]) endfoundcount+=1; else endfoundcount=0; // should progress through end template
220  flash_buffer[j++]=c;
221  if (j==flash_word_size) {j=0;
222  if (FlashProgram(flash_buffer,storage_addr+i,flash_word_size)==-1)
223  {
224  DISP3("FLASH PROGRAMMING ERROR ",storage_addr+i,"\r\n");
225  DISP3("tried to set to ",(unsigned int) *flash_buffer,"\r\n");
226  DISP3("actually set to ",(unsigned int) storage_addr[i],"\r\n");
227  }
228  // if ((i&63)==56) {DISP3(" <",i,">");}
229  // if (i>1015) { DISP3("i = ",i,"");DISP3("j = ",j,"\r\n");DISP3("efc = ",endfoundcount,"\r\n");}
230 
231  i+=flash_word_size;}
232  }
233 
234  // DISP3("i = ",i,"\r\n")
235  // DISP3("j = ",j,"\r\n")
236  // DISP3("efc = ",endfoundcount,"\r\n")
237 
238 
239  //DISP1("Copy complete \r\n");
240 
241  unsigned int picturelength=i+j; //jpegsize; //i+j;
242 
243  if (j>0)
244  {
245  while (j<flash_word_size) {flash_buffer[j++]=0;}
246  FlashProgram(flash_buffer,storage_addr+i,flash_word_size); // do final one (excess bytes from previous)
247  }
248 
249  // DISP3("Last four : ",storage_addr[picturelength-4],",");DISP3(" ",storage_addr[picturelength-3],",");
250  // DISP3(" ",storage_addr[picturelength-2],",");DISP3(" ",storage_addr[picturelength-1],"\n\r");
251 
252 // DISP3("ENDFOUNDCOUNT = ",endfoundcount,"\n\r")
253  DISP3("Downloaded ",picturelength," bytes of image data\n\r")
254  return picturelength;
255  }
256 
257 unsigned int take_picture(char *picture_storage)
258  {
259  if (((unsigned int) picture_storage)&3!=0) {DISP1("address must be word aligned");return 0;}
260 
261  DISP3(" Take Picture Storage Address: ",picture_storage,"\n\r");
262 
263  CAMWRITE(LK_RESET);CAMREAD(LK_RESET_RE);DISP1("Initialised OK\n\r"); // initialise camera
264 
265  Delay_ms(1000); // 2-3 sec gap required by data sheet before camera ready
266 
267  CAMWRITE(LK_RESOLUTION_1600);CAMREAD(LK_RESOLUTION_RE);DISP1("Resolution OK\n\r"); // set resolution
268  CAMWRITE(LK_COMPRESSION);UART_putc(CAM_SERIAL,0x10);CAMREAD(LK_COMPRESSION_RE);DISP1("Compression OK\n\r"); // set compression
269  CAMWRITE(LK_PICTURE);CAMREAD(LK_PICTURE_RE);DISP1("Take Picture OK\n\r"); // take picture
270  CAMWRITE(LK_JPEGSIZE);CAMREAD(LK_JPEGSIZE_RE);unsigned int jpegsize=getcamword(); // file size (lowest 32 bits)
271  DISP3("Picture size is ",jpegsize," bytes of image data\n\r");
272 
273 
274 /*
275  unsigned int pages_to_clear=(jpegsize+1023)>>10; // this processor's flash is in 1k blocks, these need to be erased before writing to
276 
277  DISP3("Ready to download to board :",pages_to_clear," pages\r\n");
278  unsigned int copied=1024,i=0;
279  while (copied==1024 && i<pages_to_clear)
280  {copied=get_picture_part(i*1024,1024,picture_storage+i*1024);
281  i++;
282  }
283 
284  ;; unsigned int picturelength=(i-1)*1024+copied; //jpegsize; //i+j;
285  */
286  unsigned int picturelength=get_picture_part(0,jpegsize,picture_storage);
287 
288  DISP1("Copy complete \r\n");
289 
290  DISP3("Downloaded ",picturelength," bytes of image data\n\r")
291  return picturelength;
292  }
293 
294  void send_packet(cmd,value)
295  {
296  bool packet_not_sent=true;
297  // while (packet_not_sent)
298  // {
299  // UART_putc(DEBUG_SERIAL,'X');DISP3("'",cmd,"'");
300  UART_putc(DEBUG_SERIAL,cmd);
301  writeword4(DEBUG_SERIAL,value);
302  // Delay_ms(100); // wait for response
303  // char c=UART_getc(DEBUG_SERIAL);UART_putc(DEBUG_SERIAL,'*');UART_putc(DEBUG_SERIAL,c);
304  // while (c!='A') {c=UART_getc(DEBUG_SERIAL);UART_putc(DEBUG_SERIAL,'!');UART_putc(DEBUG_SERIAL,c);}
305  // if (UART_getc(DEBUG_SERIAL)=='C' && UART_getc(DEBUG_SERIAL)=='K' && UART_getc(DEBUG_SERIAL)==cmd) packet_not_sent=false;
306  // if (packet_not_sent) DISP1("Ack not received\r\n") else DISP1("Ack received")
307  // }
308  }
309 
310  void ack(unsigned char cmd)
311  {
312  UART_putc(DEBUG_SERIAL,'A');
313  UART_putc(DEBUG_SERIAL,'C');
314  UART_putc(DEBUG_SERIAL,'K');
315  UART_putc(DEBUG_SERIAL,cmd);
316  }
317 
318  unsigned int receive_packet(unsigned char cmd)
319  {
320  char c=UART_getc(DEBUG_SERIAL);
321  while (c!=cmd) {c=UART_getc(DEBUG_SERIAL);DISP(c);}
322  unsigned int data=UART_getw4(DEBUG_SERIAL);
323  ack(cmd);
324  return data;
325  }
326 
327 int main(void)
328 {
329  Board_init(); // start the board
330  setupwatchdoginterrupt();
331 
332  UART_init(DEBUG_SERIAL, 115200); DISP1("\n\n\r Satellite UART Camera test.\n\r")
333  UART_init(CAM_SERIAL, 115200);
334 
335  // start the console, print bootup message (below)
336 
337 char *picture_storage;
338 
339 while (1)
340  {
341  DISP1(":"); // ':' is command ready
342  char cmd=UART_getc(DEBUG_SERIAL);
343  char *ad;unsigned int len;
344  switch (cmd)
345  {
346  case '#':
347  // take a picture and store at given address
348 
349  //UART_puts(DEBUG_SERIAL," Take Picture Cmd received.\r\n");
350 
351  picture_storage=UART_getw4(DEBUG_SERIAL);
352  ack('#');
353  // DISP1(" Take Picture Cmd received.\r\n");
354 
355  unsigned int picturelength=take_picture(picture_storage);
356 
357  // DISP3("Picture length = ",picturelength,"\r\n");
358  // DISP1("Sending length packet.\n\r");
359  send_packet('$',picturelength);
360  // UART_putc(DEBUG_SERIAL,'#');writeword4(DEBUG_SERIAL,picturelength); // signal length saved
361  break;
362 
363  case '@':
364  // ack('~'); // not @ or confuses python
365  // DISP1(" Download memory Cmd received.\r\n")
366 
367  ad=UART_getw4(DEBUG_SERIAL);
368  len=UART_getw(DEBUG_SERIAL);
369  // DISP3("address = ",(int)ad,"\r\n");
370  // DISP3("len = ",len,"\r\n");
371  mem_packet_send(ad,len);
372  break;
373 
374  default:{}
375  //DISP1("Unknown command received\r\n");
376  }
377  }
378 }
void Delay_ms(uint32_t milliseconds)
Definition: delay.c:19
void UART_init(uint8_t uart_num, uint32_t baudrate)
Definition: uart.c:78
char UART_getc(uint8_t uart_num)
Definition: uart.c:113
int main(void)
Runs all module tests.
Definition: test.c:19
void UART_puts(uint8_t uart_num, char *str)
Definition: uart.c:129
void Board_init(void)
Definition: board.c:13
void UART_putc(uint8_t uart_num, char c)
Definition: uart.c:121