Test software for SatChat prototype hardware Platform - MAX32630FTHR

Dependencies:   USBDevice max32630fthr

Committer:
koziniec
Date:
Tue Jul 04 17:24:55 2017 +0000
Revision:
15:7d75ecaeabdb
Parent:
14:8ff04e82bda2
Child:
16:c5634210628d
Essential documentation of the GPS BLACK CODE is completed.; Time to move onto the RockBlock code.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
koziniec 15:7d75ecaeabdb 1 /* BLACK CODE INCLUDE START
koziniec 15:7d75ecaeabdb 2 External libraries are worrying!
koziniec 15:7d75ecaeabdb 3 Keep it simple and avoid anything non essential or obscure.
koziniec 15:7d75ecaeabdb 4 Consider copying functions from libraries into the code so
koziniec 15:7d75ecaeabdb 5 we have control. */
koziniec 0:59c04ca89ae2 6 #include "mbed.h"
koziniec 0:59c04ca89ae2 7 #include "max32630fthr.h"
koziniec 1:b8cb82927f33 8 #include <stdbool.h>
koziniec 15:7d75ecaeabdb 9 /* BLACK CODE INCLUDE END */
koziniec 15:7d75ecaeabdb 10
koziniec 15:7d75ecaeabdb 11 /* BLACK CODE DEFINE START */
koziniec 13:ff0b39177386 12 #define ON 0
koziniec 13:ff0b39177386 13 #define OFF 1
koziniec 13:ff0b39177386 14 #define EXIT_SUCCESS 0
koziniec 13:ff0b39177386 15 #define EXIT_FAILURE 1
koziniec 15:7d75ecaeabdb 16 /* BLACK CODE DEFINE END */
koziniec 14:8ff04e82bda2 17
koziniec 15:7d75ecaeabdb 18 /* BLACK CODE GLOBAL VAR START */
koziniec 15:7d75ecaeabdb 19 const int GPS_TIMEOUT=180; //Wait three minutes maximum for GPS.
koziniec 9:b8a60ade343e 20 char gpsfix_last_utc_time[11] = {0};
koziniec 9:b8a60ade343e 21 char gpsfix_last_utc_date[7] = {0};
koziniec 9:b8a60ade343e 22 char gpsfix_longtitude[12] = {0};
koziniec 9:b8a60ade343e 23 char gpsfix_latitude[12] = {0};
koziniec 9:b8a60ade343e 24 char gpsfix_speed[8] = {0}; //Set but not used
koziniec 9:b8a60ade343e 25 char gpsfix_course[7] = {0}; //Set but not used
koziniec 9:b8a60ade343e 26 char gpsfix_variation[7] = {0}; //Set but not used
koziniec 9:b8a60ade343e 27 char gpsfix_mag_var_ew[1] = {0};//Set but not used
koziniec 11:a9c16968e7f6 28 char gpsfix_ns = 0;
koziniec 11:a9c16968e7f6 29 char gpsfix_ew = 0;
koziniec 13:ff0b39177386 30 bool gps_data_present = false; //If this is false we can't even use stale GPS data.
koziniec 15:7d75ecaeabdb 31 /* BLACK CODE GLOBAL VAR END */
koziniec 15:7d75ecaeabdb 32
koziniec 15:7d75ecaeabdb 33 /* BLACK CODE PERIPHERAL INIT START */
koziniec 15:7d75ecaeabdb 34 DigitalOut red_led(LED1,1);
koziniec 15:7d75ecaeabdb 35 DigitalOut green_led(LED2,1);
koziniec 15:7d75ecaeabdb 36 DigitalOut gps_led(LED3,1); //Blue
koziniec 15:7d75ecaeabdb 37 Serial pc(USBTX, USBRX);
koziniec 15:7d75ecaeabdb 38 Serial gps(P5_3, P5_4, 9600);
koziniec 15:7d75ecaeabdb 39 I2C i2c(P5_7,P6_0); // SDA, SCL
koziniec 15:7d75ecaeabdb 40 /* BLACK CODE PERIPHERAL INIT END */
koziniec 9:b8a60ade343e 41
koziniec 1:b8cb82927f33 42 void gps_power(bool state)
koziniec 15:7d75ecaeabdb 43 /* BLACK CODE
koziniec 15:7d75ecaeabdb 44 MAX32630FTHR routine to control the output of the 3v3 line.
koziniec 15:7d75ecaeabdb 45 This is achieved by issuing commands to the MAX14690 controller.
koziniec 15:7d75ecaeabdb 46 In this case when the GPS is shutdown we clear any serial
koziniec 15:7d75ecaeabdb 47 data to avoid issues with mbeds buggy serial code */
koziniec 1:b8cb82927f33 48 {
koziniec 1:b8cb82927f33 49 char data[2];
koziniec 1:b8cb82927f33 50 data[0] = 0x16; //MAX14690 LDO3cfg register
koziniec 13:ff0b39177386 51 if (state == ON) {
koziniec 1:b8cb82927f33 52 data[1] = 0xE2; //Enable LDO3
koziniec 14:8ff04e82bda2 53 i2c.write( 0x50, data, 2 );
koziniec 14:8ff04e82bda2 54 gps_led=ON;
koziniec 14:8ff04e82bda2 55 } else {
koziniec 14:8ff04e82bda2 56 data[1] = 0xE0; //Disable LDO3
koziniec 14:8ff04e82bda2 57 i2c.write( 0x50, data, 2 );
koziniec 14:8ff04e82bda2 58 gps_led=OFF;
koziniec 14:8ff04e82bda2 59 while (gps.readable()) {
koziniec 14:8ff04e82bda2 60 char dummy = gps.getc(); //Empty serial buffer because overflows reveal MBED bugs :-(
koziniec 14:8ff04e82bda2 61 }
koziniec 1:b8cb82927f33 62 }
koziniec 1:b8cb82927f33 63 }
koziniec 1:b8cb82927f33 64
koziniec 13:ff0b39177386 65 int get_epoch_from_last_gps_time(void)
koziniec 15:7d75ecaeabdb 66 /* BLACK CODE
koziniec 15:7d75ecaeabdb 67 Given appropriate global char arrays of time and date information,
koziniec 15:7d75ecaeabdb 68 return a unix time epoch.
koziniec 15:7d75ecaeabdb 69 */
koziniec 12:a895e3581542 70 {
koziniec 12:a895e3581542 71 struct tm t;
koziniec 13:ff0b39177386 72 time_t epoch;
koziniec 12:a895e3581542 73 char two_char_str[3] = {0};
koziniec 12:a895e3581542 74 memcpy(two_char_str, gpsfix_last_utc_date+4, 2);
koziniec 12:a895e3581542 75 t.tm_year = atoi(two_char_str)+100; //Years since 1900
koziniec 12:a895e3581542 76 memcpy(two_char_str, gpsfix_last_utc_date+2, 2);
koziniec 12:a895e3581542 77 t.tm_mon = atoi(two_char_str)-1; // Month, 0 - jan gpsfix_last_utc_date
koziniec 12:a895e3581542 78 memcpy(two_char_str, gpsfix_last_utc_date, 2);
koziniec 12:a895e3581542 79 t.tm_mday = atoi(two_char_str); // Day of the month gpsfix_last_utc_date
koziniec 12:a895e3581542 80 memcpy(two_char_str, gpsfix_last_utc_time, 2);
koziniec 12:a895e3581542 81 t.tm_hour = atoi(two_char_str);
koziniec 12:a895e3581542 82 memcpy(two_char_str, gpsfix_last_utc_time+2, 2);
koziniec 12:a895e3581542 83 t.tm_min = atoi(two_char_str);
koziniec 13:ff0b39177386 84 memcpy(two_char_str, gpsfix_last_utc_time+4, 2);
koziniec 12:a895e3581542 85 t.tm_sec = atoi(two_char_str);
koziniec 12:a895e3581542 86 t.tm_isdst = 0; // Is DST on? 1 = yes, 0 = no, -1 = unknown
koziniec 13:ff0b39177386 87 epoch = mktime(&t);
koziniec 13:ff0b39177386 88 return epoch;
koziniec 15:7d75ecaeabdb 89 //BLACK CODE
koziniec 12:a895e3581542 90 }
koziniec 12:a895e3581542 91
koziniec 13:ff0b39177386 92 int gps_update(void)
koziniec 15:7d75ecaeabdb 93 /* BLACK CODE
koziniec 15:7d75ecaeabdb 94 gps_update
koziniec 15:7d75ecaeabdb 95 Reads NMEA data from a serial interface defined as "gps".
koziniec 15:7d75ecaeabdb 96 The function waits for a valid $GPRMC sentence. It then decodes the sentence and populates the
koziniec 15:7d75ecaeabdb 97 following global variables which are assumed to exist.
koziniec 15:7d75ecaeabdb 98
koziniec 15:7d75ecaeabdb 99 gpsfix_last_utc_time[11] = {0}; char gpsfix_last_utc_date[7] = {0};char gpsfix_longtitude[12] = {0};
koziniec 15:7d75ecaeabdb 100 char gpsfix_latitude[12] = {0}; char gpsfix_speed[8] = {0}; char gpsfix_course[7] = {0};
koziniec 15:7d75ecaeabdb 101 char gpsfix_variation[7] = {0}; char gpsfix_mag_var_ew[1] = {0}; char gpsfix_ns = 0; char gpsfix_ew = 0;
koziniec 15:7d75ecaeabdb 102
koziniec 15:7d75ecaeabdb 103 The following are also assumed to be part of the global declarations.
koziniec 15:7d75ecaeabdb 104 #define EXIT_SUCCESS 0
koziniec 15:7d75ecaeabdb 105 #define EXIT_FAILURE 1
koziniec 15:7d75ecaeabdb 106 const int GPS_TIMEOUT=180;
koziniec 15:7d75ecaeabdb 107 a gps_power() function that controls power to the GPS unit.
koziniec 15:7d75ecaeabdb 108
koziniec 15:7d75ecaeabdb 109 If the function is successful it returns a 0. If a valid fix is not obtined within the GPS_TIMEOUT
koziniec 15:7d75ecaeabdb 110 period a 1 is returned.
koziniec 15:7d75ecaeabdb 111
koziniec 15:7d75ecaeabdb 112 The code has been tested with a uBlox 6M but other GPS units may work.
koziniec 15:7d75ecaeabdb 113 The code is deliberately blocking as the mbed OS seems to crash on serial interrupts and buffer overflow.
koziniec 15:7d75ecaeabdb 114 The serial port is continuously read while waiting for a fix. Once a fix is obtained or a timeout occurs
koziniec 15:7d75ecaeabdb 115 the GPS is powered down and remaining data read out of the buffer.
koziniec 15:7d75ecaeabdb 116 */
koziniec 1:b8cb82927f33 117 {
koziniec 13:ff0b39177386 118 gps_power(ON);
koziniec 13:ff0b39177386 119 time_t gps_on_time = time(NULL); //Start time for GPS timeout calculation.
koziniec 13:ff0b39177386 120 bool wait_for_fix = true; //Set this to false once a fix is obtained.
koziniec 13:ff0b39177386 121 while (wait_for_fix) { //Keep monitoring the GPS until we get a fix.
koziniec 14:8ff04e82bda2 122 if ((time(NULL) - gps_on_time) > GPS_TIMEOUT) {
koziniec 13:ff0b39177386 123 gps_power(OFF);
koziniec 13:ff0b39177386 124 return EXIT_FAILURE; //Return an error if the GPS takes too long for a fix.
koziniec 13:ff0b39177386 125 }
koziniec 7:4218bb385ca4 126 int checksum = 0;
koziniec 13:ff0b39177386 127 char nmea_sentence[83] = {0}; //NMEA length max is 82 + 1 terminator. Fill with NULL terminators to save doing it later.
koziniec 8:b4a6c632c809 128 while (gps.getc()!='$'); //wait for start of sentence
koziniec 1:b8cb82927f33 129 int nmea_index = 0;
koziniec 7:4218bb385ca4 130 nmea_sentence[nmea_index] = '$'; //Manually insert the '$' because we don't want it included in the checksum loop
koziniec 8:b4a6c632c809 131 char nmea_char = gps.getc(); //get sentence first char from GPS
koziniec 15:7d75ecaeabdb 132 while (nmea_char != '*') { //Loop, building sentence and calc'ing CS until a * is seen
koziniec 15:7d75ecaeabdb 133 checksum ^= nmea_char; //Calc checksum as we read sentence
koziniec 7:4218bb385ca4 134 if ((nmea_sentence[nmea_index] == ',')&&(nmea_char == ',')) {
koziniec 15:7d75ecaeabdb 135 nmea_sentence[++nmea_index] = ' '; //Pad consecutive comma with a space to make it possible to use strtok with empty values
koziniec 3:1dff075c1c88 136 }
koziniec 15:7d75ecaeabdb 137 nmea_sentence[++nmea_index] = nmea_char; //build the sentence with the next character
koziniec 13:ff0b39177386 138 if (nmea_index > 81) {
koziniec 13:ff0b39177386 139 nmea_index=81; //Don't overflow sentence buffer
koziniec 1:b8cb82927f33 140 }
koziniec 7:4218bb385ca4 141 nmea_char = gps.getc(); //get next char from GPS
koziniec 1:b8cb82927f33 142 }
koziniec 13:ff0b39177386 143 //Last character was the '*' so next two are CS
koziniec 8:b4a6c632c809 144 char hex_checksum[3] = {0};
koziniec 8:b4a6c632c809 145 hex_checksum[0] = gps.getc();
koziniec 8:b4a6c632c809 146 hex_checksum[1] = gps.getc();
koziniec 13:ff0b39177386 147 if (checksum == (int)strtol(hex_checksum, NULL, 16) ) { //Compare calc and read checksums.
koziniec 9:b8a60ade343e 148 //Valid sentence so check if it's a GPRMC
koziniec 9:b8a60ade343e 149 const char gprmc[7] = "$GPRMC";
koziniec 9:b8a60ade343e 150 char *token;
koziniec 9:b8a60ade343e 151 token = strtok(nmea_sentence, ",");
koziniec 9:b8a60ade343e 152 if (strcmp(token,gprmc) == 0) { //GPRMC ?
koziniec 13:ff0b39177386 153 //pc.printf( " %s\n\r", token ); //Get the time
koziniec 9:b8a60ade343e 154 if (token != NULL) {
koziniec 9:b8a60ade343e 155 token = strtok(NULL, ",");
koziniec 13:ff0b39177386 156 if (*token != 32) { //If there is a time present (anything but a space), record it.
koziniec 13:ff0b39177386 157 //pc.printf("Time: %s\n\r",token);
koziniec 14:8ff04e82bda2 158 gps_led =! gps_led; //Flash blue LED
koziniec 11:a9c16968e7f6 159 memcpy(gpsfix_last_utc_time, token, sizeof gpsfix_last_utc_time - 1);
koziniec 11:a9c16968e7f6 160 }
koziniec 9:b8a60ade343e 161 }
koziniec 9:b8a60ade343e 162 if (token != NULL) {
koziniec 9:b8a60ade343e 163 token = strtok(NULL, ",");
koziniec 13:ff0b39177386 164 /* if (*token == 'V') {
koziniec 10:349d4fa9037f 165 pc.printf("VOID");
koziniec 13:ff0b39177386 166 } */
koziniec 13:ff0b39177386 167 }
koziniec 12:a895e3581542 168 if (*token == 'A') { //Is this an 'A'ctive (valid) fix?
koziniec 10:349d4fa9037f 169 pc.printf("Got a fix\n\r");
koziniec 13:ff0b39177386 170 gps_power(OFF); //Yes - No need for GPS now
koziniec 12:a895e3581542 171 wait_for_fix = false; //Stop looping now we have a fix.
koziniec 10:349d4fa9037f 172 if (token != NULL) {
koziniec 10:349d4fa9037f 173 token = strtok(NULL, ",");
koziniec 11:a9c16968e7f6 174 //pc.printf("Latitude: %s\n\r",token);
koziniec 11:a9c16968e7f6 175 memcpy(gpsfix_latitude, token, sizeof gpsfix_latitude - 1);
koziniec 10:349d4fa9037f 176 }
koziniec 10:349d4fa9037f 177 if (token != NULL) {
koziniec 10:349d4fa9037f 178 token = strtok(NULL, ",");
koziniec 11:a9c16968e7f6 179 //pc.printf("North/South: %s\n\r",token);
koziniec 11:a9c16968e7f6 180 gpsfix_ns = *token;
koziniec 10:349d4fa9037f 181 }
koziniec 10:349d4fa9037f 182 if (token != NULL) {
koziniec 10:349d4fa9037f 183 token = strtok(NULL, ",");
koziniec 12:a895e3581542 184 //pc.printf("Longitude: %s\n\r",token);
koziniec 11:a9c16968e7f6 185 memcpy(gpsfix_longtitude, token, sizeof gpsfix_longtitude - 1);
koziniec 10:349d4fa9037f 186 }
koziniec 10:349d4fa9037f 187 if (token != NULL) {
koziniec 10:349d4fa9037f 188 token = strtok(NULL, ",");
koziniec 12:a895e3581542 189 //pc.printf("East/West: %s\n\r",token);
koziniec 11:a9c16968e7f6 190 gpsfix_ew = *token;
koziniec 10:349d4fa9037f 191 }
koziniec 10:349d4fa9037f 192 if (token != NULL) {
koziniec 10:349d4fa9037f 193 token = strtok(NULL, ",");
koziniec 15:7d75ecaeabdb 194 //pc.printf("Speed in knots: %s\n\r",token);
koziniec 10:349d4fa9037f 195 }
koziniec 10:349d4fa9037f 196 if (token != NULL) {
koziniec 10:349d4fa9037f 197 token = strtok(NULL, ",");
koziniec 11:a9c16968e7f6 198 //pc.printf("True course: %s\n\r",token);
koziniec 10:349d4fa9037f 199 }
koziniec 10:349d4fa9037f 200 if (token != NULL) {
koziniec 10:349d4fa9037f 201 token = strtok(NULL, ",");
koziniec 11:a9c16968e7f6 202 //pc.printf("Date: %s\n\r",token);
koziniec 11:a9c16968e7f6 203 memcpy(gpsfix_last_utc_date, token, sizeof gpsfix_last_utc_date - 1);
koziniec 10:349d4fa9037f 204 }
koziniec 10:349d4fa9037f 205 if (token != NULL) {
koziniec 10:349d4fa9037f 206 token = strtok(NULL, ",");
koziniec 11:a9c16968e7f6 207 //pc.printf("Variation: %s\n\r",token);
koziniec 10:349d4fa9037f 208 }
koziniec 10:349d4fa9037f 209 if (token != NULL) {
koziniec 10:349d4fa9037f 210 token = strtok(NULL, ",");
koziniec 11:a9c16968e7f6 211 //pc.printf("Variation East/West: %s\n\r",token);
koziniec 10:349d4fa9037f 212 }
koziniec 10:349d4fa9037f 213 }
koziniec 9:b8a60ade343e 214 }
koziniec 8:b4a6c632c809 215 }
koziniec 1:b8cb82927f33 216 }
koziniec 13:ff0b39177386 217 return EXIT_SUCCESS;
koziniec 15:7d75ecaeabdb 218 //BLACK CODE
koziniec 12:a895e3581542 219 }
koziniec 1:b8cb82927f33 220
koziniec 13:ff0b39177386 221 main()
koziniec 15:7d75ecaeabdb 222 /* Start of BLACK CODE region. This area provides minimal SOS and position
koziniec 15:7d75ecaeabdb 223 updating. It needs to be robust and well tested. Put all the fancy stuff
koziniec 15:7d75ecaeabdb 224 outside this area. Changes here should be limited to fixing bugs and
koziniec 15:7d75ecaeabdb 225 simplifying the code.
koziniec 15:7d75ecaeabdb 226 */
koziniec 15:7d75ecaeabdb 227 { //Set the power button behaviour.
koziniec 1:b8cb82927f33 228 char data[2];
koziniec 1:b8cb82927f33 229 data[0] = 0x1A; //MAX14690 BootCfg register
koziniec 1:b8cb82927f33 230 data[1] = 0x30; //Always-On Mode, off state via PWR_OFF_CMD
koziniec 0:59c04ca89ae2 231 i2c.write( 0x50, data, 2 );
koziniec 15:7d75ecaeabdb 232 //Set the voltage to 3v3 for the GPS.
koziniec 1:b8cb82927f33 233 data[0] = 0x17; //MAX14690 LDO3Vset register
koziniec 0:59c04ca89ae2 234 data[1] = 0x19; //3.3V
koziniec 0:59c04ca89ae2 235 i2c.write( 0x50, data, 2 );
koziniec 13:ff0b39177386 236 gps_power(OFF);
koziniec 15:7d75ecaeabdb 237
koziniec 13:ff0b39177386 238 pc.printf("\n\n\rOpen EPIRB - Simple mode\n\r");
koziniec 13:ff0b39177386 239 pc.printf("Press and hold both side buttons to signal rescue needed\n\r");
koziniec 13:ff0b39177386 240 pc.printf("Full functionality will start in:");
koziniec 13:ff0b39177386 241 for (int i=9; i > 0; i--) {
koziniec 13:ff0b39177386 242 time_t seconds = time(NULL); //get current epoch
koziniec 13:ff0b39177386 243 pc.printf("%d",i);
koziniec 13:ff0b39177386 244 while(time(NULL) - seconds < 1) {
koziniec 15:7d75ecaeabdb 245 if (false/*button_combination()==SOS_PRESSED*/) {
koziniec 13:ff0b39177386 246 //do the emergency code
koziniec 13:ff0b39177386 247 if (gps_update()==EXIT_SUCCESS) {
koziniec 13:ff0b39177386 248 gps_data_present = true;
koziniec 13:ff0b39177386 249 int gps_epoch = get_epoch_from_last_gps_time();
koziniec 13:ff0b39177386 250 set_time(gps_epoch);
koziniec 13:ff0b39177386 251 pc.printf("Got a GPS fix and time.\n\r");
koziniec 13:ff0b39177386 252 pc.printf("Sending SOS in 10 seconds");
koziniec 13:ff0b39177386 253 green_led=ON;
koziniec 13:ff0b39177386 254 } else {
koziniec 13:ff0b39177386 255 pc.printf("\n\rGPS timed out and we have no existing fix.\n\r");
koziniec 13:ff0b39177386 256 pc.printf("We can send an Iridium packet but coordinates are rough.\n\r");
koziniec 14:8ff04e82bda2 257 pc.printf("Sending SOS in 10 seconds");
koziniec 14:8ff04e82bda2 258 red_led=ON;
koziniec 13:ff0b39177386 259 }
koziniec 13:ff0b39177386 260 while(true) {}; //STOP HERE
koziniec 13:ff0b39177386 261 }
koziniec 13:ff0b39177386 262 }
koziniec 13:ff0b39177386 263 pc.printf("\b"); //Backspace
koziniec 0:59c04ca89ae2 264 }
koziniec 15:7d75ecaeabdb 265 /* END OF BLACK CODE REGION - Put all the fancy stuff down here
koziniec 15:7d75ecaeabdb 266 */
koziniec 13:ff0b39177386 267 pc.printf("\n\rStarting normal operation\n\r");
koziniec 13:ff0b39177386 268 /*
koziniec 13:ff0b39177386 269 if (true) { //Temp simulation
koziniec 13:ff0b39177386 270 while (1) {
koziniec 13:ff0b39177386 271 if (gps_update()==EXIT_SUCCESS) {
koziniec 13:ff0b39177386 272 gps_data_present = true;
koziniec 13:ff0b39177386 273 int gps_epoch = get_epoch_from_last_gps_time();
koziniec 13:ff0b39177386 274 set_time(gps_epoch);
koziniec 13:ff0b39177386 275 pc.printf("Got a GPS fix and time.\n\r");
koziniec 13:ff0b39177386 276 } else {
koziniec 13:ff0b39177386 277 pc.printf("GPS timed out and we have no existing fix.\n\r");
koziniec 13:ff0b39177386 278 pc.printf("We can send an Iridium packet but coordinates are rough.\n\r");
koziniec 13:ff0b39177386 279 }
koziniec 13:ff0b39177386 280 time_t seconds = time(NULL);
koziniec 13:ff0b39177386 281 //printf("Time as a basic string = %s", ctime(&seconds));
koziniec 13:ff0b39177386 282 wait(60);
koziniec 13:ff0b39177386 283 seconds = time(NULL);
koziniec 13:ff0b39177386 284
koziniec 13:ff0b39177386 285 wait(33);
koziniec 13:ff0b39177386 286 seconds = time(NULL);
koziniec 13:ff0b39177386 287 printf("Time as a basic string = %s", ctime(&seconds));
koziniec 13:ff0b39177386 288 wait(60);
koziniec 13:ff0b39177386 289 } */
koziniec 13:ff0b39177386 290 }
koziniec 0:59c04ca89ae2 291
koziniec 0:59c04ca89ae2 292
koziniec 7:4218bb385ca4 293
koziniec 7:4218bb385ca4 294
koziniec 7:4218bb385ca4 295
koziniec 0:59c04ca89ae2 296
koziniec 7:4218bb385ca4 297
koziniec 0:59c04ca89ae2 298
koziniec 7:4218bb385ca4 299