Pulls unique serial number from CPU and prints to serial console and displays on LCD. Used to generate a guaranteed unique ID for IoT apps where the IoT device needs to become it's own access point. Should work on native hardware unlike the MBED MAC address which would not be available on some custom PCB. Tested on KL46Z but should also work on most STM CPU.
main.cpp@1:61ccbbc268f6, 2016-03-09 (annotated)
- Committer:
- joeata2wh
- Date:
- Wed Mar 09 17:50:16 2016 +0000
- Revision:
- 1:61ccbbc268f6
- Parent:
- 0:eddce2241b50
added lu specifier to avoid compiler warning in printf
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
joeata2wh | 0:eddce2241b50 | 1 | /* |
joeata2wh | 0:eddce2241b50 | 2 | by Joseph Ellsworth CTO A2WH. |
joeata2wh | 0:eddce2241b50 | 3 | Freeuse for all. No promises, No warranty * |
joeata2wh | 0:eddce2241b50 | 4 | Please contact us http://a2wh.com for help with custom design projects. |
joeata2wh | 0:eddce2241b50 | 5 | |
joeata2wh | 0:eddce2241b50 | 6 | Most STM and Freescale ARM chips include a unique Serail Number embedded |
joeata2wh | 0:eddce2241b50 | 7 | in the CPU. This is a perfect number to use in IoT as a SSID. I use |
joeata2wh | 0:eddce2241b50 | 8 | this to produce the WIFi SID so I can walk up with a phone and download |
joeata2wh | 0:eddce2241b50 | 9 | telemetry. I found a blog discussion for mbed that suggested using the |
joeata2wh | 0:eddce2241b50 | 10 | MAC but this assumes mbed hardware whereas this version uses the serial |
joeata2wh | 0:eddce2241b50 | 11 | number built in to the CPU so it should work on native boards. |
joeata2wh | 0:eddce2241b50 | 12 | */ |
joeata2wh | 0:eddce2241b50 | 13 | |
joeata2wh | 0:eddce2241b50 | 14 | #include "mbed.h" |
joeata2wh | 0:eddce2241b50 | 15 | #include "SLCD.h" |
joeata2wh | 0:eddce2241b50 | 16 | //#include "lcd_scroll.h" |
joeata2wh | 0:eddce2241b50 | 17 | |
joeata2wh | 0:eddce2241b50 | 18 | |
joeata2wh | 0:eddce2241b50 | 19 | #define uniqueSerialAdd_kl_freescale (unsigned long *)0x40048058 |
joeata2wh | 0:eddce2241b50 | 20 | #define uniqueSerialAddr_stm32 (unsigned long *)0x1FFFF7E8 |
joeata2wh | 0:eddce2241b50 | 21 | #define uniqueSerialAddr uniqueSerialAdd_kl_freescale |
joeata2wh | 0:eddce2241b50 | 22 | #define lcdlen 4 |
joeata2wh | 0:eddce2241b50 | 23 | // Change to enable for address for your chip family |
joeata2wh | 0:eddce2241b50 | 24 | // Note some ealry stm L3 chips were produced with all |
joeata2wh | 0:eddce2241b50 | 25 | // chip ID set to FFF. I have not seen any but did find |
joeata2wh | 0:eddce2241b50 | 26 | // it mentioned in a blog. |
joeata2wh | 0:eddce2241b50 | 27 | |
joeata2wh | 0:eddce2241b50 | 28 | |
joeata2wh | 0:eddce2241b50 | 29 | |
joeata2wh | 0:eddce2241b50 | 30 | DigitalOut gpo(D0); |
joeata2wh | 0:eddce2241b50 | 31 | DigitalOut led(LED_RED); |
joeata2wh | 0:eddce2241b50 | 32 | Serial pc(USBTX, USBRX); |
joeata2wh | 0:eddce2241b50 | 33 | SLCD slcd; |
joeata2wh | 0:eddce2241b50 | 34 | |
joeata2wh | 0:eddce2241b50 | 35 | |
joeata2wh | 0:eddce2241b50 | 36 | /* format the unique serial number as a string. we could use |
joeata2wh | 0:eddce2241b50 | 37 | as the router SID for Lot. Supress leading zeros to save |
joeata2wh | 0:eddce2241b50 | 38 | space */ |
joeata2wh | 0:eddce2241b50 | 39 | void getUniqueIDAsStr(char *destStr) |
joeata2wh | 0:eddce2241b50 | 40 | { |
joeata2wh | 0:eddce2241b50 | 41 | unsigned long *Unique = uniqueSerialAddr; |
joeata2wh | 1:61ccbbc268f6 | 42 | sprintf(destStr, "S%luX%luX%luX\000", Unique[0], Unique[1], Unique[2]); |
joeata2wh | 0:eddce2241b50 | 43 | } |
joeata2wh | 0:eddce2241b50 | 44 | |
joeata2wh | 0:eddce2241b50 | 45 | |
joeata2wh | 0:eddce2241b50 | 46 | void scroll(int lcdLen, char *message, float charDelay) |
joeata2wh | 0:eddce2241b50 | 47 | { |
joeata2wh | 0:eddce2241b50 | 48 | short msgLen = strlen(message); |
joeata2wh | 0:eddce2241b50 | 49 | short maxStartndx = msgLen - lcdLen; |
joeata2wh | 0:eddce2241b50 | 50 | short currndx = 0; |
joeata2wh | 0:eddce2241b50 | 51 | short currpos = 0; |
joeata2wh | 0:eddce2241b50 | 52 | short winndx; |
joeata2wh | 0:eddce2241b50 | 53 | slcd.clear(); |
joeata2wh | 0:eddce2241b50 | 54 | |
joeata2wh | 0:eddce2241b50 | 55 | slcd.Home(); |
joeata2wh | 0:eddce2241b50 | 56 | for (currndx = 0; currndx <= maxStartndx; currndx++) { |
joeata2wh | 0:eddce2241b50 | 57 | for (winndx = 0; winndx < lcdLen ; winndx++) { |
joeata2wh | 0:eddce2241b50 | 58 | currpos = currndx + winndx; |
joeata2wh | 0:eddce2241b50 | 59 | if (message[currpos] == 0) { |
joeata2wh | 0:eddce2241b50 | 60 | break; |
joeata2wh | 0:eddce2241b50 | 61 | } |
joeata2wh | 0:eddce2241b50 | 62 | slcd.putc(message[currpos]); |
joeata2wh | 0:eddce2241b50 | 63 | } |
joeata2wh | 0:eddce2241b50 | 64 | wait(charDelay); |
joeata2wh | 0:eddce2241b50 | 65 | } |
joeata2wh | 0:eddce2241b50 | 66 | currndx++; |
joeata2wh | 0:eddce2241b50 | 67 | |
joeata2wh | 0:eddce2241b50 | 68 | } |
joeata2wh | 0:eddce2241b50 | 69 | |
joeata2wh | 0:eddce2241b50 | 70 | |
joeata2wh | 0:eddce2241b50 | 71 | int main() |
joeata2wh | 0:eddce2241b50 | 72 | { |
joeata2wh | 0:eddce2241b50 | 73 | pc.baud(9600); |
joeata2wh | 0:eddce2241b50 | 74 | unsigned long *Unique = uniqueSerialAddr; |
joeata2wh | 1:61ccbbc268f6 | 75 | printf("Simple Serial# %08luX %08luX %08luX\n", Unique[0], Unique[1], Unique[2]); |
joeata2wh | 0:eddce2241b50 | 76 | |
joeata2wh | 0:eddce2241b50 | 77 | char uniqueAsStr[33]; |
joeata2wh | 0:eddce2241b50 | 78 | getUniqueIDAsStr(uniqueAsStr); |
joeata2wh | 0:eddce2241b50 | 79 | pc.printf("Serial as SID %s\n", uniqueAsStr); // send back to PC |
joeata2wh | 0:eddce2241b50 | 80 | |
joeata2wh | 0:eddce2241b50 | 81 | |
joeata2wh | 0:eddce2241b50 | 82 | while (true) { |
joeata2wh | 0:eddce2241b50 | 83 | gpo = !gpo; // toggle pin |
joeata2wh | 0:eddce2241b50 | 84 | led = !led; // toggle led |
joeata2wh | 0:eddce2241b50 | 85 | |
joeata2wh | 0:eddce2241b50 | 86 | slcd.clear(); |
joeata2wh | 0:eddce2241b50 | 87 | scroll(lcdlen, uniqueAsStr, 1.2); |
joeata2wh | 0:eddce2241b50 | 88 | wait(2.0); |
joeata2wh | 0:eddce2241b50 | 89 | } |
joeata2wh | 0:eddce2241b50 | 90 | } |