#! /bin/sh # Equivalent script to what preprocessor.xls might do. # # Run e.g. like # sh preprocessor.sh ATmega128 4096 PORTD PD4 3686400 9600 > defines.h # # Written by Joerg Wunsch, 2005-07-29 PARTFILE=parts.txt usage() { echo "usage: preprocessor.sh device bootsize progport prog_no cpu_freq baud_rate" >& 2 exit 1 } if [ $# -ne 6 ] then usage fi if [ ! -f ${PARTFILE} ] then echo "part definition file ${PARTFILE} not found" >& 2 exit 1 fi device="$1" bootsize="$2" progport="$3" prog_no="$4" cpu_freq="$5" baud_rate="$6" # is there a device at all? if grep -i "^${device} " ${PARTFILE} >/dev/null then : else echo "device ${device} not found in ${PARTFILE}" >& 2 exit 1 fi devupper=`echo $device | tr '[a-z]' '[A-Z]'` # find an awk to use, out of nawk, gawk, or awk AWK=none for name in nawk gawk awk do set -- `type $name 2>/dev/null` if [ "x$2" = 'xis' ] then AWK=$name break fi done if [ $AWK = 'none' ] then echo "Sorry, no useable awk found" >& 2 exit 1 fi # OK, now get the individual fields. Unfortunately, the AVR910 device ID # is optional, and the shell cannot parse that natively. Use awk to # re-order the fields, and sort the avr910 column last (so we'll get an # empty variable in read if it is not present). set -- `grep -i "^${device} " ${PARTFILE} |\ ${AWK} -F ' ' \ '{print $1 " " $2 " " $3 " " $4 " " $5 " " $7 " " $8 " " $9 " " $10 " " $11 " " $12 " " $13 " " $14 " " $15 " " $16 " " $17 " " $18 " " $6; exit}'` dev=$1 include=$2 pagesz=$3 nrwwpag=$4 totpag=$5 sig1=$6 sig2=$7 sig3=$8 baudlo=$9 shift 9 uartc=$1 uarts=$2 txen=$3 rxen=$4 txc=$5 rxc=$6 udr=$7 spmcr=$8 avr910=$9 # Verify boot size pagebytes=`expr $pagesz \* 2` maxboot=`expr $nrwwpag \* $pagebytes` bootbytes=`expr 2 \* $bootsize` || exit 1 if [ \( $bootbytes -ne $maxboot \) -a \ \( $bootbytes -ne `expr $maxboot / 4` \) -a \ \( $bootbytes -ne `expr $maxboot / 2` \) -a \ \( $bootbytes -ne `expr $maxboot \* 3 / 4` \) ] then echo "Invalid boot size ${bootsize}, valid: `expr $maxboot / 8`, `expr $maxboot / 4`, `expr $maxboot \* 3 / 8`, `expr $maxboot / 2` words" >& 2 exit 1 fi if p=`expr $progport : 'PORT\(.\)'` then : # ok else echo "Invalid port name ${progport}, must be PORTx" >& 2 exit 1 fi progpin="PIN$p" brreg=`expr $cpu_freq / \( 16 \* $baud_rate \) - 1` || exit 1 memsize=`expr $totpag \* $pagebytes` append=`expr $memsize - $bootbytes` echo "/* definitions generated by preprocessor, copy into defines.h */ #ifndef PPINC #define _${devupper} // device select: _ATMEGAxxxx #define _B${bootsize} // boot size select: _Bxxxx (words), powers of two only #ifdef __ICCAVR__ #include \"${include}\" #endif #if __GNUC__ #include #endif /* define pin for enter-self-prog-mode */ #define PROGPORT ${progport} #define PROGPIN ${progpin} #define PROG_NO ${prog_no} /* baud rate register value calculation */ #define CPU_FREQ ${cpu_freq} #define BAUD_RATE ${baud_rate} #define BRREG_VALUE ${brreg} /* definitions for UART control */ #define BAUD_RATE_LOW_REG ${baudlo} #define UART_CONTROL_REG ${uartc} #define ENABLE_TRANSMITTER_BIT ${txen} #define ENABLE_RECEIVER_BIT ${rxen} #define UART_STATUS_REG ${uarts} #define TRANSMIT_COMPLETE_BIT ${txc} #define RECEIVE_COMPLETE_BIT ${rxc} #define UART_DATA_REG ${udr} /* definitions for SPM control */ #define SPMCR_REG ${spmcr} #define PAGESIZE ${pagebytes} #define APP_END ${append}" if [ $memsize -gt 65536 ] then echo "#define LARGE_MEMORY" else echo "//#define LARGE_MEMORY" fi echo " /* definitions for device recognition */ #define PARTCODE ${avr910} #define SIGNATURE_BYTE_1 ${sig1} #define SIGNATURE_BYTE_2 ${sig2} #define SIGNATURE_BYTE_3 ${sig3} /* indicate that preprocessor result is included */ #define PPINC #endif" echo "(IAR) Replace all code segment definitions in the linker file with the following line:" >& 2 ${AWK} 'BEGIN {printf "-Z(CODE)INTVEC,FAR_F,SWITCH,CODE=%X-%X\n", '$append', '$memsize' - 1; exit}' >& 2