Browse Source

Implement a check of the specified baud rate,
so that the user can see whether it's going to be reasonably
accurate or not. There are two parts to this:
1) Use of #error and #warning in optiboot.c, for when the error is large.
2) Since you can't get the compiler to spit out actual numbers, create a
new target "baudcheck" that does. This is somewhat complicated by the
possibile non-availability of the usual development tools in the user
environment, so baudcheck.c is run through the avr-gcc preprocessor, and
produces a shell script.

http://code.google.com/p/optiboot/issues/detail?id=79

westfw 12 years ago
parent
commit
0582897987

+ 6 - 2
optiboot/bootloaders/optiboot/Makefile

@@ -601,6 +601,10 @@ luminet_isp: isp
 
 
 FORCE:
 FORCE:
 
 
+baudcheck: FORCE
+	@$(CC) $(CFLAGS) -E baudcheck.c -o baudcheck.tmp.sh
+	@sh baudcheck.tmp.sh
+
 isp: $(TARGET)
 isp: $(TARGET)
 	$(MAKE) -f Makefile.isp isp TARGET=$(TARGET)
 	$(MAKE) -f Makefile.isp isp TARGET=$(TARGET)
 
 
@@ -608,12 +612,12 @@ isp-stk500: $(PROGRAM)_$(TARGET).hex
 	$(STK500-1)
 	$(STK500-1)
 	$(STK500-2)
 	$(STK500-2)
 
 
-%.elf: $(OBJ) $(dummy)
+%.elf: $(OBJ) baudcheck $(dummy)
 	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
 	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
 	$(SIZE) $@
 	$(SIZE) $@
 
 
 clean:
 clean:
-	rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
+	rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex *.tmp.sh
 
 
 %.lst: %.elf
 %.lst: %.elf
 	$(OBJDUMP) -h -S $< > $@
 	$(OBJDUMP) -h -S $< > $@

+ 15 - 3
optiboot/bootloaders/optiboot/README.TXT

@@ -62,9 +62,21 @@ program the bootloader into a chip. "atmega328_isp" for the atmega328,
 for example.  These will set the fuses and lock bits as appropriate as
 for example.  These will set the fuses and lock bits as appropriate as
 well as uploading the bootloader code.
 well as uploading the bootloader code.
 
 
-The makefiles default to using a USB programmer, but you can use
-a serial programmer like ArduinoISP by changing the appropriate
-variables when you invoke make:
+ISP Targets in Version 5.0 and later:
+
+The isp targets are now built using a separate "Makefile.isp" makefile,
+which should make modification easier and more obvious.  This also fixes
+the atmega8_isp target problem mentioned below.  The default
+configuration assumes an ArduinoISP setup, but you will probably need to
+update at least the serial port, since those are different for each
+Arduino board and/or system/
+
+
+ISP Targets in Version 4.6 and earlier:
+
+The older makefiles default to using a USB programmer, but you can use a
+serial programmer like ArduinoISP by changing the appropriate variables
+when you invoke make:
 
 
    make ISPTOOL=stk500v1 ISPPORT=/dev/tty.usbserial-A20e1eAN  \
    make ISPTOOL=stk500v1 ISPPORT=/dev/tty.usbserial-A20e1eAN  \
         ISPSPEED=-b19200 atmega328_isp
         ISPSPEED=-b19200 atmega328_isp

+ 50 - 0
optiboot/bootloaders/optiboot/baudcheck.c

@@ -0,0 +1,50 @@
+/*
+ * baudcheck.c
+ * Mar, 2013 by Bill Westfield (WestfW@yahoo.com)
+ * Exercises in executing arithmetic code on a system that we can't count
+ * on having the usual languages or tools installed.
+ *
+ * This little "C program" is run through the C preprocessor using the same
+ * arguments as our "real" target (which should assure that it gets the
+ * same values for clock speed and desired baud rate), and produces as
+ * output a shell script that can be run through bash, and THAT in turn
+ * writes the desired output...
+ *
+ * Note that the C-style comments are stripped by the C preprocessor.
+ */
+
+/*
+ * First strip any trailing "L" from the defined constants.  To do this
+ * we need to make the constants into shell variables first.
+ */
+bpsx=BAUD_RATE
+bps=${bpsx/L/}
+fcpux=F_CPU
+fcpu=${fcpux/L/}
+
+// echo f_cpu = $fcpu, baud = $bps
+/*
+ * Compute the divisor
+ */
+BAUD_SETTING=$(( ( ($fcpu + $bps * 4) / (($bps * 8))) - 1 ))
+// echo baud setting = $BAUD_SETTING
+
+/*
+ * Based on the computer divisor, calculate the actual bitrate,
+ * And the error.  Since we're all integers, we have to calculate
+ * the tenths part of the error separately.
+ */
+BAUD_ACTUAL=$(( ($fcpu/(8 * (($BAUD_SETTING)+1))) ))
+BAUD_ERROR=$(( (( 100*($bps - $BAUD_ACTUAL) ) / $bps) ))
+ERR_TS=$(( ((( 1000*($bps - $BAUD_ACTUAL) ) / $bps) - $BAUD_ERROR * 10) ))
+ERR_TENTHS=$(( ERR_TS > 0 ? ERR_TS: -ERR_TS ))
+
+/*
+ * Print a nice message containing the info we've calculated
+ */
+echo BAUD RATE CHECK: Desired: $bps,  Real: $BAUD_ACTUAL, UBRRL = $BAUD_SETTING, Error=$BAUD_ERROR.$ERR_TENTHS\%
+
+
+
+
+

+ 14 - 0
optiboot/bootloaders/optiboot/optiboot.c

@@ -242,6 +242,20 @@ asm("  .section .version\n"
 #define UART 0
 #define UART 0
 #endif
 #endif
 
 
+#define BAUD_SETTING (( (F_CPU + BAUD_RATE * 4L) / ((BAUD_RATE * 8L))) - 1 )
+#define BAUD_ACTUAL (F_CPU/(8 * ((BAUD_SETTING)+1)))
+#define BAUD_ERROR (( 100*(BAUD_RATE - BAUD_ACTUAL) ) / BAUD_RATE)
+
+#if BAUD_ERROR >= 5
+#error BAUD_RATE error greater than 5%
+#elif BAUD_ERROR <= -5
+#error BAUD_RATE error greater than -5%
+#elif BAUD_ERROR >= 2
+#warning BAUD_RATE error greater than 2%
+#elif BAUD_ERROR <= -2
+#warning BAUD_RATE error greater than -2%
+#endif
+
 #if 0
 #if 0
 /* Switch in soft UART for hard baud rates */
 /* Switch in soft UART for hard baud rates */
 /*
 /*