├── Makefile ├── README.txt ├── base64.c ├── base64.h ├── chksum.c ├── chksum.h ├── code_dev.io.asc ├── const.c ├── lpcflash.c ├── lpcisp.h ├── msg.c ├── msg.h ├── serial.c ├── serial.h ├── serial_cmd.c └── serial_cmd.h /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # lpcflash Makefile 3 | # this file is part of the lpcflash tool 4 | # Thorsten 'ths' Schroeder 5 | # Berlin, Germany, 20110111 6 | # 7 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 8 | # 9 | # Redistribution and use in source and binary forms, with or without modification, are 10 | # permitted provided that the following conditions are met: 11 | # 12 | # 1. Redistributions of source code must retain the above copyright notice, this list of 13 | # conditions and the following disclaimer. 14 | # 15 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 16 | # of conditions and the following disclaimer in the documentation and/or other materials 17 | # provided with the distribution. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 20 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 22 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 27 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | # The views and conclusions contained in the software and documentation are those of the 30 | # authors and should not be interpreted as representing official policies, either expressed 31 | # or implied, of Thorsten Schroeder. 32 | 33 | 34 | CMDS=lpcflash 35 | OBJS=lpcflash.o serial.o base64.o serial_cmd.o msg.o const.o chksum.o 36 | LIBS= 37 | INCS= 38 | CC=gcc 39 | CFLAGS=-Wall 40 | # -ansi -pedantic 41 | 42 | CFLAGS+=-g 43 | CFLAGS+=${INCS} ${LIBS} 44 | #CFLAGS+=-DWITH_MAGIC_SLEEP 45 | 46 | all: lpcflash 47 | 48 | lpcflash: ${OBJS} 49 | ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS} 50 | 51 | clean: 52 | rm -fr ${OBJS} *.o *~ *.core a.out ${CMDS} 53 | 54 | .PHONY: clean all 55 | 56 | 57 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | 2011/01/30 2 | 3 | lpcflash (beta) - an opensource flash utility for NXP LPC17xx ARM CM3 series 4 | 5 | Currently supporting: 6 | - boot rom/on-chip serial bootloader. 7 | - all lpc1700 boot rom loader compatible bootloaders, such as the usb cdc secondary bootloader included in 8 | the opensource LPCboot Suite (will be released soon) 9 | 10 | lpcflash was written by Thorsten Schroeder and is released under the 2-clause BSD license. Even though it is released under a very flexible and free licence, feedback and feature requests are highly appreciated. 11 | 12 | PLATFORMS 13 | 14 | lpcflash was tested under Mac OSX 10.6.6 and Ubuntu 10.04 LTS. Target platforms are all LPC1700 based ARM Coretex-M3 processors. 15 | 16 | BUILD 17 | 18 | $ make 19 | gcc -Wall -g -c -o lpcflash.o lpcflash.c 20 | gcc -Wall -g -c -o serial.o serial.c 21 | gcc -Wall -g -c -o base64.o base64.c 22 | gcc -Wall -g -c -o serial_cmd.o serial_cmd.c 23 | gcc -Wall -g -c -o msg.o msg.c 24 | gcc -Wall -g -c -o const.o const.c 25 | gcc -Wall -g -c -o chksum.o chksum.c 26 | gcc -Wall -g -o lpcflash lpcflash.o serial.o base64.o serial_cmd.o msg.o const.o chksum.o 27 | 28 | 29 | USAGE 30 | 31 | $ ./lpcflash 32 | usage: lpcflash 33 | -l (8N1 cu device) 34 | -b (default 115200UL) 35 | -f (.bin file) 36 | -o 37 | -c (default: 100000UL) 38 | -A (all flash sectors) 39 | -R (default: 0x10000400UL) 40 | -F 41 | -T 42 | -B 43 | -a (ram/rom memory address in hex) 44 | -s (only for -a: size in hex - word aligned) 45 | [-v] (be verbose) 46 | [-h] ( _o/ ) 47 | [-i] (dump cpu infos) 48 | [-e] (erase only (== erase and exit)) 49 | [-] More infos at https://project.dev.io/code/arm/ 50 | 51 | 52 | FEATURES 53 | 54 | + Erase all flash ROM sectors 55 | + Erase selected flash ROM sectors/ranges 56 | + Dump/Read flash ROM and SRAM memory (if not protected by CRP) by sector/ranges 57 | + Dump/Read flash ROM and SRAM memory (if not protected by CRP) by addresses/ranges 58 | + Download/Write flash ROM and SRAM memory (if not protected by CRP) by sector/ranges 59 | + Download/Write flash ROM and SRAM memory (if not protected by CRP) by addresses/ranges 60 | 61 | Everything that is specified within the LPC17xx user documentation (ISP/IAP (flash) memory programming) has also been implemented in the USB CDC secondary bootloader firmware to be able using lpcflash also with this opensource bootloader skeletton (this also allows some kind of crypto layer for integrity checks of the firmware etc). 62 | 63 | EXAMPLES: 64 | 65 | 1) Erase all sectors on an LPC1756 using the on-chip bootloader via serial line 66 | 67 | $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -e -A 68 | [*] 69 | [*] Detected part ID = 0x25011723: 70 | [*] Total number of 4k/32k ROM sectors: 0x15 71 | [*] Part serial no: 0x05050502 53360752 4A83D292 F5000003 72 | [*] Boot code: 0x1 73 | [*] 74 | [+] erasing sectors 0 - 21 - done. 75 | 76 | 2) Write a firmware image file to flash ROM sector 0, using the LPC1756 on-chip bootloader via serial line 77 | 78 | $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -f testbinaries/keykerikiv2-blinke-flashplace-0000h.bin 79 | [*] 80 | [*] Detected part ID = 0x25011723: 81 | [*] Total number of 4k/32k ROM sectors: 0x15 82 | [*] Part serial no: 0x05050502 53360752 4A83D292 F5000003 83 | [*] Boot code: 0x1 84 | [*] 85 | [+] erasing sectors 0 - 0 - done. 86 | [*] Firmware image testbinaries/keykerikiv2-blinke-flashplace-0000h.bin: 87 | [*] Size (bytes): 0x1000 88 | [*] First ROM sector: 0x0 89 | [*] Last ROM sector: 0x1 of 0x15 90 | [*] 91 | [-] current sector: 0x00 - 0x00000200 of 0x00000E00 bytes written 92 | [-] current sector: 0x00 - 0x00000400 of 0x00000E00 bytes written 93 | [-] current sector: 0x00 - 0x00000600 of 0x00000E00 bytes written 94 | [-] current sector: 0x00 - 0x00000800 of 0x00000E00 bytes written 95 | [-] current sector: 0x00 - 0x00000A00 of 0x00000E00 bytes written 96 | [-] current sector: 0x00 - 0x00000C00 of 0x00000E00 bytes written 97 | [-] current sector: 0x00 - 0x00000E00 of 0x00000E00 bytes written 98 | [*] done. 99 | 100 | 3) hexdump (to stdout) flash ROM address 0x00000000-0x00001000 of an LPC1756 using the on-chip bootloader via serial line 101 | 102 | $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -a 0x00000000 -s 0x1000 103 | [*] 104 | [*] Detected part ID = 0x25011723: 105 | [*] Total number of 4k/32k ROM sectors: 0x15 106 | [*] Part serial no: 0x05050502 53360752 4A83D292 F5000003 107 | [*] Boot code: 0x1 108 | [*] 109 | [+] remapping boot interrupt vector. 110 | [*] read 00001000 of 00001000 Bytes from address 00000000 111 | 00000 2c 01 00 10 e5 01 00 00 f7 01 00 00 f9 01 00 00 , 112 | 00010 fb 01 00 00 fd 01 00 00 ff 01 00 00 08 f3 ff ef 113 | 00020 00 00 00 00 00 00 00 00 00 00 00 00 01 02 00 00 114 | 00030 03 02 00 00 00 00 00 00 83 0d 00 00 25 04 00 00 % 115 | 00040 09 02 00 00 65 02 00 00 0d 02 00 00 0f 02 00 00 e 116 | 00050 11 02 00 00 13 02 00 00 15 02 00 00 17 02 00 00 117 | 00060 19 02 00 00 1b 02 00 00 1d 02 00 00 1f 02 00 00 118 | 00070 21 02 00 00 23 02 00 00 25 02 00 00 27 02 00 00 ! # % ' 119 | 00080 29 02 00 00 2b 02 00 00 2d 02 00 00 2f 02 00 00 ) + - / 120 | 00090 31 02 00 00 33 02 00 00 35 02 00 00 37 02 00 00 1 3 5 7 121 | 000a0 39 02 00 00 3b 02 00 00 3d 02 00 00 3f 02 00 00 9 ; = ? 122 | 000b0 41 02 00 00 43 02 00 00 45 02 00 00 47 02 00 00 A C E G 123 | 000c0 49 02 00 00 4b 02 00 00 4d 02 00 00 2b 49 8d 46 I K M +I F 124 | 000d0 2b 49 2c 48 0a 1a 04 d0 81 f3 09 88 02 22 82 f3 +I,H " 125 | [...] 126 | 127 | 128 | 4) hexdump (to stdout) 256 bytes of SRAM address 0x10000000 of an LPC1756 using the on-chip bootloader via serial line 129 | 130 | $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -a 0x10000000 -s 0x100 131 | [*] 132 | [*] Detected part ID = 0x25011723: 133 | [*] Total number of 4k/32k ROM sectors: 0x15 134 | [*] Part serial no: 0x05050502 53360752 4A83D292 F5000003 135 | [*] Boot code: 0x1 136 | [*] 137 | [+] remapping boot interrupt vector. 138 | [*] read 00000100 of 00000100 Bytes from address 10000000 139 | 10000000 00 e1 f5 05 01 00 00 00 00 00 00 00 00 00 00 00 140 | 10000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 141 | 10000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 142 | 10000030 80 00 00 00 94 18 48 9c fd 3b 41 f4 49 02 24 69 H ;A I $i 143 | 10000040 b4 8c 9c f8 49 27 0c 44 7c a3 67 ee fa c3 ba cf I' D| g 144 | 10000050 84 e5 fc 2c a2 49 10 c3 22 9f f7 b9 e5 00 70 b5 , I " p 145 | 10000060 90 23 9a ec 81 0b 09 f1 8e d1 18 b4 39 08 4a 81 # 9 J 146 | 10000070 8d 71 6d f8 16 08 2b 93 0c 2a 13 51 02 d7 88 9a qm + * Q 147 | 10000080 b8 77 43 35 72 e1 30 4c 85 f7 1e 04 1b 10 08 69 wC5r 0L i 148 | 10000090 7d 05 15 78 17 84 00 18 48 ef b8 2e 30 df a0 d0 } x H .0 149 | 100000a0 b6 21 06 b9 d1 ba 6b 6c 4c 25 99 c9 a2 00 88 a1 ! klL% 150 | 100000b0 64 24 a2 b7 78 1e c2 09 99 53 89 ee a9 29 1b b2 d$ x S ) 151 | 100000c0 9f 8f 4c 89 db 0f 54 a1 db 72 b5 5a 01 dc 8c 80 L T r Z 152 | 100000d0 22 bb 93 b4 db 19 80 82 c8 fb d1 0e 99 98 2f cc " / 153 | 100000e0 9b e1 40 0e 5b 54 b2 51 44 ad fb 01 41 96 45 6d @ [T QD A Em 154 | 100000f0 fc 5a 84 cf 2d cb fe 28 07 6b 75 a6 f8 c0 64 32 Z - ( ku d2 155 | 156 | 5) Dumping all flash ROM sectors of an LPC1756 to file, starting at flash ROM base sector 0 157 | 158 | $ ./lpcflash -l /dev/cu.usbserial-A1004cdd -b 115200 -A -B 0 -o flashrom.bin 159 | [*] 160 | [*] Detected part ID = 0x25011723: 161 | [*] Total number of 4k/32k ROM sectors: 0x15 162 | [*] Part serial no: 0x05050502 53360752 4A83D292 F5000003 163 | [*] Boot code: 0x1 164 | [*] 165 | [*] ROM image flashrom.bin: 166 | [*] Size (bytes): 0x3F000 167 | [*] First ROM sector: 0x0 168 | [*] Last ROM sector: 0x15 169 | [*] 170 | [+] remapping boot interrupt vector. 171 | [+] reading sector 0 - 21. Starting at address 00000000, reading 262144 bytes 172 | [*] read 00040000 of 00040000 Bytes from address 00000000 173 | 174 | Why? 175 | 176 | The Official FlashMagic Tool for this task, which is recommended and referred to by NXP is available only for Microsoft Windows operating systems. There is no sourcecode available for porting it to different platforms, and the usage scenarios are quite restricted for non-paying customers. The free FlashMagicTool version is quite restrictive. LPCFlash utility is available as source code under the BSD license. It has been tested with Mac OSX and Linux. A complete list of supported platforms is available in the source code. 177 | 178 | Where? 179 | 180 | 181 | Please be aware, that this version is a very early beta testing version. Please send wishes, recommendations, bug-reports and comments to me, using email. Every feedback is highly appreciated! 182 | 183 | What else? 184 | 185 | I'm also working on an open-source LPCboot Suite 186 | 187 | Support? 188 | 189 | Hardware and Developer Boards are expensive. Hardware donations are highly appreciated... 190 | 191 | 192 | 193 | 194 | 195 | 196 | -------------------------------------------------------------------------------- /base64.c: -------------------------------------------------------------------------------- 1 | // 2 | // base64.c 3 | // lpcflash 4 | // 5 | // Created by ths on 2011-01-17. 6 | // Copyright 2011 ths @ dev.io. All rights reserved. 7 | // 8 | 9 | /* 10 | # 11 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 12 | # 13 | # Redistribution and use in source and binary forms, with or without modification, are 14 | # permitted provided that the following conditions are met: 15 | # 16 | # 1. Redistributions of source code must retain the above copyright notice, this list of 17 | # conditions and the following disclaimer. 18 | # 19 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 20 | # of conditions and the following disclaimer in the documentation and/or other materials 21 | # provided with the distribution. 22 | # 23 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 25 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 26 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 29 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | # The views and conclusions contained in the software and documentation are those of the 34 | # authors and should not be interpreted as representing official policies, either expressed 35 | # or implied, of Thorsten Schroeder. 36 | # 37 | * 38 | * */ 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | #include "base64.h" 45 | 46 | unsigned int raw_uu_encode( unsigned char *out, unsigned int binlen, unsigned char *in) 47 | { 48 | unsigned b=0; 49 | int incnt = 0; 50 | int outcnt = 0; 51 | int modcnt = 0; 52 | 53 | modcnt = (binlen%3); 54 | 55 | incnt = binlen / 3; 56 | incnt += modcnt; 57 | 58 | for(b=0;b<(incnt);b++) { 59 | 60 | unsigned int _in = 0; 61 | 62 | _in |= (*in << 16) & 0x00ff0000; 63 | 64 | if(b==incnt-1) { 65 | if(modcnt == 2) { 66 | _in |= (0 << 0) & 0x0000ff00; 67 | _in |= (0 << 0) & 0x000000ff; 68 | } else if(modcnt == 1) { 69 | _in |= (*(in+1) << 8) & 0x0000ff00; 70 | _in |= (0 << 0) & 0x000000ff; 71 | } else if (modcnt == 0) { 72 | _in |= (*(in+1) << 8) & 0x0000ff00; 73 | _in |= (*(in+2) << 0) & 0x000000ff; 74 | } 75 | } else { 76 | _in |= (*(in+1) << 8) & 0x0000ff00; 77 | _in |= (*(in+2) << 0) & 0x000000ff; 78 | } 79 | 80 | in+=3; 81 | 82 | out[outcnt+0] = ((_in >> 18) & 0x3F) + 0x20; 83 | out[outcnt+1] = ((_in >> 12) & 0x3F) + 0x20; 84 | out[outcnt+2] = ((_in >> 6) & 0x3F) + 0x20; 85 | out[outcnt+3] = ((_in >> 0) & 0x3F) + 0x20; 86 | 87 | outcnt+=4; 88 | } 89 | return outcnt; 90 | } 91 | 92 | 93 | unsigned int raw_uu_decode_set( unsigned char *in, unsigned char *set) 94 | { 95 | set[0]=set[1]=set[2]=0; 96 | 97 | set[0] =((in[0]-32)<<2); 98 | set[0]|=((in[1]-32)>>4) & 0x03; 99 | 100 | set[1] =((in[1]-32)<<4) & 0xf0; 101 | set[1]|=((in[2]-32)>>2) & 0x0f; 102 | 103 | set[2] =((in[2]-32)<<6) & 0xC0; 104 | set[2]|=((in[3]-32)) & 0x3F; 105 | 106 | return 3; 107 | } 108 | 109 | 110 | unsigned int raw_uu_decode( unsigned char *in, unsigned char *out) 111 | { 112 | unsigned int binlen = 0; 113 | unsigned char o1=0; 114 | unsigned char o2=0; 115 | unsigned char o3=0; 116 | unsigned int i=0; 117 | unsigned b=0; 118 | 119 | binlen = (*(in++) - 32) & 0xFF; 120 | 121 | for(i=0;i<60;i+=4) { 122 | 123 | o1=o2=o3=0; 124 | 125 | o1 =((in[i+0]-32)<<2); 126 | o1|=((in[i+1]-32)>>4) & 0x03; 127 | 128 | o2 =((in[i+1]-32)<<4) & 0xf0; 129 | o2|=((in[i+2]-32)>>2) & 0x0f; 130 | 131 | o3 =((in[i+2]-32)<<6) & 0xC0; 132 | o3|=((in[i+3]-32)) & 0x3F; 133 | 134 | out[b++] = o1; 135 | out[b++] = o2; 136 | out[b++] = o3; 137 | 138 | if (b >= binlen) { 139 | b=binlen; 140 | break; 141 | } 142 | } 143 | return b; 144 | } 145 | -------------------------------------------------------------------------------- /base64.h: -------------------------------------------------------------------------------- 1 | // 2 | // base64.h 3 | // lpcflash 4 | // 5 | // Created by ths on 2011-01-17. 6 | // Copyright 2011 ths @ dev.io. All rights reserved. 7 | // 8 | 9 | /* 10 | # 11 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 12 | # 13 | # Redistribution and use in source and binary forms, with or without modification, are 14 | # permitted provided that the following conditions are met: 15 | # 16 | # 1. Redistributions of source code must retain the above copyright notice, this list of 17 | # conditions and the following disclaimer. 18 | # 19 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 20 | # of conditions and the following disclaimer in the documentation and/or other materials 21 | # provided with the distribution. 22 | # 23 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 25 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 26 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 29 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | # The views and conclusions contained in the software and documentation are those of the 34 | # authors and should not be interpreted as representing official policies, either expressed 35 | # or implied, of Thorsten Schroeder. 36 | 37 | * */ 38 | 39 | #ifndef _BASE64_H 40 | #define _BASE64_H 41 | 42 | unsigned int raw_uu_decode( unsigned char *, unsigned char *); 43 | unsigned int raw_uu_encode( unsigned char *, unsigned int, unsigned char *); 44 | 45 | #endif -------------------------------------------------------------------------------- /chksum.c: -------------------------------------------------------------------------------- 1 | // 2 | // chksum.c 3 | // lpcflash 4 | // 5 | // Created by ths on 2011-01-30. 6 | // Copyright 2011 ths @ dev.io. All rights reserved. 7 | // 8 | 9 | /* 10 | # 11 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 12 | # 13 | # Redistribution and use in source and binary forms, with or without modification, are 14 | # permitted provided that the following conditions are met: 15 | # 16 | # 1. Redistributions of source code must retain the above copyright notice, this list of 17 | # conditions and the following disclaimer. 18 | # 19 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 20 | # of conditions and the following disclaimer in the documentation and/or other materials 21 | # provided with the distribution. 22 | # 23 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 25 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 26 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 29 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | # The views and conclusions contained in the software and documentation are those of the 34 | # authors and should not be interpreted as representing official policies, either expressed 35 | # or implied, of Thorsten Schroeder. 36 | # 37 | * */ 38 | 39 | unsigned int serial_checksum_init(void) 40 | { 41 | return 0; 42 | } 43 | 44 | 45 | unsigned int serial_checksum_update(unsigned int ctx, unsigned char *buf, unsigned int len) 46 | { 47 | int i = 0; 48 | 49 | for(i=0;i. All rights reserved. 12 | # 13 | # Redistribution and use in source and binary forms, with or without modification, are 14 | # permitted provided that the following conditions are met: 15 | # 16 | # 1. Redistributions of source code must retain the above copyright notice, this list of 17 | # conditions and the following disclaimer. 18 | # 19 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 20 | # of conditions and the following disclaimer in the documentation and/or other materials 21 | # provided with the distribution. 22 | # 23 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 25 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 26 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 29 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | # The views and conclusions contained in the software and documentation are those of the 34 | # authors and should not be interpreted as representing official policies, either expressed 35 | # or implied, of Thorsten Schroeder. 36 | # 37 | 38 | * */ 39 | 40 | 41 | #ifndef _CHKSUM_H 42 | #define _CHKSUM_H 43 | 44 | unsigned int serial_checksum_finalize(unsigned int); 45 | unsigned int serial_checksum_update(unsigned int, unsigned char *, unsigned int); 46 | unsigned int serial_checksum_init(void); 47 | 48 | #endif -------------------------------------------------------------------------------- /code_dev.io.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | Version: GnuPG v1.4.11 (Darwin) 3 | 4 | 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 172 | =HBQg 173 | -----END PGP PUBLIC KEY BLOCK----- 174 | -------------------------------------------------------------------------------- /const.c: -------------------------------------------------------------------------------- 1 | // 2 | // const.c 3 | // lpcflash 4 | // 5 | // Created by ths on 2011-01-17. 6 | // Copyright 2011 ths @ dev.io. All rights reserved. 7 | // 8 | 9 | /* 10 | # 11 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 12 | # 13 | # Redistribution and use in source and binary forms, with or without modification, are 14 | # permitted provided that the following conditions are met: 15 | # 16 | # 1. Redistributions of source code must retain the above copyright notice, this list of 17 | # conditions and the following disclaimer. 18 | # 19 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 20 | # of conditions and the following disclaimer in the documentation and/or other materials 21 | # provided with the distribution. 22 | # 23 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 25 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 26 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 29 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | # The views and conclusions contained in the software and documentation are those of the 34 | # authors and should not be interpreted as representing official policies, either expressed 35 | # or implied, of Thorsten Schroeder. 36 | # 37 | 38 | * 39 | * */ 40 | 41 | #include 42 | #include 43 | 44 | const char *lpcisp_status_msg[] = { 45 | "CMD_SUCCESS", 46 | "INVALID_COMMAND", 47 | "SRC_ADDR_ERROR", 48 | "DST_ADDR_ERROR", 49 | "SRC_ADDR_NOT_MAPPED", 50 | "DST_ADDR_NOT_MAPPED", 51 | "COUNT_ERROR", 52 | "INVALID_SECTOR", 53 | "SECTOR_NOT_BLANK", 54 | "SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION", 55 | "COMPARE_ERROR", 56 | "BUSY", 57 | "PARAM_ERROR", 58 | "ADDR_ERROR", 59 | "ADDR_NOT_MAPPED", 60 | "CMD_LOCKED", 61 | "INVALID_CODE", 62 | "INVALID_BAUD_RATE", 63 | "INVALID_STOP_BIT", 64 | "CODE_READ_PROTECTION_ENABLED", 65 | NULL 66 | }; 67 | 68 | /* array of arrays with start and end addresses of each sector 69 | * - this is necessary, since sector sizes are different 70 | */ 71 | const unsigned long sector_address[][2] = { 72 | {0x00000000,0x00000FFF}, 73 | {0x00001000,0x00001FFF}, 74 | {0x00002000,0x00002FFF}, 75 | {0x00003000,0x00003FFF}, 76 | {0x00004000,0x00004FFF}, 77 | {0x00005000,0x00005FFF}, 78 | {0x00006000,0x00006FFF}, 79 | {0x00007000,0x00007FFF}, 80 | {0x00008000,0x00008FFF}, 81 | {0x00009000,0x00009FFF}, 82 | {0x0000A000,0x0000AFFF}, 83 | {0x0000B000,0x0000BFFF}, 84 | {0x0000C000,0x0000CFFF}, 85 | {0x0000D000,0x0000DFFF}, 86 | {0x0000E000,0x0000EFFF}, 87 | {0x0000F000,0x0000FFFF}, 88 | {0x00010000,0x00017FFF}, 89 | {0x00018000,0x0001FFFF}, 90 | {0x00020000,0x00027FFF}, 91 | {0x00028000,0x0002FFFF}, 92 | {0x00030000,0x00037FFF}, 93 | {0x00038000,0x0003FFFF}, 94 | {0x00040000,0x00047FFF}, 95 | {0x00048000,0x0004FFFF}, 96 | {0x00050000,0x00057FFF}, 97 | {0x00058000,0x0005FFFF}, 98 | {0x00060000,0x00067FFF}, 99 | {0x00068000,0x0006FFFF}, 100 | {0x00070000,0x00077FFF}, 101 | {0x00078000,0x0007FFFF} 102 | }; 103 | 104 | -------------------------------------------------------------------------------- /lpcflash.c: -------------------------------------------------------------------------------- 1 | // 2 | // lpcflash.c 3 | // lpcflash tool main file 4 | // 5 | // Created by ths on 2011-01-30. 6 | // Copyright 2011 ths @ dev.io. All rights reserved. 7 | // 8 | 9 | /* 10 | * lpcflash - an LPC17xx bootloader IAP/ISP flash programming tool 11 | * 12 | * Thorsten Schroeder 13 | * 20110130, Berlin, Germany 14 | * 15 | 16 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 17 | # 18 | # Redistribution and use in source and binary forms, with or without modification, are 19 | # permitted provided that the following conditions are met: 20 | # 21 | # 1. Redistributions of source code must retain the above copyright notice, this list of 22 | # conditions and the following disclaimer. 23 | # 24 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 25 | # of conditions and the following disclaimer in the documentation and/or other materials 26 | # provided with the distribution. 27 | # 28 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 29 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 30 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 31 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 33 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 34 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 36 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | 38 | # The views and conclusions contained in the software and documentation are those of the 39 | # authors and should not be interpreted as representing official policies, either expressed 40 | # or implied, of Thorsten Schroeder. 41 | 42 | * 43 | * */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | #include 58 | 59 | #include "serial.h" 60 | #include "serial_cmd.h" 61 | 62 | #include "lpcisp.h" 63 | 64 | // XXX THS: Todo: parse SP and PC value at binary file offset 0 to get sector base address 65 | #define DEFAULT_SECTOR_BASE 0 66 | #define DEFAULT_ROM_BASE_ADDR (DEFAULT_SECTOR_BASE * 4096) 67 | #define DEFAULT_BAUDRATE 115200UL 68 | #define DEFAULT_DEVICE_CCLK 100000UL 69 | #define DEFAULT_RAMBUFFER_ADDR 0x10000400UL 70 | 71 | extern char **lpcisp_status_msg; 72 | 73 | typedef enum _lpcflash_cmds { 74 | LPC_NONE, 75 | LPC_INFO, 76 | LPC_ERASE, 77 | LPC_DUMPFLASH, 78 | LPC_WRITEFLASH, 79 | LPC_READMEM 80 | } lpcflash_cmd; 81 | 82 | static unsigned int lpcflash_get_lastsector(unsigned int); 83 | static void lpcflash_dumpinfo(mem_info_t *); 84 | static void lpcflash_help(void); 85 | static void lpcflash_erase(int, mem_info_t *); 86 | static int lpcflash_image_dump(int, mem_info_t *, char *); 87 | static int lpcflash_image_write(int, mem_info_t *, char *); 88 | 89 | extern const unsigned long sector_address[][2]; 90 | 91 | int main(int argc, char **argv) 92 | { 93 | char *device = NULL; 94 | char *binfile = NULL; 95 | char *outfile = NULL; 96 | 97 | char c = 0; 98 | 99 | int serial_fd = 0; 100 | int verbose = 0; 101 | 102 | mem_info_t mem; 103 | 104 | unsigned int opt_flash_sector_all = 0; 105 | unsigned int opt_flash_sector_from = 0; 106 | unsigned int opt_flash_sector_to = 0; 107 | 108 | unsigned long read_addr=0; 109 | unsigned long read_size=32; 110 | 111 | unsigned long baudrate = DEFAULT_BAUDRATE; 112 | unsigned int opt_lpcflash_cmd = LPC_NONE; 113 | 114 | memset(&mem, 0, sizeof(mem)); 115 | 116 | mem.ram_buffer_address = DEFAULT_RAMBUFFER_ADDR; 117 | mem.rom_sector_base = DEFAULT_SECTOR_BASE; 118 | mem.rom_address_base = DEFAULT_ROM_BASE_ADDR; 119 | mem.cclk = DEFAULT_DEVICE_CCLK; 120 | 121 | /* parse command line */ 122 | while( ( c = getopt(argc, argv, "l:b:f:c:o:hvieAR:F:T:B:a:s:") ) != -1 ) { 123 | switch(c) { 124 | 125 | case 'l': /* line - cu/tty device file */ 126 | device = optarg; 127 | break; 128 | 129 | case 'b': /* baudrate */ 130 | baudrate = (int)atoi(optarg); 131 | break; 132 | 133 | case 'f': /* infile */ 134 | binfile = optarg; 135 | opt_lpcflash_cmd = LPC_WRITEFLASH; 136 | break; 137 | 138 | case 'c': /* cclk in kHz */ 139 | mem.cclk = (unsigned long)atol(optarg);; 140 | break; 141 | 142 | case 'o': /* outfile */ 143 | outfile = optarg; 144 | opt_lpcflash_cmd = LPC_DUMPFLASH; 145 | break; 146 | 147 | case 'R': /* RAM buffer address */ 148 | mem.ram_buffer_address = (unsigned long)atol(optarg); 149 | break; 150 | 151 | case 'F': /* Flash ROM _F_rom sector */ 152 | mem.img_sector_base = opt_flash_sector_from = (int)atoi(optarg); 153 | break; 154 | 155 | case 'T': /* Flash ROM _T_o sector */ 156 | mem.img_sector_last = opt_flash_sector_to = (int)atoi(optarg); 157 | break; 158 | 159 | case 'A': /* Flash ROM _A_ll sectors */ 160 | opt_flash_sector_all = 1; 161 | break; 162 | 163 | case 'B': /* Flash ROM sector _B_ase */ 164 | mem.rom_sector_base = (int)atoi(optarg); 165 | mem.rom_address_base = (unsigned long)(mem.rom_sector_base * 0x1000); 166 | break; 167 | 168 | case 'a': /* read mem addr */ 169 | read_addr = (unsigned long)strtol(optarg, NULL, 16); 170 | opt_lpcflash_cmd = LPC_READMEM; 171 | 172 | break; 173 | case 's': /* read size bytes at mem addr */ 174 | read_size = (unsigned long)strtol(optarg, NULL, 16); 175 | break; 176 | 177 | case 'v': /* verbose */ 178 | verbose=1; 179 | break; 180 | 181 | case 'i': /* dump cpu info */ 182 | opt_lpcflash_cmd = LPC_INFO; 183 | break; 184 | 185 | case 'e': /* erase flash rom and exit */ 186 | opt_lpcflash_cmd = LPC_ERASE; 187 | break; 188 | 189 | case 'h': /* help */ 190 | default: 191 | lpcflash_help(); 192 | return 0; 193 | } 194 | } 195 | 196 | if ( !( 197 | (device) && 198 | (binfile || outfile || opt_lpcflash_cmd) 199 | ) ) { 200 | lpcflash_help(); 201 | exit(1); 202 | } 203 | 204 | /* open serial port */ 205 | serial_fd = serial_open(device, baudrate); 206 | 207 | if(serial_fd<0) 208 | return(1); 209 | 210 | serial_synchronize(serial_fd, mem.cclk); 211 | serial_cmd_read_partid(serial_fd, &mem.cpu.id); 212 | serial_cmd_read_bootcode_version(serial_fd, &mem.cpu.bootcode); 213 | serial_cmd_read_device_serialno(serial_fd, mem.cpu.serial); 214 | 215 | if(opt_flash_sector_from < mem.rom_sector_base) 216 | opt_flash_sector_from = mem.rom_sector_base; 217 | 218 | if(opt_flash_sector_to > lpcflash_get_lastsector(mem.cpu.id)) 219 | opt_flash_sector_to = lpcflash_get_lastsector(mem.cpu.id); 220 | 221 | else if(opt_flash_sector_to < opt_flash_sector_from) 222 | opt_flash_sector_to = opt_flash_sector_from; 223 | 224 | mem.img_sector_base = opt_flash_sector_from; 225 | mem.img_sector_last = opt_flash_sector_to; 226 | mem.rom_sector_last = lpcflash_get_lastsector(mem.cpu.id); 227 | mem.rom_address_base = mem.rom_sector_base * 0x1000; 228 | 229 | 230 | serial_cmd_unlock(serial_fd); 231 | 232 | if(opt_flash_sector_all != 0) { 233 | mem.img_sector_last = mem.rom_sector_last; 234 | mem.img_sector_base = mem.rom_sector_base; 235 | } 236 | 237 | lpcflash_dumpinfo(&mem); 238 | 239 | if (opt_lpcflash_cmd == LPC_ERASE) { 240 | 241 | // erase only 242 | lpcflash_erase(serial_fd, &mem); 243 | close(serial_fd); 244 | return 0; 245 | 246 | } else if(opt_lpcflash_cmd == LPC_INFO) { 247 | 248 | // dump info only 249 | close(serial_fd); 250 | return 0; 251 | 252 | } else if(opt_lpcflash_cmd == LPC_WRITEFLASH) { 253 | 254 | lpcflash_erase(serial_fd, &mem); 255 | lpcflash_image_write(serial_fd, &mem, binfile); 256 | 257 | } else if (opt_lpcflash_cmd == LPC_DUMPFLASH) { 258 | 259 | lpcflash_image_dump(serial_fd, &mem, outfile); 260 | 261 | } else if (opt_lpcflash_cmd == LPC_READMEM) { 262 | // echo off 263 | serial_cmd_echo(serial_fd, 0); 264 | serial_cmd_remap_bootvect(serial_fd, mem.ram_buffer_address); 265 | serial_cmd_read_memory(serial_fd, outfile, read_addr, read_size); 266 | } 267 | 268 | close(serial_fd); 269 | return(0); 270 | } 271 | 272 | 273 | 274 | static void lpcflash_erase(int serial_fd, mem_info_t *mem) 275 | { 276 | /* erase [entire] (user) flash rom */ 277 | printf("[+] erasing sectors %ld - %d", mem->rom_address_base, mem->rom_sector_last); 278 | serial_cmd_prepare_sector(serial_fd, mem->rom_address_base, mem->rom_sector_last); 279 | serial_cmd_erase_sector(serial_fd, mem->rom_address_base, mem->rom_sector_last); 280 | printf(" - done.\n"); 281 | 282 | return; 283 | } 284 | 285 | static int lpcflash_image_write(int serial_fd, mem_info_t *mem, char *imgpath) 286 | { 287 | 288 | struct stat bin_stat; 289 | unsigned char outbuf[512]; 290 | unsigned int nwritten = 0; 291 | unsigned int i = 0; 292 | 293 | int bin_fd = open(imgpath, O_RDONLY); 294 | if(bin_fd < 0) { 295 | err(0, "open binary file"); 296 | return -1; 297 | } 298 | 299 | if(fstat(bin_fd, &bin_stat) < 0) { 300 | err(0, "fstat binary file"); 301 | return -1; 302 | } 303 | 304 | /* 305 | * sector size 4k from sector 0x00 - 0x0F (0000 0000 - 0000 FFFF) 306 | * sector size 32k from sector 0x10 - 0x15 (0001 0000 - 0001 7FFF) 307 | * 308 | */ 309 | 310 | switch(mem->cpu.id) { 311 | case PART_LPC1343: 312 | // 32kB ROM 313 | mem->img_sector_last = (bin_stat.st_size + (0x1000 - (bin_stat.st_size % 0x1000))) / 0x1000; 314 | mem->rom_sector_last = 0x07; 315 | mem->rom_total_size = mem->rom_sector_last * 0x1000; 316 | break; 317 | case PART_LPC1751: 318 | // 32kB ROM 319 | mem->img_sector_last = (bin_stat.st_size + (0x1000 - (bin_stat.st_size % 0x1000))) / 0x1000; 320 | mem->img_total_size = mem->img_sector_last * 0x1000; 321 | mem->rom_sector_last = 0x07; 322 | break; 323 | 324 | case PART_LPC1752: 325 | // 64 kB ROM 326 | mem->img_sector_last = (bin_stat.st_size + (0x1000 - (bin_stat.st_size % 0x1000))) / 0x1000; 327 | mem->img_total_size = mem->img_sector_last * 0x1000; 328 | mem->rom_sector_last = 0x0f; 329 | break; 330 | 331 | case PART_LPC1754: 332 | case PART_LPC1764: 333 | // 128 kB ROM 334 | /* determine sectors used by firmware image */ 335 | if(bin_stat.st_size < 0x00010000) { // only 4k sectors are used 336 | mem->img_sector_last = (bin_stat.st_size + (0x1000 - (bin_stat.st_size % 0x1000))) / 0x1000; 337 | mem->img_total_size = mem->img_sector_last * 0x1000; 338 | } else { 339 | mem->img_sector_last = 0x0f + ((bin_stat.st_size - 0x10000) + (0x8000 - ((bin_stat.st_size - 0x10000) % 0x8000))) / 0x8000; 340 | mem->img_total_size = mem->img_sector_last * 0x8000; 341 | } 342 | mem->rom_sector_last = 0x11; 343 | break; 344 | 345 | case PART_LPC1756: 346 | case PART_LPC1763: 347 | case PART_LPC1765: 348 | case PART_LPC1766: 349 | // 256kB ROM 350 | /* determine sectors used by firmware image */ 351 | if(bin_stat.st_size < 0x00010000) { // only 4k sectors are used 352 | mem->img_sector_last = (bin_stat.st_size + (0x1000 - (bin_stat.st_size % 0x1000))) / 0x1000; 353 | mem->img_total_size = mem->img_sector_last * 0x1000; 354 | printf("D1: mem->img_sector_last = %x\nD1: mem->img_total_size = %x\n", mem->img_sector_last, mem->img_total_size); 355 | } else { 356 | mem->img_sector_last = 0x0f + ((bin_stat.st_size - 0x10000) + (0x8000 - ((bin_stat.st_size - 0x10000) % 0x8000))) / 0x8000; 357 | mem->img_total_size = mem->img_sector_last * 0x8000; 358 | printf("D2: mem->img_sector_last = %x\nD2: mem->img_total_size = %x\n", mem->img_sector_last, mem->img_total_size); 359 | } 360 | mem->rom_sector_last = 0x15; 361 | 362 | break; 363 | 364 | case PART_LPC1767: 365 | case PART_LPC1768: 366 | case PART_LPC1769: 367 | case PART_LPC1758: 368 | // 512 kB ROM 369 | /* determine sectors used by firmware image */ 370 | if(bin_stat.st_size < 0x00010000) { // only 4k sectors are used 371 | mem->img_sector_last = (bin_stat.st_size + (0x1000 - (bin_stat.st_size % 0x1000))) / 0x1000; 372 | mem->img_total_size = mem->img_sector_last * 0x1000; 373 | } else { 374 | mem->img_sector_last = 0x0f + ((bin_stat.st_size - 0x10000) + (0x8000 - ((bin_stat.st_size - 0x10000) % 0x8000))) / 0x8000; 375 | mem->img_total_size = mem->img_sector_last * 0x8000; 376 | } 377 | mem->rom_sector_last = 0x1d; 378 | break; 379 | 380 | default: 381 | printf("[e] Unknown part id (%08x)\n", mem->cpu.id); 382 | mem->img_sector_last = 0; 383 | mem->img_total_size = 0; 384 | mem->rom_sector_last = 0; 385 | 386 | return -1; 387 | break; 388 | } 389 | 390 | // perform write 391 | 392 | printf("[*] Firmware image %s:\n", imgpath); 393 | printf("[*] Size (bytes): 0x%X\n", mem->img_total_size); 394 | printf("[*] First ROM sector: 0x%X\n", mem->img_sector_base); 395 | printf("[*] Last ROM sector: 0x%X of 0x%X\n", mem->img_sector_last+mem->rom_sector_base, mem->rom_sector_last); 396 | printf("[*] \n"); 397 | 398 | if(mem->rom_sector_last < mem->img_sector_last+mem->rom_sector_base) { 399 | printf("[e] Firmware image is too large (size=0x%X) to fit onto this part (id=0x%08X)\n", 400 | (unsigned int)bin_stat.st_size, mem->cpu.id); 401 | close(bin_fd); 402 | return -1; 403 | } 404 | 405 | //serial_cmd_read_memory(serial_fd, 0, 128); 406 | memset(outbuf, 0xCC, sizeof(outbuf)); 407 | 408 | // echo off 409 | serial_cmd_echo(serial_fd, 0); 410 | 411 | nwritten=0; 412 | 413 | // process 4kB sectors 414 | for(i=mem->rom_sector_base; i<=0xf && i<(mem->img_sector_last + mem->rom_sector_base); i++) { 415 | unsigned int j=0; 416 | 417 | 418 | serial_cmd_prepare_sector(serial_fd, i, i); 419 | serial_cmd_erase_sector(serial_fd, i, i); 420 | 421 | for(j=0; j < (0x1000/0x200); j++) { // write in blocksizes of 512 byte 422 | 423 | int nr = read(bin_fd, &outbuf, 512); 424 | if(nr <= 0) { // ende gelaende. 425 | break; 426 | } 427 | 428 | 429 | serial_cmd_write_to_ram(serial_fd, mem->ram_buffer_address, nr, outbuf); 430 | serial_cmd_prepare_sector(serial_fd, i, i); 431 | serial_cmd_copy_ram_to_flash(serial_fd, mem->rom_address_base + nwritten, mem->ram_buffer_address, 512); 432 | 433 | nwritten += nr; 434 | 435 | printf("[-] current 4k sector: 0x%02X - 0x%08X of 0x%08X bytes written\r\n", 436 | i, nwritten, (unsigned int)bin_stat.st_size); 437 | 438 | fflush(stdout); 439 | } 440 | } 441 | 442 | // process 32kB sectors 443 | for(; i<=(mem->img_sector_last + mem->rom_sector_base); i++) { 444 | unsigned j=0; 445 | 446 | for(j=0; j < (0x8000/0x200); j++) { // write in blocksizes of 512 byte 447 | 448 | int nr = read(bin_fd, &outbuf, 512); 449 | if(nr <= 0) { // ende gelaende. 450 | break; 451 | } 452 | 453 | serial_cmd_write_to_ram(serial_fd, mem->ram_buffer_address, nr, outbuf); 454 | serial_cmd_prepare_sector(serial_fd, i, i); 455 | serial_cmd_copy_ram_to_flash(serial_fd, mem->rom_address_base + nwritten, mem->ram_buffer_address, 512); 456 | 457 | nwritten += nr; 458 | 459 | printf("[-] current 32k sector: 0x%02X - 0x%08X of 0x%08X bytes written\r\n", 460 | i, nwritten, (unsigned int)bin_stat.st_size); 461 | 462 | fflush(stdout); 463 | } 464 | } 465 | 466 | printf("[*] done.\n"); 467 | 468 | close(bin_fd); 469 | return 0; 470 | } 471 | 472 | static int lpcflash_image_dump(int serial_fd, mem_info_t *mem, char *imgpath) 473 | { 474 | 475 | 476 | // echo off 477 | serial_cmd_echo(serial_fd, 0); 478 | 479 | /* 480 | * sector size 4k from sector 0x00 - 0x0F (0000 0000 - 0000 FFFF) 481 | * sector size 32k from sector 0x10 - 0x15 (0001 0000 - 0001 7FFF) 482 | * 483 | */ 484 | 485 | switch(mem->cpu.id) { 486 | case PART_LPC1751: 487 | // 32kB ROM 488 | mem->rom_sector_last = 0x07; 489 | mem->rom_total_size = mem->rom_sector_last * 0x1000; 490 | break; 491 | 492 | case PART_LPC1752: 493 | // 64 kB ROM 494 | 495 | mem->rom_sector_last = 0x0f; 496 | mem->rom_total_size = mem->rom_sector_last * 0x1000; 497 | 498 | break; 499 | 500 | case PART_LPC1754: 501 | case PART_LPC1764: 502 | // 128 kB ROM 503 | /* determine sectors used by firmware image */ 504 | 505 | mem->rom_sector_last = 0x11; 506 | mem->rom_total_size = 0x0F * 0x1000; 507 | mem->rom_total_size += (mem->rom_sector_last-0x0F) * 0x8000; 508 | 509 | break; 510 | 511 | case PART_LPC1756: 512 | case PART_LPC1765: 513 | case PART_LPC1766: 514 | // 256kB ROM 515 | /* determine sectors used by firmware image */ 516 | 517 | mem->rom_sector_last = 0x15; 518 | mem->rom_total_size = 0x0F * 0x1000; 519 | mem->rom_total_size += (mem->rom_sector_last-0x0F) * 0x8000; 520 | 521 | break; 522 | 523 | case PART_LPC1767: 524 | case PART_LPC1768: 525 | case PART_LPC1769: 526 | case PART_LPC1758: 527 | // 512 kB ROM 528 | /* determine sectors used by firmware image */ 529 | 530 | mem->rom_sector_last = 0x1d; 531 | mem->rom_total_size = 0x0F * 0x1000; 532 | mem->rom_total_size += (mem->rom_sector_last-0x0F) * 0x8000; 533 | 534 | break; 535 | case PART_LPC1343: 536 | // 32kB ROM 537 | mem->rom_sector_last = 0x07; 538 | mem->rom_total_size = mem->rom_sector_last * 0x1000; 539 | break; 540 | default: 541 | printf("[e] Unknown part id (%08x)\n", mem->cpu.id); 542 | mem->img_sector_last = 0; 543 | mem->img_total_size = 0; 544 | mem->rom_sector_last = 0; 545 | 546 | return -1; 547 | break; 548 | } 549 | 550 | 551 | // perform read 552 | 553 | printf("[*] ROM image %s:\n", imgpath); 554 | printf("[*] Size (bytes): 0x%X\n", mem->rom_total_size); 555 | printf("[*] First ROM sector: 0x%X\n", mem->rom_sector_base); 556 | printf("[*] Last ROM sector: 0x%X\n", mem->rom_sector_last); 557 | printf("[*] \n"); 558 | 559 | serial_cmd_remap_bootvect(serial_fd, mem->ram_buffer_address); 560 | 561 | printf("[+] reading sector %d - %d. Starting at address %08x, reading %lu bytes\n", 562 | mem->img_sector_base, 563 | mem->img_sector_last, 564 | (unsigned int)sector_address[mem->img_sector_base][START], 565 | (unsigned int)sector_address[mem->img_sector_last][END]-sector_address[mem->img_sector_base][START]+1 566 | ); 567 | 568 | // dump sectors 569 | serial_cmd_read_memory(serial_fd, imgpath, 570 | sector_address[mem->img_sector_base][START], 571 | sector_address[mem->img_sector_last][END]-sector_address[mem->img_sector_base][START]+1 572 | ); 573 | 574 | return 0; 575 | } 576 | 577 | static void lpcflash_dumpinfo(mem_info_t *mem) 578 | { 579 | 580 | printf("[*] \n"); 581 | printf("[*] Detected part ID = 0x%08X:\n", 582 | mem->cpu.id); 583 | printf("[*] Total number of 4k/32k ROM sectors: 0x%02X\n", 584 | mem->rom_sector_last); 585 | printf("[*] Part serial no: 0x%08X %08X %08X %08X\n", 586 | mem->cpu.serial[0], mem->cpu.serial[1], mem->cpu.serial[2], mem->cpu.serial[3]); 587 | printf("[*] Boot code: 0x%X\n", 588 | mem->cpu.bootcode); 589 | printf("[*] \n"); 590 | 591 | return; 592 | } 593 | 594 | static void lpcflash_help(void) 595 | { 596 | // l:b:f:c:o:hviAR:F:T:B:a:s: 597 | puts("usage: lpcflash"); 598 | puts("\t -l (8N1 cu device)"); 599 | puts("\t -b (default 115200UL)"); 600 | puts("\t -f (.bin file)"); 601 | puts("\t -o "); 602 | puts("\t -c (default: 100000UL)"); 603 | puts("\t -A (all flash sectors)"); 604 | puts("\t -R (default: 0x10000400UL)"); 605 | puts("\t -F "); 606 | puts("\t -T "); 607 | puts("\t -B "); 608 | puts("\t -a (ram/rom memory address in hex)"); 609 | puts("\t -s (only for -a: size in hex - word aligned)"); 610 | puts("\t[-v] (be verbose)"); 611 | puts("\t[-h] ( _o/ )"); 612 | puts("\t[-i] (dump cpu infos)"); 613 | puts("\t[-e] (erase only (== erase and exit))"); 614 | puts("[-] More infos at https://project.dev.io/code/arm/"); 615 | 616 | return; 617 | } 618 | 619 | 620 | static unsigned int lpcflash_get_lastsector(unsigned int id) 621 | { 622 | unsigned int last_sector=0; 623 | 624 | switch(id) { 625 | case PART_LPC1751: 626 | // 32kB ROM 627 | last_sector = 0x07; 628 | break; 629 | 630 | case PART_LPC1752: 631 | // 64 kB ROM 632 | last_sector = 0x0f; 633 | break; 634 | 635 | case PART_LPC1754: 636 | case PART_LPC1764: 637 | // 128 kB ROM 638 | last_sector = 0x11; 639 | break; 640 | 641 | case PART_LPC1756: 642 | case PART_LPC1765: 643 | case PART_LPC1766: 644 | // 256kB ROM 645 | last_sector = 0x15; 646 | break; 647 | 648 | case PART_LPC1767: 649 | case PART_LPC1768: 650 | case PART_LPC1769: 651 | case PART_LPC1758: 652 | // 512 kB ROM 653 | last_sector = 0x1d; 654 | break; 655 | case PART_LPC1343: 656 | last_sector = 0x07; 657 | break; 658 | default: 659 | printf("[e] Unknown part id (%08x)\n", id); 660 | return 0; 661 | } 662 | return last_sector; 663 | } 664 | 665 | 666 | -------------------------------------------------------------------------------- /lpcisp.h: -------------------------------------------------------------------------------- 1 | // 2 | // lpcisp.h 3 | // lpcflash 4 | // 5 | // Created by ths on 2011-01-16. 6 | // Copyright 2011 ths @ dev.io. All rights reserved. 7 | // 8 | 9 | /* 10 | # 11 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 12 | # 13 | # Redistribution and use in source and binary forms, with or without modification, are 14 | # permitted provided that the following conditions are met: 15 | # 16 | # 1. Redistributions of source code must retain the above copyright notice, this list of 17 | # conditions and the following disclaimer. 18 | # 19 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 20 | # of conditions and the following disclaimer in the documentation and/or other materials 21 | # provided with the distribution. 22 | # 23 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 25 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 26 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 29 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | # The views and conclusions contained in the software and documentation are those of the 34 | # authors and should not be interpreted as representing official policies, either expressed 35 | # or implied, of Thorsten Schroeder. 36 | # 37 | 38 | * */ 39 | 40 | #ifndef _LPCISP_H 41 | #define _LPCISP_H 42 | 43 | typedef enum _lpcisp_retcodes { 44 | CMD_SUCCESS, 45 | INVALID_COMMAND, 46 | SRC_ADDR_ERROR, 47 | DST_ADDR_ERROR, 48 | SRC_ADDR_NOT_MAPPED, 49 | DST_ADDR_NOT_MAPPED, 50 | COUNT_ERROR, 51 | INVALID_SECTOR, 52 | SECTOR_NOT_BLANK, 53 | SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION, 54 | COMPARE_ERROR, /* 10 */ 55 | BUSY, 56 | PARAM_ERROR, 57 | ADDR_ERROR, 58 | ADDR_NOT_MAPPED, 59 | CMD_LOCKED, /* 15 */ 60 | INVALID_CODE, 61 | INVALID_BAUD_RATE, 62 | INVALID_STOP_BIT, 63 | CODE_READ_PROTECTION_ENABLED 64 | } lpcisp_status_t; 65 | 66 | #define PART_LPC1769 0x26113F37UL 67 | #define PART_LPC1768 0x26013F37UL 68 | #define PART_LPC1767 0x26012837UL 69 | #define PART_LPC1766 0x26013F33UL 70 | #define PART_LPC1765 0x26013733UL 71 | #define PART_LPC1764 0x26011922UL 72 | #define PART_LPC1763 0x26012033UL 73 | #define PART_LPC1759 0x25113737UL 74 | #define PART_LPC1758 0x25013F37UL 75 | #define PART_LPC1756 0x25011723UL 76 | #define PART_LPC1754 0x25011722UL 77 | #define PART_LPC1752 0x25001121UL 78 | #define PART_LPC1751 0x25001118UL 79 | #define PART_LPC1343 0x3D00002BUL 80 | 81 | typedef struct _cpu_info_t { 82 | unsigned int id; 83 | unsigned int serial[4]; 84 | unsigned int bootcode; 85 | } cpu_info_t; 86 | 87 | typedef struct _mem_info_t { 88 | cpu_info_t cpu; 89 | unsigned int rom_sector_base; 90 | unsigned long rom_address_base; 91 | unsigned int rom_sector_last; 92 | unsigned int rom_total_size; 93 | unsigned int img_sector_base; 94 | unsigned long img_address_base; 95 | unsigned int img_sector_last; 96 | unsigned int img_total_size; 97 | unsigned long ram_buffer_address; 98 | unsigned long cclk; 99 | } mem_info_t; 100 | 101 | #define START 0 102 | #define END 1 103 | 104 | #endif -------------------------------------------------------------------------------- /msg.c: -------------------------------------------------------------------------------- 1 | // 2 | // msg.c 3 | // lpcflash 4 | // 5 | // Created by dagu on 2011-01-30. 6 | // Copyright 2011 David Gullasch. All rights reserved. 7 | // 8 | 9 | 10 | #include 11 | #include 12 | 13 | #include "msg.h" 14 | 15 | int msglevel = MSGLEVEL_NORMAL; 16 | 17 | void msg(int level, const char *function, const char *fmt, ...) 18 | { 19 | va_list args; 20 | 21 | if (level < msglevel) 22 | return; 23 | 24 | printf("%s(): ", function); 25 | va_start(args, fmt); 26 | vprintf(fmt, args); 27 | va_end(args); 28 | } 29 | -------------------------------------------------------------------------------- /msg.h: -------------------------------------------------------------------------------- 1 | // 2 | // msg.h 3 | // lpcflash 4 | // 5 | // Created by dagu on 2011-01-30. 6 | // Copyright 2011 David Gullasch. All rights reserved. 7 | // 8 | 9 | #ifndef MSG_H 10 | #define MSG_H 11 | 12 | #include 13 | 14 | #define MSGLEVEL_DEBUG 3 15 | #define MSGLEVEL_VERBOSE 2 16 | #define MSGLEVEL_NORMAL 1 17 | #define MSGLEVEL_WARN 0 18 | 19 | extern int msglevel; 20 | 21 | __attribute__((format(printf, 3, 4))) 22 | void msg(int level, const char *function, const char *fmt, ...); 23 | 24 | #define WARN(args...) msg(MSGLEVEL_WARN, __FUNCTION__, args) 25 | #define MSG(args...) msg(MSGLEVEL_NORMAL, __FUNCTION__, args) 26 | #define INFO(args...) msg(MSGLEVEL_VERBOSE, __FUNCTION__, args) 27 | #define DEBUG(args...) msg(MSGLEVEL_DEBUG, __FUNCTION__, args) 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /serial.c: -------------------------------------------------------------------------------- 1 | // 2 | // serial.c 3 | // lpcflash 4 | // 5 | // Created by ths on 2011-01-16. 6 | // 7 | // Authors: 8 | // Thorsten Schroeder 9 | // David Gullasch 10 | // 11 | // Copyright 2011 ths @ dev.io. All rights reserved. 12 | // 13 | 14 | /* 15 | # 16 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 17 | # 18 | # Redistribution and use in source and binary forms, with or without modification, are 19 | # permitted provided that the following conditions are met: 20 | # 21 | # 1. Redistributions of source code must retain the above copyright notice, this list of 22 | # conditions and the following disclaimer. 23 | # 24 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 25 | # of conditions and the following disclaimer in the documentation and/or other materials 26 | # provided with the distribution. 27 | # 28 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 29 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 30 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 31 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 33 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 34 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 36 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | 38 | # The views and conclusions contained in the software and documentation are those of the 39 | # authors and should not be interpreted as representing official policies, either expressed 40 | # or implied, of Thorsten Schroeder. 41 | # 42 | * 43 | * */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | 58 | #include "msg.h" 59 | #include "serial.h" 60 | #include "serial_cmd.h" 61 | 62 | #ifdef WITH_MAGIC_SLEEP 63 | 64 | // this function is (by now) necessary on linux, since we ran into trouble without 65 | // this break. This is completely stupid, since using this sleep, it does not even matter 66 | // wether we use 115200 or 38400 baud... therefore we have a new 67 | // XXX TODO: find a solution for the strange behavior on linux 68 | 69 | static void magic(void) 70 | { 71 | struct timespec ts; 72 | ts.tv_sec = 0; 73 | ts.tv_nsec = 10000000; 74 | nanosleep(&ts,NULL); 75 | } 76 | #endif 77 | 78 | int serial_readline(char *buf, int len, int serial_fd) 79 | { 80 | char *p = buf; 81 | size_t remaining = len; 82 | ssize_t nread; 83 | 84 | memset(buf, 0, remaining); 85 | 86 | while(remaining>0) { 87 | 88 | // need to read one character at a time to detect '\n' 89 | nread = read(serial_fd, p, 1); 90 | 91 | switch (nread) { 92 | 93 | case -1: 94 | if (errno == EAGAIN || errno == EINTR) { 95 | WARN("read interrupted"); 96 | continue; 97 | } 98 | err(1, "read(): "); 99 | break; 100 | 101 | case 0: 102 | errx(1, "unexpected EOF read"); 103 | break; 104 | } 105 | 106 | remaining -= nread; 107 | p += nread; 108 | if (p[-1] == '\n') 109 | break; 110 | } 111 | 112 | if(p-buf <= 2) 113 | WARN("short line"); 114 | else if (p[-2] != '\r' || p[-1] != '\n') 115 | WARN("no CR NL at end of line%s", remaining ? "" : " (buffer too small?)"); 116 | 117 | return p - buf; 118 | } 119 | 120 | int serial_send(int serial_fd, int len, char *data) 121 | { 122 | ssize_t nwritten; 123 | char *p = data; 124 | size_t remaining = len; 125 | 126 | #ifdef WITH_MAGIC_SLEEP 127 | // linux problem?? 128 | magic(); 129 | #endif 130 | 131 | while (remaining > 0) { 132 | errno = 0; 133 | 134 | nwritten = write(serial_fd, (unsigned char *)p, remaining); 135 | 136 | switch (nwritten) { 137 | case -1: 138 | if (errno == EAGAIN || errno == EINTR) { 139 | WARN("write interrupted"); 140 | continue; 141 | } 142 | err(1,"write(): "); 143 | break; 144 | 145 | case 0: 146 | warn("write(): "); 147 | break; 148 | } 149 | 150 | p += nwritten; 151 | remaining -= nwritten; 152 | } 153 | 154 | return p - data; 155 | } 156 | 157 | int serial_open(char *device, int baudrate) 158 | { 159 | struct termios ttyio; 160 | speed_t speed; 161 | int fd; 162 | 163 | fd=open(device, O_RDWR); 164 | if(fd<0) 165 | err(1,"serial_open: open(): "); 166 | 167 | //DEBUG("fd = %d\n", fd); 168 | 169 | if(tcgetattr(fd,&ttyio)<0) 170 | err(1,"tcgetattr(): "); 171 | 172 | /* 173 | * c_iflag 174 | */ 175 | 176 | CLR(ttyio.c_iflag,IGNBRK); 177 | // Ignore BREAK condition on input. 178 | 179 | CLR(ttyio.c_iflag,BRKINT); 180 | // If IGNBRK is set, a BREAK is ignored. If it is not set but BRKINT 181 | // is set, then a BREAK causes the input and output queues to be 182 | // flushed, and if the terminal is the controlling terminal of a 183 | // foreground process group, it will cause a SIGINT to be sent to 184 | // this foreground process group. When neither IGNBRK nor BRKINT are 185 | // set, a BREAK reads as a null byte ('\0'), except when PARMRK is 186 | // set, in which case it reads as the sequence \377 \0 \0. 187 | 188 | SET(ttyio.c_iflag,IGNPAR); 189 | // Ignore framing errors and parity errors. 190 | 191 | CLR(ttyio.c_iflag,PARMRK); 192 | // If IGNPAR is not set, prefix a character with a parity error or 193 | // framing error with \377 \0. If neither IGNPAR nor PARMRK is set, 194 | // read a character with a parity error or framing error as \0. 195 | 196 | CLR(ttyio.c_iflag,INPCK); 197 | // Enable input parity checking. 198 | 199 | CLR(ttyio.c_iflag,ISTRIP); 200 | // Strip off eighth bit. 201 | 202 | CLR(ttyio.c_iflag,INLCR); 203 | // Translate NL to CR on input. 204 | 205 | CLR(ttyio.c_iflag,IGNCR); 206 | // Ignore carriage return on input. 207 | 208 | CLR(ttyio.c_iflag,ICRNL); 209 | // Translate carriage return to newline on input (unless IGNCR is 210 | // set). 211 | 212 | SET(ttyio.c_iflag,IXON); 213 | // Enable XON/XOFF flow control on output. 214 | 215 | CLR(ttyio.c_iflag,IXANY); 216 | // (XSI) Typing any character will restart stopped output. (The 217 | // default is to allow just the START character to restart output.) 218 | 219 | SET(ttyio.c_iflag,IXOFF); 220 | // Enable XON/XOFF flow control on input. 221 | 222 | /* 223 | * c_oflag 224 | */ 225 | 226 | CLR(ttyio.c_oflag,OPOST); 227 | // Enable implementation-defined output processing. 228 | 229 | CLR(ttyio.c_oflag,ONLCR); 230 | // (XSI) Map NL to CR-NL on output. 231 | 232 | CLR(ttyio.c_oflag,OCRNL); 233 | // Map CR to NL on output. 234 | 235 | CLR(ttyio.c_oflag,ONOCR); 236 | // Don't output CR at column 0. 237 | 238 | CLR(ttyio.c_oflag,ONLRET); 239 | // Don't output CR. 240 | 241 | CLR(ttyio.c_oflag,OFILL); 242 | // Send fill characters for a delay, rather than using a timed delay. 243 | 244 | /* 245 | * c_cflag 246 | */ 247 | 248 | CLR(ttyio.c_cflag,CSIZE); 249 | SET(ttyio.c_cflag,CS8); 250 | // Character size mask. Values are CS5, CS6, CS7, or CS8. 251 | 252 | CLR(ttyio.c_cflag,CSTOPB); 253 | // Set two stop bits, rather than one. 254 | 255 | SET(ttyio.c_cflag,CREAD); 256 | // Enable receiver. 257 | 258 | CLR(ttyio.c_cflag,PARENB); 259 | // Enable parity generation on output and parity checking for input. 260 | 261 | CLR(ttyio.c_cflag,PARODD); 262 | // If set, then parity for input and output is odd; otherwise even 263 | // parity is used. 264 | 265 | CLR(ttyio.c_cflag,HUPCL); 266 | // Lower modem control lines after last process closes the device 267 | // (hang up). 268 | 269 | SET(ttyio.c_cflag,CLOCAL); 270 | // Ignore modem control lines. 271 | 272 | /* 273 | * c_lflag 274 | */ 275 | 276 | CLR(ttyio.c_cflag,ISIG); 277 | // When any of the characters INTR, QUIT, SUSP, or DSUSP are 278 | // received, generate the corresponding signal. 279 | 280 | SET(ttyio.c_cflag,ICANON); 281 | // Enable canonical mode (described below). 282 | 283 | CLR(ttyio.c_cflag,ECHO); 284 | // Echo input characters. 285 | 286 | CLR(ttyio.c_cflag,ECHOE); 287 | // If ICANON is also set, the ERASE character erases the preceding 288 | // input character, and WERASE erases the preceding word. 289 | 290 | CLR(ttyio.c_cflag,ECHOK); 291 | // If ICANON is also set, the KILL character erases the current line. 292 | 293 | CLR(ttyio.c_cflag,ECHONL); 294 | // If ICANON is also set, echo the NL character even if ECHO is not 295 | // set. 296 | 297 | CLR(ttyio.c_cflag,NOFLSH); 298 | // Disable flushing the input and output queues when generating 299 | // signals for the INT, QUIT, and SUSP characters. 300 | 301 | CLR(ttyio.c_cflag,TOSTOP); 302 | // Send the SIGTTOU signal to the process group of a background 303 | // process which tries to write to its controlling terminal. 304 | 305 | CLR(ttyio.c_cflag,IEXTEN); 306 | // Enable implementation-defined input processing. This flag, as well 307 | // as ICANON must be enabled for the special characters EOL2, LNEXT, 308 | // REPRINT, WERASE to be interpreted, and for the IUCLC flag to be 309 | // effective. 310 | 311 | /* set baudrate */ 312 | switch(baudrate) { 313 | case 115200: 314 | speed=B115200; 315 | break; 316 | case 57600: 317 | speed=B57600; 318 | break; 319 | case 38400: 320 | speed=B38400; 321 | break; 322 | case 19200: 323 | speed=B19200; 324 | break; 325 | default: 326 | MSG("invalid baud rate (%d)\n",baudrate); 327 | baudrate=9600; 328 | // fallthrough 329 | case 9600: 330 | speed=B9600; 331 | break; 332 | case 4800: 333 | speed=B4800; 334 | break; 335 | } 336 | 337 | if(cfsetispeed(&ttyio,speed)<0) 338 | err(1,"cfsetispeed(): "); 339 | 340 | if(cfsetospeed(&ttyio,speed)<0) 341 | err(1,"cfsetospeed(): "); 342 | 343 | //INFO("baud rate set to %d\n",baudrate); 344 | 345 | if(tcsetattr(fd, TCSANOW, &ttyio)<0) 346 | err(1,"tcsetattr(): "); 347 | 348 | return(fd); 349 | } 350 | 351 | 352 | 353 | 354 | -------------------------------------------------------------------------------- /serial.h: -------------------------------------------------------------------------------- 1 | // 2 | // serial.h 3 | // lpcflash 4 | // 5 | // Created by ths on 2011-01-16. 6 | // Copyright 2011 ths @ dev.io. All rights reserved. 7 | 8 | /* 9 | # 10 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 11 | # 12 | # Redistribution and use in source and binary forms, with or without modification, are 13 | # permitted provided that the following conditions are met: 14 | # 15 | # 1. Redistributions of source code must retain the above copyright notice, this list of 16 | # conditions and the following disclaimer. 17 | # 18 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 19 | # of conditions and the following disclaimer in the documentation and/or other materials 20 | # provided with the distribution. 21 | # 22 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 24 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 25 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 28 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | # The views and conclusions contained in the software and documentation are those of the 33 | # authors and should not be interpreted as representing official policies, either expressed 34 | # or implied, of Thorsten Schroeder. 35 | # 36 | 37 | * */ 38 | 39 | #ifndef _SERIAL_H 40 | #define _SERIAL_H 41 | 42 | #define ERROR -1 43 | 44 | #define CLR(var,flag) (var) &= ~(flag) 45 | #define SET(var,flag) (var) |= (flag) 46 | 47 | /* serial i/o routines */ 48 | 49 | int serial_open(char *, int); 50 | int serial_readline(char *, int, int); 51 | int serial_send(int, int, char *); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /serial_cmd.c: -------------------------------------------------------------------------------- 1 | // 2 | // serial_cmd.c 3 | // lpcflash 4 | // 5 | // Created by ths on 2011-01-16. 6 | // Copyright 2011 ths @ dev.io. All rights reserved. 7 | // 8 | 9 | /* 10 | # 11 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 12 | # 13 | # Redistribution and use in source and binary forms, with or without modification, are 14 | # permitted provided that the following conditions are met: 15 | # 16 | # 1. Redistributions of source code must retain the above copyright notice, this list of 17 | # conditions and the following disclaimer. 18 | # 19 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 20 | # of conditions and the following disclaimer in the documentation and/or other materials 21 | # provided with the distribution. 22 | # 23 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 24 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 25 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 26 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 29 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | # The views and conclusions contained in the software and documentation are those of the 34 | # authors and should not be interpreted as representing official policies, either expressed 35 | # or implied, of Thorsten Schroeder. 36 | # 37 | 38 | * */ 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #include "serial.h" 53 | #include "serial_cmd.h" 54 | #include "chksum.h" 55 | #include "lpcisp.h" 56 | #include "base64.h" 57 | 58 | extern char **lpcisp_status_msg; 59 | extern const unsigned long sector_address[][2]; 60 | 61 | // W start addr, number of bytes 62 | int serial_cmd_write_to_ram(int serial_fd, unsigned int ramstart, unsigned int count, unsigned char *data) 63 | { 64 | unsigned char uuout[62]; 65 | unsigned char *puuout = uuout; 66 | unsigned char *pdata = data; 67 | unsigned int len=0; 68 | unsigned int checksum=0; 69 | 70 | char buf[128]; 71 | char cmd[128]; 72 | 73 | unsigned int num_lines = 0; // total number of lines 74 | unsigned int num_blocks = 0; // total number of uublocks a 20 lines 75 | unsigned int lastblock_len = 0; // total number of lines in last block 76 | unsigned int lastline_len = 0; // length of last line in last block 77 | 78 | int ret=-1; 79 | 80 | int nl=0; 81 | int nb=0; 82 | int lbl=0; 83 | 84 | num_lines = (unsigned int)(count / 45); 85 | lastline_len = (unsigned int)(count % 45); 86 | 87 | if (lastline_len) 88 | num_lines++; 89 | 90 | num_blocks = (unsigned int)(num_lines / 20); 91 | lastblock_len = (unsigned int)(num_lines % 20); 92 | 93 | memset(&buf,0,sizeof(buf)); 94 | memset(&uuout,0,sizeof(uuout)); 95 | 96 | // TODO check ramaddr word boundary -ths 97 | 98 | snprintf(cmd, sizeof(cmd), "W %d %d\r\n", ramstart, count); 99 | serial_send(serial_fd, strlen(cmd), cmd); 100 | 101 | len = serial_readline(buf, sizeof(buf), serial_fd); 102 | ret = serial_retcode(buf, len); 103 | len = 0; 104 | 105 | memset(&buf,0,sizeof(buf)); 106 | len = 0; 107 | 108 | if(ret != CMD_SUCCESS) 109 | return ret; 110 | 111 | // first block(s) 112 | for(nb=0; nb uulen) { // checksum 326 | 327 | if(uulen > 1) { 328 | int sent = 0; 329 | int got_chksum = strtol(uuline, NULL, 10); 330 | 331 | if(got_chksum == checksum) 332 | sent = serial_send(serial_fd, 4, "OK\r\n"); 333 | 334 | else { //XXX implement proper resend request handling! 335 | 336 | printf("\n[e] (%d > %d ?) sumlen=%d - count=%d - checksum mismatch: %x == %x\n", 337 | binlen, uulen, sumlen, count, got_chksum, checksum); 338 | 339 | sent = serial_send(serial_fd, 4, "RESEND\r\n"); 340 | } 341 | 342 | checksum = serial_checksum_init(); 343 | 344 | if(sumlen >= count) { 345 | break; 346 | } 347 | 348 | if(sizeof(buf) 2) { // definitvely no checksum 355 | 356 | binlen = raw_uu_decode((unsigned char *)uuline, rawdata); 357 | checksum = serial_checksum_update(checksum, rawdata, binlen); 358 | sumlen += binlen; 359 | printf("[*] read %08x of %08x Bytes from address %08x\r", sumlen, count, start); 360 | 361 | // if we have a valid file descriptor, write everything to file, otherwise hexdump 362 | // all data to stdout 363 | if(bin_fd > 0) 364 | write(bin_fd, rawdata, binlen); 365 | else { 366 | if(memout!=NULL) { 367 | memcpy(pmemout, rawdata, binlen); 368 | pmemout += binlen; 369 | } else 370 | print_hex_ascii_line((unsigned char *)rawdata, binlen, sumlen-binlen); 371 | } 372 | } 373 | } 374 | 375 | printf("\n"); 376 | 377 | // if we don't have a valid file descriptor, hexdump all data to stdout 378 | // (as long as memout is not NULL) and free resources 379 | if((memout!=NULL) && (bin_fd < 0)) { 380 | print_hex_ascii_line(memout, sumlen, start); 381 | free(memout); 382 | } 383 | return ret; 384 | } 385 | 386 | // flash addr, ram addr, number 387 | int serial_cmd_copy_ram_to_flash(int serial_fd, unsigned int flash_addr, unsigned int ram_addr, unsigned int count) 388 | { 389 | char buf[128]; 390 | int len=0; 391 | char cmd[128]; 392 | int ret=-1; 393 | 394 | snprintf(cmd, sizeof(cmd), "C %d %d %d\r\n", flash_addr, ram_addr, count); 395 | 396 | memset(&buf,0,sizeof(buf)); 397 | len=0; 398 | 399 | serial_send(serial_fd, strlen(cmd), cmd); 400 | len=serial_readline(buf, sizeof(buf), serial_fd); 401 | 402 | //printf("\n---\ncopy ram to flash ret: \n"); 403 | //print_hex_ascii_line((unsigned char *)buf, len, 0); 404 | 405 | ret = serial_retcode(buf, len); 406 | 407 | if(ret != CMD_SUCCESS) 408 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 409 | 410 | return ret; 411 | } 412 | 413 | 414 | // addr, mode 415 | int serial_cmd_go(int serial_fd, unsigned int addr) 416 | { 417 | int ret=-1; 418 | 419 | char buf[128]; 420 | char cmd[128]; 421 | int len=0; 422 | 423 | memset(&buf,0,sizeof(buf)); 424 | memset(&cmd,0,sizeof(cmd)); 425 | 426 | len=0; 427 | 428 | snprintf(cmd, sizeof(cmd), "G %u T\r\n", addr); 429 | 430 | serial_send(serial_fd, strlen(cmd), cmd); 431 | len=serial_readline(buf, sizeof(buf), serial_fd); 432 | 433 | ret = serial_retcode(buf, len); 434 | 435 | if(ret != CMD_SUCCESS) 436 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 437 | 438 | return ret; 439 | } 440 | 441 | // addr1, addr2, number of bytes 442 | int serial_cmd_compare(int serial_fd, unsigned int addr1, unsigned int addr2, unsigned int len) 443 | { 444 | int ret=-1; 445 | 446 | /* implement me :-) */ 447 | 448 | //if(ret != CMD_SUCCESS) 449 | // printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 450 | 451 | return ret; 452 | } 453 | 454 | 455 | int serial_retcode(char *buf, int buflen) 456 | { 457 | int result=0; 458 | 459 | if(buflen < 3) 460 | return -1; 461 | 462 | if(buflen >= 4) { 463 | if(isdigit(buf[buflen-4])) 464 | result=10*(buf[buflen-4]-'0'); 465 | } 466 | 467 | if(isdigit(buf[buflen-3])) { 468 | result+=buf[buflen-3]-'0'; 469 | } 470 | return result; 471 | } 472 | 473 | 474 | int serial_cmd_prepare_sector(int serial_fd, unsigned int from_sector, unsigned int to_sector) 475 | { 476 | char buf[128]; 477 | int len=0; 478 | char cmd[128]; 479 | int ret=-1; 480 | 481 | snprintf(cmd, sizeof(cmd), "P %d %d\r\n", from_sector, to_sector); 482 | 483 | //printf("D Prepare: %s\n", cmd); 484 | 485 | memset(&buf,0,sizeof(buf)); 486 | len=0; 487 | 488 | serial_send(serial_fd, strlen(cmd), cmd); 489 | 490 | len=serial_readline(buf, sizeof(buf), serial_fd); 491 | ret = serial_retcode(buf, len); 492 | 493 | if(ret != CMD_SUCCESS) 494 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 495 | 496 | return ret; 497 | } 498 | 499 | 500 | int serial_cmd_erase_sector(int serial_fd, unsigned int from_sector, unsigned int to_sector) 501 | { 502 | char buf[128]; 503 | int len=0; 504 | char cmd[128]; 505 | int ret=-1; 506 | 507 | snprintf(cmd, sizeof(cmd), "E %d %d\r\n", from_sector, to_sector); 508 | 509 | memset(&buf,0,sizeof(buf)); 510 | len=0; 511 | 512 | serial_send(serial_fd, strlen(cmd), cmd); 513 | 514 | len = serial_readline(buf, sizeof(buf), serial_fd); 515 | ret = serial_retcode(buf, len); 516 | 517 | if(ret != CMD_SUCCESS) 518 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 519 | 520 | return ret; 521 | } 522 | 523 | 524 | int serial_cmd_unlock(int serial_fd) 525 | { 526 | char buf[128]; 527 | int len=0; 528 | char cmd[] = "U 23130\r\n"; // this depends on the part or definition. XXX change it 529 | int ret=-1; 530 | 531 | memset(&buf,0,sizeof(buf)); 532 | len=0; 533 | 534 | serial_send(serial_fd, strlen(cmd), cmd); 535 | 536 | len = serial_readline(buf, sizeof(buf), serial_fd); 537 | ret = serial_retcode(buf, len); 538 | 539 | if(ret != CMD_SUCCESS) 540 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 541 | 542 | return ret; 543 | 544 | } 545 | 546 | 547 | int serial_cmd_read_device_serialno(int serial_fd, unsigned int *ser) 548 | { 549 | char buf[128]; 550 | int len = 0; 551 | char cmd[] = "N\r\n"; 552 | int ret = -1; 553 | int i = 0; 554 | 555 | memset(&buf,0,sizeof(buf)); 556 | len = 0; 557 | 558 | serial_send(serial_fd, strlen(cmd), cmd); 559 | 560 | while(ret != CMD_SUCCESS) { 561 | 562 | len = serial_readline(buf, sizeof(buf), serial_fd); 563 | 564 | ret = serial_retcode(buf, len); 565 | memset(&buf,0,sizeof(buf)); 566 | len = 0; 567 | } 568 | 569 | for(i=0;i<4;i++) { 570 | len = serial_readline(buf, sizeof(buf), serial_fd); 571 | ser[i]=(unsigned int)atoi(buf); 572 | } 573 | 574 | if(ret != CMD_SUCCESS) 575 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 576 | 577 | return ret; 578 | } 579 | 580 | 581 | int serial_cmd_read_bootcode_version(int serial_fd, unsigned int *ver) 582 | { 583 | char buf[128]; 584 | int len=0; 585 | char cmd[] = "K\r\n"; 586 | int ret=-1; 587 | unsigned int result=0; 588 | 589 | memset(&buf,0,sizeof(buf)); 590 | len=0; 591 | 592 | serial_send(serial_fd, strlen(cmd), cmd); 593 | 594 | while(ret != CMD_SUCCESS) { 595 | len = serial_readline(buf, sizeof(buf), serial_fd); 596 | ret = serial_retcode(buf, len); 597 | memset(&buf,0,sizeof(buf)); 598 | len = 0; 599 | } 600 | 601 | // read response 0 - partid 602 | len = serial_readline(buf, sizeof(buf), serial_fd); 603 | 604 | result = (unsigned int)atoi(buf); 605 | 606 | memcpy(ver, &result, 4); 607 | 608 | if(ret != CMD_SUCCESS) 609 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 610 | 611 | return ret; 612 | } 613 | 614 | 615 | int serial_cmd_read_partid(int serial_fd, unsigned int *id) 616 | { 617 | char buf[128]; 618 | int len=0; 619 | char cmd[] = "J\r\n"; 620 | int ret=-1; 621 | unsigned int result=0; 622 | 623 | memset(&buf,0,sizeof(buf)); 624 | len=0; 625 | 626 | serial_send(serial_fd, strlen(cmd), cmd); 627 | 628 | while(ret != CMD_SUCCESS) { 629 | len = serial_readline(buf, sizeof(buf), serial_fd); 630 | ret = serial_retcode(buf, len); 631 | memset(&buf,0,sizeof(buf)); 632 | len = 0; 633 | } 634 | 635 | // read response 0 - partid 636 | len = serial_readline(buf, sizeof(buf), serial_fd); 637 | 638 | result = (unsigned int)atoi(buf); 639 | 640 | memcpy(id, &result, 4); 641 | 642 | if(ret != CMD_SUCCESS) 643 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 644 | 645 | return ret; 646 | } 647 | 648 | void print_hex_ascii_line(const unsigned char *payload, int slen, int offset) 649 | { 650 | int i; 651 | int gap, len; 652 | const unsigned char *ch, *ch2; 653 | 654 | len = 16; 655 | ch2 = ch = payload; 656 | 657 | do { 658 | 659 | /* offset */ 660 | printf("%05x ", offset); 661 | 662 | /* hex */ 663 | if(slen < len) 664 | len=slen; 665 | 666 | for(i = 0; i < len; i++) { 667 | printf("%02x ", *ch); 668 | ch++; 669 | /* print extra space after 8th byte for visual aid */ 670 | if (i == 7) 671 | putc(' ', stdout); 672 | } 673 | /* print space to handle line less than 8 bytes */ 674 | if (len < 8) 675 | putc(' ', stdout); 676 | 677 | /* fill hex gap with spaces if not full line */ 678 | if (len < 16) { 679 | gap = 16 - len; 680 | for (i = 0; i < gap; i++) { 681 | printf(" "); 682 | } 683 | } 684 | printf(" "); 685 | 686 | /* ascii (if printable) */ 687 | for(i = 0; i < len; i++) { 688 | 689 | if (isprint(*ch2)) { 690 | printf("%c", *ch2); 691 | } else 692 | putc(' ', stdout); 693 | ch2++; 694 | } 695 | 696 | printf("\n\r"); 697 | slen -= 16; 698 | offset += len; 699 | } while( slen > 0 ); 700 | return; 701 | } 702 | 703 | //int serial_cmd_set_baudrate(int, unsigned long, unsigned int); // B baudrate, stopbit 704 | int serial_cmd_set_baudrate(int serial_fd, unsigned long baudrate, unsigned int stopbit) 705 | { 706 | char buf[128]; 707 | int len=0; 708 | char cmd[128]; 709 | int ret=-1; 710 | 711 | if(stopbit > 1) 712 | stopbit = 2; 713 | 714 | snprintf(cmd, sizeof(cmd), "B %ld %d\r\n", baudrate, stopbit); 715 | 716 | memset(&buf,0,sizeof(buf)); 717 | len = 0; 718 | 719 | serial_send(serial_fd, strlen(cmd), cmd); 720 | 721 | len = serial_readline(buf, sizeof(buf), serial_fd); 722 | ret = serial_retcode(buf, len); 723 | 724 | if(ret != CMD_SUCCESS) 725 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 726 | 727 | return ret; 728 | } 729 | 730 | //int serial_cmd_echo(int, unsigned int); // A setting 731 | int serial_cmd_echo(int serial_fd, unsigned int echo) 732 | { 733 | char buf[128]; 734 | int len = 0; 735 | char cmd[128]; 736 | int ret = -1; 737 | 738 | if(echo > 0) 739 | echo = 1; 740 | 741 | snprintf(cmd, sizeof(cmd), "A %d\r\n", echo); 742 | 743 | memset(&buf,0,sizeof(buf)); 744 | len = 0; 745 | 746 | serial_send(serial_fd, strlen(cmd), cmd); 747 | 748 | len = serial_readline(buf, sizeof(buf), serial_fd); 749 | ret = serial_retcode(buf, len); 750 | 751 | if(ret != CMD_SUCCESS) 752 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 753 | 754 | return ret; 755 | } 756 | 757 | /* 758 | * This command is used to blank check one or more sectors of on-chip flash memory. 759 | */ 760 | int serial_cmd_blankcheck_sector(int serial_fd, unsigned int start_sector, unsigned int end_sector) 761 | { 762 | char buf[128]; 763 | char cmd[128]; 764 | int len = 0; 765 | int ret = -1; 766 | 767 | /* End Sector Number: Should be greater than or equal to start sector number. */ 768 | if(end_sector > start_sector) 769 | return PARAM_ERROR; 770 | 771 | snprintf(cmd, sizeof(cmd), "I %d %d\r\n", start_sector, end_sector); 772 | 773 | memset(&buf,0,sizeof(buf)); 774 | len = 0; 775 | 776 | serial_send(serial_fd, strlen(cmd), cmd); 777 | 778 | len = serial_readline(buf, sizeof(buf), serial_fd); 779 | ret = serial_retcode(buf, len); 780 | 781 | if(ret != CMD_SUCCESS) 782 | printf("[e] failed cmd: %s => ret=%d\n", cmd, ret); 783 | 784 | return ret; 785 | } 786 | 787 | int serial_check_ok(char *buf, int buflen) 788 | { 789 | if(buflen < 4) 790 | return 0; 791 | return memcmp(&buf[buflen-4], "OK\r\n", 4) == 0; 792 | } 793 | 794 | int serial_synchronize(int serial_fd, unsigned int freq) 795 | { 796 | char buf[128]; 797 | int len = 0; 798 | 799 | memset(&buf,0,sizeof(buf)); 800 | serial_send(serial_fd, 1, "?"); 801 | len = serial_readline(buf, sizeof(buf), serial_fd); 802 | 803 | serial_send(serial_fd, len, buf); 804 | memset(&buf,0,sizeof(buf)); 805 | len = serial_readline(buf, sizeof(buf), serial_fd); 806 | 807 | if(!serial_check_ok(buf, len)) 808 | return -1; 809 | 810 | memset(&buf,0,sizeof(buf)); 811 | len = 0; 812 | 813 | snprintf(buf, sizeof(buf), "%d\r\n", freq); 814 | serial_send(serial_fd, (int)strlen(buf), buf); 815 | 816 | memset(&buf,0,sizeof(buf)); 817 | len = 0; 818 | 819 | len=serial_readline(buf, sizeof(buf), serial_fd); 820 | 821 | if(!serial_check_ok(buf, len)) 822 | return -1; 823 | 824 | return 0; 825 | } 826 | 827 | 828 | -------------------------------------------------------------------------------- /serial_cmd.h: -------------------------------------------------------------------------------- 1 | // 2 | // serial_cmd.h 3 | // lpcflash 4 | // 5 | // Created by ths on 2011-01-16. 6 | // Copyright 2011 ths @ dev.io. All rights reserved. 7 | // 8 | /* 9 | # 10 | # Copyright 2011 Thorsten Schroeder < ths (at) dev (dot) io >. All rights reserved. 11 | # 12 | # Redistribution and use in source and binary forms, with or without modification, are 13 | # permitted provided that the following conditions are met: 14 | # 15 | # 1. Redistributions of source code must retain the above copyright notice, this list of 16 | # conditions and the following disclaimer. 17 | # 18 | # 2. Redistributions in binary form must reproduce the above copyright notice, this list 19 | # of conditions and the following disclaimer in the documentation and/or other materials 20 | # provided with the distribution. 21 | # 22 | # THIS SOFTWARE IS PROVIDED BY THORSTEN SCHROEDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 24 | # FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THORSTEN SCHROEDER OR 25 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 28 | # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | # The views and conclusions contained in the software and documentation are those of the 33 | # authors and should not be interpreted as representing official policies, either expressed 34 | # or implied, of Thorsten Schroeder. 35 | # 36 | 37 | * */ 38 | 39 | 40 | #ifndef _SERIAL_CMD_H 41 | #define _SERIAL_CMD_H 42 | 43 | int serial_cmd_set_baudrate(int, unsigned long, unsigned int); // B baudrate, stopbit 44 | int serial_cmd_echo(int, unsigned int); // A setting 45 | int serial_cmd_blankcheck_sector(int, unsigned int, unsigned int); // I start sector, end sector 46 | 47 | int serial_cmd_write_to_ram(int, unsigned int, unsigned int, unsigned char *); // start addr, number of bytes, databuf 48 | int serial_cmd_read_memory(int, char *,unsigned int, unsigned int); // start addr, number of bytes 49 | int serial_cmd_copy_ram_to_flash(int, unsigned int, unsigned int, unsigned int); // flash addr, ram addr, number 50 | int serial_cmd_go(int, unsigned int); // addr 51 | int serial_cmd_compare(int, unsigned int, unsigned int, unsigned int); // addr1, addr2, number of bytes 52 | 53 | int serial_cmd_read_partid(int, unsigned int *); 54 | int serial_cmd_read_bootcode_version(int, unsigned int *); 55 | int serial_cmd_read_device_serialno(int, unsigned int *); 56 | int serial_cmd_prepare_sector(int, unsigned int, unsigned int); 57 | int serial_cmd_unlock(int); 58 | int serial_cmd_erase_sector(int, unsigned int, unsigned int); 59 | 60 | void serial_cmd_remap_bootvect(int, unsigned long); 61 | 62 | int serial_synchronize(int, unsigned int); 63 | int serial_retcode(char *, int); 64 | int serial_check_ok(char *, int); 65 | 66 | /* helper stuff ... move it */ 67 | void print_hex_ascii_line(const unsigned char *, int, int); 68 | 69 | #endif 70 | --------------------------------------------------------------------------------