Parcourir la 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 il y a 12 ans
Parent
commit
0582897987

+ 6 - 2
optiboot/bootloaders/optiboot/Makefile

@@ -601,6 +601,10 @@ luminet_isp: isp
 
 FORCE:
 
+baudcheck: FORCE
+	@$(CC) $(CFLAGS) -E baudcheck.c -o baudcheck.tmp.sh
+	@sh baudcheck.tmp.sh
+
 isp: $(TARGET)
 	$(MAKE) -f Makefile.isp isp TARGET=$(TARGET)
 
@@ -608,12 +612,12 @@ isp-stk500: $(PROGRAM)_$(TARGET).hex
 	$(STK500-1)
 	$(STK500-2)
 
-%.elf: $(OBJ) $(dummy)
+%.elf: $(OBJ) baudcheck $(dummy)
 	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
 	$(SIZE) $@
 
 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
 	$(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
 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  \
         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
 #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
 /* Switch in soft UART for hard baud rates */
 /*