rfid lock build to interface with mf7 rfid reader using white / black list

Dependencies:   mbed

Committer:
pwheels
Date:
Wed Feb 09 07:44:59 2011 +0000
Revision:
0:c9e183da8303
initial release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pwheels 0:c9e183da8303 1 /*
pwheels 0:c9e183da8303 2 * Copyright (c) 2011 Paul van der Wielen, Pro-Serv
pwheels 0:c9e183da8303 3 *
pwheels 0:c9e183da8303 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
pwheels 0:c9e183da8303 5 * of this software and associated documentation files (the "Software"), to use
pwheels 0:c9e183da8303 6 * and implement the software for none commercial reason and usage only and
pwheels 0:c9e183da8303 7 * subject to the following conditions:
pwheels 0:c9e183da8303 8 *
pwheels 0:c9e183da8303 9 * The above copyright notice and this permission notice shall be included in
pwheels 0:c9e183da8303 10 * all copies or substantial portions of the Software.
pwheels 0:c9e183da8303 11 *
pwheels 0:c9e183da8303 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pwheels 0:c9e183da8303 13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pwheels 0:c9e183da8303 14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pwheels 0:c9e183da8303 15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pwheels 0:c9e183da8303 16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pwheels 0:c9e183da8303 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pwheels 0:c9e183da8303 18 * THE SOFTWARE.
pwheels 0:c9e183da8303 19 *
pwheels 0:c9e183da8303 20 * Usage and assumptions:
pwheels 0:c9e183da8303 21 * a RFID reader Model MF7(1.05) is configured in ascii mode and attached to p10 via
pwheels 0:c9e183da8303 22 * a level converter (rs232 at ttl level to 3.3V), which also inverses the signal
pwheels 0:c9e183da8303 23 * The imbedded local drive holds a white list and black list file in csv format.
pwheels 0:c9e183da8303 24 * Operation signalling is available via default LED 1-4 being:
pwheels 0:c9e183da8303 25 * LED1 - access granted, LED2 - access denied, LED3 - door unlocked, LED4 - file reading
pwheels 0:c9e183da8303 26 *
pwheels 0:c9e183da8303 27 * the white list master card should be at white[0], being first entry in white list csv file
pwheels 0:c9e183da8303 28 * while the black list master card should be at white[1], being second entry in white list csv
pwheels 0:c9e183da8303 29 * file, mind these two card DON'T provide access and/or door unlocking operations
pwheels 0:c9e183da8303 30 *
pwheels 0:c9e183da8303 31 * Used device = LPC1768, basic logging is availabe as needed on the serial to usb port via
pwheels 0:c9e183da8303 32 * terminal emulator like Tera, extend logging or debugging data is available by uncomment
pwheels 0:c9e183da8303 33 * the #define DEBUG statement
pwheels 0:c9e183da8303 34 */
pwheels 0:c9e183da8303 35
pwheels 0:c9e183da8303 36 #include "mbed.h"
pwheels 0:c9e183da8303 37 #include <string.h>
pwheels 0:c9e183da8303 38
pwheels 0:c9e183da8303 39 //#define DEBUG
pwheels 0:c9e183da8303 40
pwheels 0:c9e183da8303 41 Serial pc(USBTX, USBRX); // tx, rx
pwheels 0:c9e183da8303 42 Serial device(p9, p10); // tx, rx
pwheels 0:c9e183da8303 43 LocalFileSystem local("local");
pwheels 0:c9e183da8303 44
pwheels 0:c9e183da8303 45 const char *wl = "/local/list_wht.csv";
pwheels 0:c9e183da8303 46 const char *bl = "/local/list_blk.csv";
pwheels 0:c9e183da8303 47
pwheels 0:c9e183da8303 48 const char *ver = "V1.1";
pwheels 0:c9e183da8303 49
pwheels 0:c9e183da8303 50 /*
pwheels 0:c9e183da8303 51 * In order to assure proper white & black list operation we assume to
pwheels 0:c9e183da8303 52 * have the master card for white & black list to be at index 0 and 1 resp.
pwheels 0:c9e183da8303 53 */
pwheels 0:c9e183da8303 54 unsigned long white[256] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 55 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 56 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 57 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 58 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 59 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 60 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 61 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 62 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 63 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 64 0,0,0,0,0,0
pwheels 0:c9e183da8303 65 };
pwheels 0:c9e183da8303 66
pwheels 0:c9e183da8303 67 unsigned long black[64] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 68 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
pwheels 0:c9e183da8303 69 0,0,0,0,0,0,0,0,0,0,0,0,0
pwheels 0:c9e183da8303 70 };
pwheels 0:c9e183da8303 71
pwheels 0:c9e183da8303 72 unsigned int hex2int(char a);
pwheels 0:c9e183da8303 73 bool rfid_match_wl( unsigned long b);
pwheels 0:c9e183da8303 74 bool rfid_match_bl( unsigned long b);
pwheels 0:c9e183da8303 75 int add_card(const char *ft, char *xx);
pwheels 0:c9e183da8303 76 int get_list(const char *ft, unsigned long *xx);
pwheels 0:c9e183da8303 77
pwheels 0:c9e183da8303 78 void memdump( char *p, int n );
pwheels 0:c9e183da8303 79
pwheels 0:c9e183da8303 80 char rfid[10];
pwheels 0:c9e183da8303 81 char buffer[32];
pwheels 0:c9e183da8303 82
pwheels 0:c9e183da8303 83 unsigned char tmp;
pwheels 0:c9e183da8303 84 int cnt = 0;
pwheels 0:c9e183da8303 85 int pnt = 0;
pwheels 0:c9e183da8303 86 int mst = 0; // usage format abxxxxxn where a = white, b = black operation, n indicates second step
pwheels 0:c9e183da8303 87
pwheels 0:c9e183da8303 88 DigitalOut myled1(LED1);
pwheels 0:c9e183da8303 89 DigitalOut myled2(LED2);
pwheels 0:c9e183da8303 90 DigitalOut myled3(LED3);
pwheels 0:c9e183da8303 91 DigitalOut myled4(LED4);
pwheels 0:c9e183da8303 92
pwheels 0:c9e183da8303 93 int main() {
pwheels 0:c9e183da8303 94
pwheels 0:c9e183da8303 95 #ifdef DEBUG
pwheels 0:c9e183da8303 96 char mem[ 1024 ]; // memory, it should be aligned to word boundary
pwheels 0:c9e183da8303 97 #endif
pwheels 0:c9e183da8303 98
pwheels 0:c9e183da8303 99 float release = 7.0;
pwheels 0:c9e183da8303 100 unsigned long val = 0;
pwheels 0:c9e183da8303 101
pwheels 0:c9e183da8303 102 printf( "\r\nRFID Lock System, version: %s\r\n", ver);
pwheels 0:c9e183da8303 103 printf( " CPU running %dkHz\r\n", SystemCoreClock / 1000 );
pwheels 0:c9e183da8303 104
pwheels 0:c9e183da8303 105 cnt = get_list(wl, white);
pwheels 0:c9e183da8303 106 #ifdef DEBUG
pwheels 0:c9e183da8303 107 memcpy(&mem, &white, 1024);
pwheels 0:c9e183da8303 108
pwheels 0:c9e183da8303 109 printf( "Showing `White List` content ...\r\n" );
pwheels 0:c9e183da8303 110 memdump( mem, 256 * 4 );
pwheels 0:c9e183da8303 111 #endif
pwheels 0:c9e183da8303 112 printf( "Started with %d known RFID 'White list' cards\r\n\n", cnt);
pwheels 0:c9e183da8303 113
pwheels 0:c9e183da8303 114 cnt = get_list(bl, black);
pwheels 0:c9e183da8303 115 #ifdef DEBUG
pwheels 0:c9e183da8303 116 memcpy(&mem, &black, 256);
pwheels 0:c9e183da8303 117
pwheels 0:c9e183da8303 118 printf( "Showing `Black List` content ...\r\n" );
pwheels 0:c9e183da8303 119 memdump( mem, 256 * 1 );
pwheels 0:c9e183da8303 120 #endif
pwheels 0:c9e183da8303 121 printf( "Started with %d known RFID 'Black list' cards\r\n\n", cnt);
pwheels 0:c9e183da8303 122
pwheels 0:c9e183da8303 123 while (1) {
pwheels 0:c9e183da8303 124 if (device.readable()) {
pwheels 0:c9e183da8303 125 tmp = device.getc();
pwheels 0:c9e183da8303 126 switch (tmp) {
pwheels 0:c9e183da8303 127 case 0x02:
pwheels 0:c9e183da8303 128 cnt = 0;
pwheels 0:c9e183da8303 129 val = 0;
pwheels 0:c9e183da8303 130 break;
pwheels 0:c9e183da8303 131 case 0x03:
pwheels 0:c9e183da8303 132 rfid[cnt++] = 0x00;
pwheels 0:c9e183da8303 133 val = strtoul(rfid, 0, 16);
pwheels 0:c9e183da8303 134 #ifdef DEBUG
pwheels 0:c9e183da8303 135 pc.printf("%s %u", rfid, val ); // define for debug mode
pwheels 0:c9e183da8303 136 #endif
pwheels 0:c9e183da8303 137 pc.printf("%s", rfid );
pwheels 0:c9e183da8303 138 if ((rfid_match_wl(val)) && !(rfid_match_bl(val)) && (mst == 0x00)) {
pwheels 0:c9e183da8303 139 // green led - access provided
pwheels 0:c9e183da8303 140 myled1 = 1;
pwheels 0:c9e183da8303 141 // activate lock for 'release' time duration
pwheels 0:c9e183da8303 142 myled3 = 1;
pwheels 0:c9e183da8303 143 // we will need to add a defenition for DigitalOut here
pwheels 0:c9e183da8303 144 wait(0.25);
pwheels 0:c9e183da8303 145 myled1 = 0;
pwheels 0:c9e183da8303 146 wait(release-0.25);
pwheels 0:c9e183da8303 147 myled3 = 0;
pwheels 0:c9e183da8303 148 // we will need to add a defenition for DigitalOut here
pwheels 0:c9e183da8303 149 pc.printf(" -> Granted\r\n" );
pwheels 0:c9e183da8303 150 } else {
pwheels 0:c9e183da8303 151 if (mst == 0x81) {
pwheels 0:c9e183da8303 152 // master mode, add new card to white list
pwheels 0:c9e183da8303 153 white[cnt++] = val;
pwheels 0:c9e183da8303 154 mst = 0;
pwheels 0:c9e183da8303 155 pc.printf(" -> Card added\r\n" );
pwheels 0:c9e183da8303 156 if (add_card(wl, rfid) != 0) {
pwheels 0:c9e183da8303 157 pc.printf("%s -> WL Add Failed\r\n", rfid );
pwheels 0:c9e183da8303 158 }
pwheels 0:c9e183da8303 159 } else if (mst == 0x41) {
pwheels 0:c9e183da8303 160 // master mode, add new card to white list
pwheels 0:c9e183da8303 161 black[cnt++] = val;
pwheels 0:c9e183da8303 162 mst = 0;
pwheels 0:c9e183da8303 163 pc.printf(" -> Card Removed\r\n" );
pwheels 0:c9e183da8303 164 if (add_card(bl, rfid) != 0) {
pwheels 0:c9e183da8303 165 pc.printf("%s -> BL Remove Failed\r\n", rfid );
pwheels 0:c9e183da8303 166 }
pwheels 0:c9e183da8303 167 } else {
pwheels 0:c9e183da8303 168 // red led - no access
pwheels 0:c9e183da8303 169 myled2 = 1;
pwheels 0:c9e183da8303 170 wait(0.25);
pwheels 0:c9e183da8303 171 myled2 = 0;
pwheels 0:c9e183da8303 172 if (mst == 0x80) {
pwheels 0:c9e183da8303 173 pc.printf(" -> White List Mode!\r\n");
pwheels 0:c9e183da8303 174 } else if (mst == 0x40) {
pwheels 0:c9e183da8303 175 pc.printf(" -> Black List Mode!\r\n");
pwheels 0:c9e183da8303 176 } else {
pwheels 0:c9e183da8303 177 pc.printf(" -> Denied !\r\n" );
pwheels 0:c9e183da8303 178 }
pwheels 0:c9e183da8303 179 }
pwheels 0:c9e183da8303 180 }
pwheels 0:c9e183da8303 181 break;
pwheels 0:c9e183da8303 182 case 0x0a:
pwheels 0:c9e183da8303 183 case 0x0d:
pwheels 0:c9e183da8303 184 break;
pwheels 0:c9e183da8303 185 default:
pwheels 0:c9e183da8303 186 // data from MF7 (ascii mode) is in `litle endian` format, so need
pwheels 0:c9e183da8303 187 // to swap groups but, we will store rfid card as a value
pwheels 0:c9e183da8303 188 // char array addressing = [group + count - count offset]
pwheels 0:c9e183da8303 189 switch (cnt) {
pwheels 0:c9e183da8303 190 case 0x00:
pwheels 0:c9e183da8303 191 case 0x01:
pwheels 0:c9e183da8303 192 rfid[6 + cnt] = tmp;
pwheels 0:c9e183da8303 193 break;
pwheels 0:c9e183da8303 194 case 0x02:
pwheels 0:c9e183da8303 195 case 0x03:
pwheels 0:c9e183da8303 196 rfid[4 + cnt - 2] = tmp;
pwheels 0:c9e183da8303 197 break;
pwheels 0:c9e183da8303 198 case 0x04:
pwheels 0:c9e183da8303 199 case 0x05:
pwheels 0:c9e183da8303 200 rfid[2 + cnt - 4] = tmp;
pwheels 0:c9e183da8303 201 break;
pwheels 0:c9e183da8303 202 case 0x06:
pwheels 0:c9e183da8303 203 case 0x07:
pwheels 0:c9e183da8303 204 rfid[0 + cnt - 6] = tmp;
pwheels 0:c9e183da8303 205 break;
pwheels 0:c9e183da8303 206 }
pwheels 0:c9e183da8303 207 cnt++;
pwheels 0:c9e183da8303 208 }
pwheels 0:c9e183da8303 209 }
pwheels 0:c9e183da8303 210 }
pwheels 0:c9e183da8303 211 }
pwheels 0:c9e183da8303 212 /*
pwheels 0:c9e183da8303 213 * All used functions are listed below
pwheels 0:c9e183da8303 214 *
pwheels 0:c9e183da8303 215 * function to add a card to selected list (black or white)
pwheels 0:c9e183da8303 216 */
pwheels 0:c9e183da8303 217 int add_card(const char *ft, char *xx) {
pwheels 0:c9e183da8303 218
pwheels 0:c9e183da8303 219 FILE *fp;
pwheels 0:c9e183da8303 220
pwheels 0:c9e183da8303 221 if ((fp = fopen(ft, "a")) == NULL) {
pwheels 0:c9e183da8303 222 fprintf(stderr, "File %s could not be opened!\r\n", ft);
pwheels 0:c9e183da8303 223 return -1;
pwheels 0:c9e183da8303 224 }
pwheels 0:c9e183da8303 225 fprintf(fp,"%s\r\n", xx);
pwheels 0:c9e183da8303 226 fclose(fp);
pwheels 0:c9e183da8303 227 return 0;
pwheels 0:c9e183da8303 228 }
pwheels 0:c9e183da8303 229
pwheels 0:c9e183da8303 230 /*
pwheels 0:c9e183da8303 231 * function to read initial content for selected list (black or white)
pwheels 0:c9e183da8303 232 */
pwheels 0:c9e183da8303 233 int get_list(const char *ft, unsigned long *xx) {
pwheels 0:c9e183da8303 234
pwheels 0:c9e183da8303 235 FILE *fp;
pwheels 0:c9e183da8303 236
pwheels 0:c9e183da8303 237 if ((fp = fopen(ft, "r")) == NULL) {
pwheels 0:c9e183da8303 238 fprintf(stderr, "File %s could not be opened!\r\n", ft);
pwheels 0:c9e183da8303 239 return 0;
pwheels 0:c9e183da8303 240 } else {
pwheels 0:c9e183da8303 241 cnt = pnt = 0;
pwheels 0:c9e183da8303 242 printf("Reading Data File...\r\n");
pwheels 0:c9e183da8303 243 // reading file content
pwheels 0:c9e183da8303 244 while ((tmp = getc(fp)) != 0xff) {
pwheels 0:c9e183da8303 245 switch (tmp) {
pwheels 0:c9e183da8303 246 case 0x0d:
pwheels 0:c9e183da8303 247 myled4 = 1;
pwheels 0:c9e183da8303 248 rfid[pnt++] = 0x00;
pwheels 0:c9e183da8303 249 xx[cnt++] = strtoul(rfid, 0, 16);
pwheels 0:c9e183da8303 250 #ifdef DEBUG
pwheels 0:c9e183da8303 251 printf( " %s !\r\n", rfid); // define for debug mode
pwheels 0:c9e183da8303 252 #endif
pwheels 0:c9e183da8303 253 pnt = 0;
pwheels 0:c9e183da8303 254 myled4 = 0;
pwheels 0:c9e183da8303 255 break;
pwheels 0:c9e183da8303 256 case 0x0a:
pwheels 0:c9e183da8303 257 break;
pwheels 0:c9e183da8303 258 default:
pwheels 0:c9e183da8303 259 rfid[pnt++] = tmp;
pwheels 0:c9e183da8303 260 break;
pwheels 0:c9e183da8303 261 }
pwheels 0:c9e183da8303 262 }
pwheels 0:c9e183da8303 263 printf("Closing Data File...\r\n");
pwheels 0:c9e183da8303 264 fclose(fp);
pwheels 0:c9e183da8303 265 }
pwheels 0:c9e183da8303 266 return cnt;
pwheels 0:c9e183da8303 267 }
pwheels 0:c9e183da8303 268
pwheels 0:c9e183da8303 269 /*
pwheels 0:c9e183da8303 270 * function to match current card against selected white list
pwheels 0:c9e183da8303 271 */
pwheels 0:c9e183da8303 272 bool rfid_match_wl( unsigned long myval) {
pwheels 0:c9e183da8303 273 int i;
pwheels 0:c9e183da8303 274
pwheels 0:c9e183da8303 275 if (( mst == 0x80 ) || ( mst == 0x40 )) {
pwheels 0:c9e183da8303 276 mst++;
pwheels 0:c9e183da8303 277 }
pwheels 0:c9e183da8303 278 for (i = 0; i < sizeof(white)/sizeof(white[0]); i++) {
pwheels 0:c9e183da8303 279 if (white[i] == myval) {
pwheels 0:c9e183da8303 280 // if master card (being first in list) is presented twice ! -> add new card
pwheels 0:c9e183da8303 281 if (( i == 0 ) && (mst == 0)) {
pwheels 0:c9e183da8303 282 mst = 0x80;
pwheels 0:c9e183da8303 283 } else if (( i == 1 ) && (mst == 0)) {
pwheels 0:c9e183da8303 284 mst = 0x40;
pwheels 0:c9e183da8303 285 } else {
pwheels 0:c9e183da8303 286 ;
pwheels 0:c9e183da8303 287 }
pwheels 0:c9e183da8303 288 #ifdef DEBUG
pwheels 0:c9e183da8303 289 pc.printf("%u %u\r\n", white[i], i); // define for debug mode
pwheels 0:c9e183da8303 290 #endif
pwheels 0:c9e183da8303 291 return true;
pwheels 0:c9e183da8303 292 }
pwheels 0:c9e183da8303 293 }
pwheels 0:c9e183da8303 294 return false;
pwheels 0:c9e183da8303 295 }
pwheels 0:c9e183da8303 296
pwheels 0:c9e183da8303 297 /*
pwheels 0:c9e183da8303 298 * function to match current card against selected black list
pwheels 0:c9e183da8303 299 */
pwheels 0:c9e183da8303 300 bool rfid_match_bl( unsigned long myval) {
pwheels 0:c9e183da8303 301 int i;
pwheels 0:c9e183da8303 302
pwheels 0:c9e183da8303 303 for (i = 0; i < sizeof(black)/sizeof(black[0]); i++) {
pwheels 0:c9e183da8303 304 if (black[i] == myval) {
pwheels 0:c9e183da8303 305 return true;
pwheels 0:c9e183da8303 306 }
pwheels 0:c9e183da8303 307 }
pwheels 0:c9e183da8303 308 return false;
pwheels 0:c9e183da8303 309 }
pwheels 0:c9e183da8303 310
pwheels 0:c9e183da8303 311 /*
pwheels 0:c9e183da8303 312 * function to convert single character value it's decimal value
pwheels 0:c9e183da8303 313 */
pwheels 0:c9e183da8303 314 unsigned int hex2int(char a) {
pwheels 0:c9e183da8303 315 unsigned int val = 0;
pwheels 0:c9e183da8303 316
pwheels 0:c9e183da8303 317 if ((int)a <= 57)
pwheels 0:c9e183da8303 318 val = ((int)a-48);
pwheels 0:c9e183da8303 319 else
pwheels 0:c9e183da8303 320 val = ((int)a-55);
pwheels 0:c9e183da8303 321 return val;
pwheels 0:c9e183da8303 322 }
pwheels 0:c9e183da8303 323
pwheels 0:c9e183da8303 324 /*
pwheels 0:c9e183da8303 325 * function to dump specific memory block
pwheels 0:c9e183da8303 326 */
pwheels 0:c9e183da8303 327 void memdump( char *base, int n ) {
pwheels 0:c9e183da8303 328 unsigned int *p;
pwheels 0:c9e183da8303 329
pwheels 0:c9e183da8303 330 printf( " memdump from 0x%08X for %d bytes", (unsigned long)base, n );
pwheels 0:c9e183da8303 331
pwheels 0:c9e183da8303 332 p = (unsigned int *)((unsigned int)base & ~(unsigned int)0x3);
pwheels 0:c9e183da8303 333
pwheels 0:c9e183da8303 334 for ( int i = 0; i < (n >> 2); i++, p++ ) {
pwheels 0:c9e183da8303 335 if ( !(i % 4) )
pwheels 0:c9e183da8303 336 printf( "\r\n 0x%08X :", (unsigned int)p );
pwheels 0:c9e183da8303 337
pwheels 0:c9e183da8303 338 printf( " 0x%08X", *p );
pwheels 0:c9e183da8303 339 }
pwheels 0:c9e183da8303 340
pwheels 0:c9e183da8303 341 printf( "\r\n" );
pwheels 0:c9e183da8303 342 }