b7c6b1614316a9c4fe2c834cc36e314f9de45bbf
[aversive.git] / config / prog_fuses.sh
1 #!/bin/sh
2
3 # bit $1 is set in $2 (8 bits)
4 bit_is_set() {
5         return $[ $[ $2 / $[ ( 1 << $1 ) ] ] % 2 ]
6                         # <<$ fix syntax coloration
7 }
8
9 # $1 = name
10 # $2 = value
11 disp_fuse() {
12         echo -n "$1:"
13         echo -n -e "\t"
14         let bit=7
15         while [ $bit -ge 0 ]; do
16                 NAME=`cut -d ' ' -f 2- ${MCU_DESC_FILE} | grep "^$bit $1" | cut -d ' ' -f 3`
17                 if [ -z "$NAME" ]; then
18                         echo -n "XXXX"
19                 else
20                         bit_is_set $bit $2
21                         bitval=$?
22                         echo -n "$NAME=$bitval"
23                 fi
24                 echo -n " "
25                 let bit=$bit-1
26         done
27         echo
28 }
29
30 # $1 filename
31 intel2hex() {
32         echo "0x`cat $1 | head -1 | cut -b10-11`" > $1.tmp
33         mv $1.tmp $1
34 }
35
36 # $1 filename
37 hex2intel() {
38         printf ":01000000%.2X" `cat $1` > $1.tmp
39         printf "%.2X\n" $[ 0xFF - `cat $1` ] >> $1.tmp
40         echo ":00000001FF" >> $1.tmp
41         mv $1.tmp $1
42 }
43
44
45 # 1/ read fuse state if possible
46 # 2/ prompt every bit
47 # 3/ program
48
49 MCU_DESC_FILE=$1
50
51 echo "----------------------------------------------------------"
52 echo "                   Programming fuses"
53 echo "----------------------------------------------------------"
54 echo
55 echo "Warning : It can bue dangerous to program your fuses: some"
56 echo "configurations will prevent you to program your uC. Be sure"
57 echo "that you have carrefully read the documentation, and that"
58 echo "you know what you're doing"
59 echo
60 echo "Warning : 0 means programmed and 1 means unprogrammed (see"
61 echo "AVR documentation for details"
62 echo
63 echo "BIT FAT WARNING ! PLEASE CHECK THE DOCUMENTATION BEFORE"
64 echo "PROGRAMMING BECAUSE SOME PARTS HAVE NOT BEEN TESTED"
65 echo
66
67 while true; do
68         echo -n "Are you sure ? [y/n] "
69         read ans
70
71         case $ans in
72                 y|Y)
73                         break
74                         ;;
75                 n|N)
76                         echo " abort..."
77                         exit 0
78                         ;;
79                 *)
80                         echo " Please type 'y' or 'n'"
81         esac
82 done
83
84 if [ ! -f ${MCU_DESC_FILE} ]; then
85         echo "ERROR"
86         echo "Can't find the file ${MCU_DESC_FILE}"
87         echo "If `basename ${MCU_DESC_FILE}` is a valid uC, you should add it in"
88         echo "AVERSIVE/config/fuses_defs directory"
89         exit 1
90 fi
91
92 if [ -z "${PROGRAMMER}" ]; then
93         echo "ERROR !"
94         echo " PROGRAMMER variable is not defined, check that the script"
95         echo " is launched from a 'make fuse' in project directory"
96         exit 1
97 fi
98
99 if [ "${PROGRAMMER}" = "avrdude" -a -z "${AVRDUDE}" ]; then
100         echo "ERROR !"
101         echo " AVRDUDE variable is not defined, check that the script"
102         echo " is launched from a 'make fuse' in project directory"
103         exit 1
104 fi
105
106 if [ "${AVARICE}" = "avarice" -a -z "${AVARICE}" ]; then
107         echo "ERROR !"
108         echo " AVARICE variable is not defined, check that the script"
109         echo " is launched from a 'make fuse' in project directory"
110         exit 1
111 fi
112
113 if [ "${PROGRAMMER}" = "avarice" ]; then
114         echo "ERROR !"
115         echo " Sorry, AVARICE fuse programming is not implemented now"
116         exit 1
117 fi
118
119 if [ `wc -c ${MCU_DESC_FILE} | cut -d ' ' -f 1` -eq 0 ]; then
120         echo "Aborting : this uC does not have any fuse to program."
121         exit 0
122 fi
123
124
125 FUSE_LIST=`cut -d ' ' -f 3 ${MCU_DESC_FILE} | sort -u`
126
127 echo "Reading current fuse state"
128
129 if [ ! -z "${AVRDUDE_DELAY}" ]; then
130         DELAY="-i ${AVRDUDE_DELAY}"
131 else
132         DELAY=""
133 fi
134
135 CANNOT_READ=0
136
137 for f in ${FUSE_LIST}
138 do
139         rm -f $f 2> /dev/null
140         echo 0x00 > ${f}_new
141         ${AVRDUDE} ${DELAY} -p ${MCU} -P `echo ${AVRDUDE_PORT} | sed 's,",,g'` \
142                 -c ${AVRDUDE_PROGRAMMER} -U ${f}:r:${f}:i
143         if [ ! -f $f ]; then
144                 CANNOT_READ=1
145         fi
146 done
147
148 echo
149 echo
150
151 if [ $CANNOT_READ -eq 1 ]; then
152         echo -n "Problem during reading fuse. Continue anyway with writing ? [y/N] "
153         read ans
154         case $ans in
155                 y|Y)
156                         echo " ok"
157                         echo
158                         echo
159
160                         ;;
161                 *|n|N)
162                         echo " abort..."
163                         exit 1
164         esac
165 else
166         for f in ${FUSE_LIST}; do
167                 intel2hex $f
168                 disp_fuse $f `cat $f`
169         done
170         echo
171         echo
172 fi
173
174 echo "Now please enter the new value for each fuse. The default one"
175 echo "is the value that has been read, or factory default if read failed"
176 echo
177 echo
178
179 NB_LINE=`wc -l ${MCU_DESC_FILE} | cut -d ' ' -f 1`
180 SEQ_END=$[ ${NB_LINE} - 1 ]
181
182 for i in `seq 0 ${SEQ_END}`
183 do
184         LINE=`grep "^${i} " ${MCU_DESC_FILE}`
185         BIT=`echo ${LINE} | cut -d ' ' -f 2`
186         FUSE=`echo ${LINE} | cut -d ' ' -f 3`
187         NAME=`echo ${LINE} | cut -d ' ' -f 4`
188         FACTORY=`echo ${LINE} | cut -d ' ' -f 5`
189         DEFAULT=${FACTORY}
190         CURRENT=x
191         HELP=`echo ${LINE} | cut -d ' ' -f 6-`
192         if [ -f ${FUSE} ]; then
193                 BIN_FUSE=`cat $FUSE`
194                 bit_is_set $BIT `printf "%d" $BIN_FUSE`
195                 CURRENT=$?
196                 DEFAULT=${CURRENT}
197         fi
198
199         echo -n "[$FUSE:${BIT}] ${NAME} <${HELP}> (factory=${DEFAULT}) "
200         echo -n "(current=${CURRENT}) [${DEFAULT}] ? "
201         read ans
202
203         if [ -z "$ans" ] ; then
204                 ans=${DEFAULT}
205         fi
206
207         case $ans in
208                 1)
209                         printf "0x%x\n" $[ $[ ( 1 << $BIT ) ] + `cat ${FUSE}_new` ] > ${FUSE}_new
210                         # <<$ fix syntax coloration
211                         echo "    get 1 (unprogrammed)"
212                         ;;
213                 0)
214                         echo "    get 0 (programmed)"
215                         ;;
216                 *)
217                         echo "Bad answer, aborting..."
218                         exit 1
219         esac
220
221 done
222
223 echo
224 echo "Summary of new values :"
225 echo
226
227 for f in ${FUSE_LIST}; do
228         if [ ! -f ${f}_new ]; then
229                 echo "ERROR: cannot find ${f}_new, aborting"
230                 exit 1
231         fi
232         disp_fuse $f `cat ${f}_new`
233 done
234
235 echo
236
237
238 while true
239 do
240         echo -n "Are you sure ? [y/n] "
241         read ans
242
243         case $ans in
244                 y|Y)
245                         for f in ${FUSE_LIST}; do
246                                 hex2intel ${f}_new
247                                 PORT=`echo ${AVRDUDE_PORT} | sed 's,",,g'`
248                                 ${AVRDUDE} -p ${MCU} -P ${PORT} \
249                                         -c ${AVRDUDE_PROGRAMMER} \
250                                         -U ${f}:w:${f}_new:i ${DELAY}
251                         done
252                         exit 0
253                         ;;
254                 n|N)
255                         echo " abort..."
256                         exit 0
257                         ;;
258                 *)
259                         echo " Please type 'y' or 'n'"
260         esac
261 done