add framedist
[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 ];
16       do
17       NAME=`cut -d ' ' -f 2- ${MCU_DESC_FILE} | grep "^$bit $1" | cut -d ' ' -f 3`
18       if [ -z "$NAME" ]; then
19           echo -n "XXXX"
20       else
21           bit_is_set $bit $2
22           bitval=$?
23           echo -n "$NAME=$bitval"
24       fi
25       echo -n " "
26       let bit=$bit-1
27     done
28     echo
29 }
30
31 # $1 filename
32 intel2hex() {
33     echo "0x`cat $1 | head -1 | cut -b10-11`" > $1.tmp
34     mv $1.tmp $1
35 }
36
37 # $1 filename
38 hex2intel() {
39     printf ":01000000%.2X" `cat $1` > $1.tmp
40     printf "%.2X\n" $[ 0xFF - `cat $1` ] >> $1.tmp
41     echo ":00000001FF" >> $1.tmp
42     mv $1.tmp $1
43 }
44
45
46 # 1/ read fuse state if possible
47 # 2/ prompt every bit
48 # 3/ program 
49
50 MCU_DESC_FILE=$1
51
52 echo "----------------------------------------------------------"
53 echo "                   Programming fuses"
54 echo "----------------------------------------------------------"
55 echo
56 echo "Warning : It can bue dangerous to program your fuses: some"
57 echo "configurations will prevent you to program your uC. Be sure"
58 echo "that you have carrefully read the documentation, and that"
59 echo "you know what you're doing"
60 echo 
61 echo "Warning : 0 means programmed and 1 means unprogrammed (see"
62 echo "AVR documentation for details"
63 echo
64 echo "BIT FAT WARNING ! PLEASE CHECK THE DOCUMENTATION BEFORE"
65 echo "PROGRAMMING BECAUSE SOME PARTS HAVE NOT BEEN TESTED"
66 echo
67
68 while true
69   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 0x00 > ${f}_new
143   ${AVRDUDE} ${DELAY} -p ${MCU} -P `echo ${AVRDUDE_PORT} | sed 's,",,g'` -c ${AVRDUDE_PROGRAMMER} -U ${f}:r:${f}:i
144   if [ ! -f $f ]; then
145       CANNOT_READ=1
146   fi
147 done
148
149 echo
150 echo
151
152 if [ $CANNOT_READ -eq 1 ]; then
153     echo -n "Problem during reading fuse. Continue anyway with writing ? [y/N] "
154     read ans
155     case $ans in
156         y|Y)
157             echo " ok"
158             echo
159             echo
160
161             ;;
162         *|n|N)
163             echo " abort..."
164             exit 1
165     esac
166 else
167     for f in ${FUSE_LIST}; do
168         intel2hex $f
169         disp_fuse $f `cat $f`
170     done
171     echo
172     echo
173 fi
174
175 echo "Now please enter the new value for each fuse. The default one"
176 echo "is the value that has been read, or factory default if read failed"
177 echo
178 echo
179
180 NB_LINE=`wc -l ${MCU_DESC_FILE} | cut -d ' ' -f 1`
181 SEQ_END=$[ ${NB_LINE} - 1 ]
182
183 for i in `seq 0 ${SEQ_END}`
184   do
185   LINE=`grep "^${i} " ${MCU_DESC_FILE}`
186   BIT=`echo ${LINE} | cut -d ' ' -f 2`
187   FUSE=`echo ${LINE} | cut -d ' ' -f 3`
188   NAME=`echo ${LINE} | cut -d ' ' -f 4`
189   FACTORY=`echo ${LINE} | cut -d ' ' -f 5`
190   DEFAULT=${FACTORY}
191   CURRENT=x
192   HELP=`echo ${LINE} | cut -d ' ' -f 6-`
193   if [ -f ${FUSE} ]; then
194       BIN_FUSE=`cat $FUSE`
195       bit_is_set $BIT `printf "%d" $BIN_FUSE`
196       CURRENT=$?
197       DEFAULT=${CURRENT}
198   fi
199
200   echo -n "[$FUSE:${BIT}] ${NAME} <${HELP}> (factory=${DEFAULT}) (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               ${AVRDUDE} -p ${MCU} -P `echo ${AVRDUDE_PORT} | sed 's,",,g'` -c ${AVRDUDE_PROGRAMMER} -U ${f}:w:${f}_new:i ${DELAY}
248           done
249           exit 0
250           ;;
251       n|N)
252           echo " abort..."
253           exit 0
254           ;;
255       *)
256           echo " Please type 'y' or 'n'"
257   esac
258 done