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