2008-03-14 Martin Thomas <mthomas@rhrk.uni-kl.de>
authorKevin Rosenberg <kevin@rosenberg.net>
Fri, 14 Mar 2008 22:13:33 +0000 (16:13 -0600)
committerKevin Rosenberg <kevin@rosenberg.net>
Fri, 14 Mar 2008 22:13:33 +0000 (16:13 -0600)
        * added "volatile" to structure object and array declarations for objects
        sed in main-thread and ISRs. I'm not sure about the current state of
        implicitly "guaranteed" accesses in (avr-)gcc but it should be a "better
        safe than sorry" extension.
        * enveloped access to timer-values in timer.c to make them "atomic" since
        they are unsigned long
        * "atomic" access to singned int and unsigned int members of ADCS
        * it maybe better to have one place to globally enable interrupts ("sei").
        Done in "initialize" now and not several times in the driver

12 files changed:
BaseTinyFirmware/GCC/ADC.c
BaseTinyFirmware/GCC/ADC.h
BaseTinyFirmware/GCC/ChangeLog
BaseTinyFirmware/GCC/USI.c
BaseTinyFirmware/GCC/avr463.aps
BaseTinyFirmware/GCC/avr463.aws
BaseTinyFirmware/GCC/battery.c
BaseTinyFirmware/GCC/chargefunc.c
BaseTinyFirmware/GCC/main.c
BaseTinyFirmware/GCC/statefunc.c
BaseTinyFirmware/GCC/time.c
BaseTinyFirmware/GCC/time.h

index 004ba8dc6cbcddd222e5eb368805e5ff740a9580..50814ca6413782eef7d73523cbbf2e590c972910 100644 (file)
@@ -45,7 +45,7 @@
 //******************************************************************************\r
 // ADC status struct.\r
 //! \brief Holds sampled data and ADC-status\r
-ADC_Status_t ADCS;\r
+volatile ADC_Status_t ADCS;\r
 \r
 \r
 /*! \brief Indicates maximum battery voltage.\r
@@ -170,10 +170,10 @@ ISR(ADC_vect)
 \r
                        // Scale sample according to jumper setting, handle negative numbers.\r
                        if (ADC > 511) {\r
-                          ADCS.IBAT = -(signed int)ScaleI(eeprom_read_byte(&VBAT_RANGE),\r
-                                            (1024 - (ADC-ADCS.ADC5_G20_OS)));\r
+                               ADCS.IBAT = -(signed int)ScaleI(eeprom_read_byte(&VBAT_RANGE),\r
+                                                               (1024 - (ADC-ADCS.ADC5_G20_OS)));\r
                        } else if (ADC > 0) {\r
-                          ADCS.IBAT = ScaleI(eeprom_read_byte(&VBAT_RANGE), (ADC-ADCS.ADC5_G20_OS));\r
+                               ADCS.IBAT = ScaleI(eeprom_read_byte(&VBAT_RANGE), (ADC-ADCS.ADC5_G20_OS));\r
                        } else {\r
                                ADCS.IBAT = 0;\r
                        }\r
@@ -206,15 +206,15 @@ ISR(ADC_vect)
        ADMUX = (1<<REFS0) + ADCS.MUX;\r
 \r
        if (Signed)     {\r
-         ADCSRB |= (1<<BIN);\r
+               ADCSRB |= (1<<BIN);\r
        } else {\r
-         ADCSRB &= ~(1<<BIN);\r
+               ADCSRB &= ~(1<<BIN);\r
        }\r
 \r
        // Re-enable the ADC unless a halt has been flagged and a conversion\r
        // cycle has completed.\r
        if (!((ADCS.Halt) && (ADCS.Flag))) {\r
-         ADCSRA |= (1<<ADEN)|(1<<ADSC);\r
+               ADCSRA |= (1<<ADEN)|(1<<ADSC);\r
        }\r
 }\r
 \r
@@ -333,7 +333,7 @@ void ADC_Wait(void)
        do {\r
        } while (ADCS.Flag == FALSE);\r
 \r
-       // Repeat, so we are sure the data beong to the same cycle.\r
+       // Repeat, so we are sure the data belongs to the same cycle.\r
        ADCS.Flag = FALSE;\r
        do {\r
        } while (ADCS.Flag == FALSE);\r
@@ -368,7 +368,9 @@ void ADC_Wait(void)
 void ADC_Init(void)\r
 {\r
        unsigned char i;\r
+       unsigned char sreg_saved;\r
 \r
+       sreg_saved = SREG;\r
        cli();\r
 \r
        ADCS.Halt = FALSE; // Enable consecutive runs of ADC.\r
@@ -423,4 +425,6 @@ void ADC_Init(void)
 \r
        // Get a complete cycle of data before returning.\r
        ADC_Wait();\r
+\r
+       SREG = sreg_saved;\r
 }\r
index 461dbda177711301ec58fb3600d2245ac8557f07..a309205a96baee25dd69db09802d3507e52a6688 100644 (file)
@@ -54,7 +54,7 @@
 // Global variables\r
 //******************************************************************************\r
 extern unsigned char EEMEM VBAT_RANGE;\r
-extern ADC_Status_t ADCS;\r
+extern volatile ADC_Status_t ADCS;\r
 \r
 \r
 //******************************************************************************\r
index 93703b77dbee590023f815710d4a202653a92ee3..f36d807c26d57316c0b594525fd271fc6370235c 100644 (file)
@@ -1,3 +1,20 @@
+2008-03-14 Martin Thomas <mthomas@rhrk.uni-kl.de>\r
+       * added "volatile" to structure object and array declarations for objects\r
+       sed in main-thread and ISRs. I'm not sure about the current state of\r
+       implicitly "guaranteed" accesses in (avr-)gcc but it should be a "better\r
+       safe than sorry" extension.\r
+       * enveloped access to timer-values in timer.c to make them "atomic" since\r
+       they are unsigned long\r
+       * "atomic" access to singned int and unsigned int members of ADCS\r
+       * it maybe better to have one place to globally enable interrupts ("sei").\r
+       Done in "initialize" now and not several times in the driver\r
+       init-functions.\r
+       * changed some space to tab as in the original code\r
+       * added header files to the AVR-Studio project workspace\r
+       * added -lm to the linker-options in the AVR Studio gcc-plugin, not\r
+       important for the basic application but might be good if someone uses the\r
+       code as a base for own developments\r
+\r
 2008-03-12 Kevin Rosenberg <kevin@rosenberg.net>\r
        * Initial GCC port performed and compiles without error\r
        * Warning: Not yet tested on BC100 hardware!\r
index efc004fc24c22149e12d0d47ad5e3a39ad120d86..6813d1565f317fca9c2db1965b9bcd624e72bbdd 100644 (file)
@@ -44,7 +44,7 @@
 // Variables\r
 //******************************************************************************\r
 //! SPI status struct\r
-SPI_Status_t SPI;\r
+volatile SPI_Status_t SPI;\r
 \r
 \r
 //******************************************************************************\r
@@ -162,7 +162,7 @@ ISR(USI_OVF_vect)
                                \r
                                \r
                                case ADR_BATTCTRL:\r
-                                  SPI_Put(eeprom_read_byte((unsigned char*)&BattControl + (SPI.Count)));\r
+                                       SPI_Put(eeprom_read_byte((unsigned char*)&BattControl + (SPI.Count)));\r
                                break;\r
                                \r
                                case ADR_TIMERS:\r
@@ -221,6 +221,9 @@ ISR(USI_OVF_vect)
  */\r
 void SPI_Init(unsigned char spi_mode)\r
 {\r
+       unsigned char sreg_saved;\r
+\r
+       sreg_saved = SREG;\r
        cli();\r
        \r
        // Configure outputs and inputs, enable pull-ups for DATAIN and CLOCK pins.\r
@@ -241,7 +244,7 @@ void SPI_Init(unsigned char spi_mode)
        SPI.XferComplete = FALSE;     // We haven't even started a transfer yet.\r
        SPI.WriteCollision = FALSE;   // ..And therefore a collision hasn't happened.\r
 \r
-       sei();\r
+       SREG = sreg_saved;\r
 }\r
 \r
 \r
index 0e89be1a4e33373962929f878347b3dedc5dfeb2..360a5e2f6880ff8d4b849e2b05f8b072bb64540e 100644 (file)
@@ -1 +1 @@
-<AVRStudio><MANAGEMENT><ProjectName>avr463</ProjectName><Created>13-Mar-2008 01:54:24</Created><LastEdit>13-Mar-2008 03:07:11</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>13-Mar-2008 01:54:24</Created><Version>4</Version><Build>4, 14, 0, 580</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>avr463\avr463.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>C:\Users\kevin\pub\src\bc100\GCC\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATtiny861.xml</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>ADC.c</SOURCEFILE><SOURCEFILE>battery.c</SOURCEFILE><SOURCEFILE>chargefunc.c</SOURCEFILE><SOURCEFILE>main.c</SOURCEFILE><SOURCEFILE>menu.c</SOURCEFILE><SOURCEFILE>NIMHcharge.c</SOURCEFILE><SOURCEFILE>OWI.c</SOURCEFILE><SOURCEFILE>PWM.c</SOURCEFILE><SOURCEFILE>statefunc.c</SOURCEFILE><SOURCEFILE>time.c</SOURCEFILE><SOURCEFILE>USI.c</SOURCEFILE><OTHERFILE>avr463\avr463.lss</OTHERFILE><OTHERFILE>avr463\avr463.map</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>avr463</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>attiny861</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>avr463.elf</OUTPUTFILENAME><OUTPUTDIR>avr463\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS><OPTION><FILE>ADC.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>NIMHcharge.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>OWI.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>PWM.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>USI.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>battery.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>chargefunc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>main.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>menu.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>statefunc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>time.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS/><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -DNIMH </OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>avr463</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\WinAVR\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\WinAVR\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><ProjectFiles><Files><Name>C:\Users\kevin\pub\src\bc100\GCC\ADC.c</Name><Name>C:\Users\kevin\pub\src\bc100\GCC\battery.c</Name><Name>C:\Users\kevin\pub\src\bc100\GCC\chargefunc.c</Name><Name>C:\Users\kevin\pub\src\bc100\GCC\main.c</Name><Name>C:\Users\kevin\pub\src\bc100\GCC\menu.c</Name><Name>C:\Users\kevin\pub\src\bc100\GCC\NIMHcharge.c</Name><Name>C:\Users\kevin\pub\src\bc100\GCC\OWI.c</Name><Name>C:\Users\kevin\pub\src\bc100\GCC\PWM.c</Name><Name>C:\Users\kevin\pub\src\bc100\GCC\statefunc.c</Name><Name>C:\Users\kevin\pub\src\bc100\GCC\time.c</Name><Name>C:\Users\kevin\pub\src\bc100\GCC\USI.c</Name></Files></ProjectFiles><IOView><usergroups/><sort sorted="0" column="0" ordername="0" orderaddress="0" ordergroup="0"/></IOView><Files><File00000><FileId>00000</FileId><FileName>battery.c</FileName><Status>1</Status></File00000><File00001><FileId>00001</FileId><FileName>chargefunc.c</FileName><Status>1</Status></File00001><File00002><FileId>00002</FileId><FileName>nimhcharge.c</FileName><Status>1</Status></File00002><File00003><FileId>00003</FileId><FileName>statefunc.c</FileName><Status>1</Status></File00003></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>\r
+<AVRStudio><MANAGEMENT><ProjectName>avr463</ProjectName><Created>13-Mar-2008 01:54:24</Created><LastEdit>14-Mar-2008 21:11:26</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>13-Mar-2008 01:54:24</Created><Version>4</Version><Build>4, 14, 0, 580</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>avr463\avr463.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>D:\users\mthomas\develop\avr\bc100\bcc100_mth_20080314\BaseTinyFirmware\GCC\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATtiny861</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>ADC.c</SOURCEFILE><SOURCEFILE>battery.c</SOURCEFILE><SOURCEFILE>chargefunc.c</SOURCEFILE><SOURCEFILE>main.c</SOURCEFILE><SOURCEFILE>menu.c</SOURCEFILE><SOURCEFILE>NIMHcharge.c</SOURCEFILE><SOURCEFILE>OWI.c</SOURCEFILE><SOURCEFILE>PWM.c</SOURCEFILE><SOURCEFILE>statefunc.c</SOURCEFILE><SOURCEFILE>time.c</SOURCEFILE><SOURCEFILE>USI.c</SOURCEFILE><HEADERFILE>ADC.h</HEADERFILE><HEADERFILE>battery.h</HEADERFILE><HEADERFILE>charge.h</HEADERFILE><HEADERFILE>chargefunc.h</HEADERFILE><HEADERFILE>delay_x_gcc.h</HEADERFILE><HEADERFILE>enums.h</HEADERFILE><HEADERFILE>main.h</HEADERFILE><HEADERFILE>menu.h</HEADERFILE><HEADERFILE>NIMHspecs.h</HEADERFILE><HEADERFILE>OWI.h</HEADERFILE><HEADERFILE>PWM.h</HEADERFILE><HEADERFILE>statefunc.h</HEADERFILE><HEADERFILE>structs.h</HEADERFILE><HEADERFILE>time.h</HEADERFILE><HEADERFILE>USI.h</HEADERFILE><OTHERFILE>avr463\avr463.lss</OTHERFILE><OTHERFILE>avr463\avr463.map</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>avr463</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>attiny861</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>avr463.elf</OUTPUTFILENAME><OUTPUTDIR>avr463\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS><OPTION><FILE>ADC.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>NIMHcharge.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>OWI.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>PWM.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>USI.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>battery.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>chargefunc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>main.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>menu.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>statefunc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>time.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS><LIB>libm.a</LIB></LIBS><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -DNIMH</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>avr463</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\WinAVR\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\WinAVR\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><IOView><usergroups/><sort sorted="0" column="0" ordername="1" orderaddress="1" ordergroup="1"/></IOView><Files><File00000><FileId>00000</FileId><FileName>structs.h</FileName><Status>1</Status></File00000></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>\r
index 2773bffa93d707100d610c8722f6a7e0e06befa5..e73c6bfc641cf0211aefdd14faa2c21ed66c9a7d 100644 (file)
@@ -1 +1 @@
-<AVRWorkspace><IOSettings><CurrentRegisters/></IOSettings><part name="ATTINY861"/><Files/></AVRWorkspace>\r
+<AVRWorkspace><IOSettings><CurrentRegisters/></IOSettings><part name="ATTINY861"/><Files><File00000 Name="D:\users\mthomas\develop\avr\bc100\bcc100_mth_20080314\BaseTinyFirmware\GCC\structs.h" Position="343 217 1015 700" LineCol="93 53"/></Files></AVRWorkspace>\r
index e6cacd863849592bcb9794a7ab9f5b0def018a8f..b3617118cd562fd4f29df63ad09e3ec1bcfb9861 100644 (file)
@@ -30,6 +30,7 @@
 \r
 #include <avr/io.h>\r
 #include <avr/eeprom.h>\r
+#include <avr/interrupt.h>\r
 \r
 #include "structs.h"\r
 #include "enums.h"\r
@@ -172,6 +173,9 @@ unsigned char BatteryStatusRefresh(void)
 {\r
        // Assume the worst..\r
        unsigned char success = FALSE;\r
+       unsigned char sreg_saved;\r
+       unsigned int adcs_VBAT_tmp;\r
+       signed int adcs_avgIBAT_tmp;\r
        \r
        BattData.Present = FALSE;\r
        BattData.Charged = FALSE;\r
@@ -186,13 +190,19 @@ unsigned char BatteryStatusRefresh(void)
        NTCLookUp();\r
        BattData.HasRID = RIDLookUp();\r
 \r
+       sreg_saved = SREG;\r
+       cli();\r
+       adcs_VBAT_tmp = ADCS.VBAT;\r
+       adcs_avgIBAT_tmp = ADCS.avgIBAT;\r
+       SREG = sreg_saved;\r
+\r
        // Is the battery voltage above minimum safe cell voltage?\r
-       if (ADCS.VBAT >= BAT_VOLTAGE_MIN) {\r
+       if (adcs_VBAT_tmp >= BAT_VOLTAGE_MIN) {\r
                BattData.Low = FALSE;\r
        }\r
 \r
        // Is the battery charged?\r
-       if (ADCS.VBAT >= BAT_VOLTAGE_LOW) {\r
+       if (adcs_VBAT_tmp >= BAT_VOLTAGE_LOW) {\r
                BattData.Charged = TRUE;\r
        }\r
 \r
@@ -205,7 +215,7 @@ unsigned char BatteryStatusRefresh(void)
        * not 100% proof.\r
        */\r
        if (((OCR1B == 0) && (!BattData.Low)) ||\r
-           ((OCR1B != 0) && (ADCS.avgIBAT > 0))) {\r
+           ((OCR1B != 0) && (adcs_avgIBAT_tmp > 0))) {\r
                BattData.Present = TRUE;\r
                success = TRUE;\r
        } else {\r
@@ -299,7 +309,7 @@ unsigned char BatteryDataRefresh(void)
          // Erase local EEPROM page if there were any errors during transfer.\r
                if (!success) {\r
                        for (i=0; i<32; i++) {\r
-                          eeprom_write_byte(&BattEEPROM[page][i], 0);\r
+                               eeprom_write_byte(&BattEEPROM[page][i], 0);\r
                        }\r
                }\r
        }\r
@@ -358,12 +368,18 @@ void DisableBatteries(void)
 unsigned char RIDLookUp (void)\r
 {\r
        unsigned char i, found = FALSE;\r
+       unsigned int adcs_rawRID_tmp;\r
+       unsigned char sreg_saved;\r
                \r
        // Lookup in the RID-table. If measured RID is within the limits\r
        // of an entry, those data are used, and TRUE is returned.\r
        for (i = 0 ; i < RID_TABLE_SIZE; i++) {\r
-               if (ADCS.rawRID >= RID[i].Low) {\r
-                       if (ADCS.rawRID <= RID[i].High) {\r
+               sreg_saved = SREG;\r
+               cli();\r
+               adcs_rawRID_tmp = ADCS.rawRID;\r
+               SREG = sreg_saved;\r
+               if (adcs_rawRID_tmp >= RID[i].Low) {\r
+                       if (adcs_rawRID_tmp <= RID[i].High) {\r
                                BattData.Capacity = RID[i].Capacity;\r
                                BattData.MaxCurrent = RID[i].Icharge;\r
                                BattData.MaxTime = RID[i].tCutOff;\r
@@ -401,15 +417,21 @@ void NTCLookUp (void)
 {\r
        unsigned char i;\r
        unsigned char found = FALSE;\r
+       unsigned char adcs_rawNTC_tmp;\r
+       unsigned char sreg_saved;\r
        \r
        // Lookup in the NTC-table. Use the first entry which is equal or below\r
        // sampled NTC. Calculate temperature by using the index number, and the\r
        // difference between the measured NTC value and the one in the entry.\r
        for (i=0 ; (i < NTC_TABLE_SIZE) && (!found); i++)       {\r
-               if (ADCS.rawNTC >= NTC[i].ADCV) {\r
+               sreg_saved = SREG;\r
+               cli();\r
+               adcs_rawNTC_tmp = ADCS.rawNTC;\r
+               SREG = sreg_saved;\r
+               if (adcs_rawNTC_tmp >= NTC[i].ADCV) {\r
                        BattData.Temperature = (i<<2) ;\r
                        BattData.ADCSteps = NTC[i].ADCsteps;  \r
-                       BattData.Temperature -= ((ADCS.rawNTC - NTC[i].ADCV)<<1) / BattData.ADCSteps;\r
+                       BattData.Temperature -= ((adcs_rawNTC_tmp - NTC[i].ADCV)<<1) / BattData.ADCSteps;\r
                        \r
                        found = TRUE;  // Could be done with a break, but that violates MISRA.\r
                }\r
index 2194e569b7c462fad247a98abc72922e53cc8e1a..5f441b7f85dbc45970108c8fea68747f367c07ff 100644 (file)
@@ -28,6 +28,7 @@
  ******************************************************************************/\r
 \r
 #include <avr/io.h>\r
+#include <avr/interrupt.h>\r
 \r
 #include "enums.h"\r
 #include "structs.h"\r
@@ -81,9 +82,11 @@ unsigned char ConstantCurrent(void)
 {\r
        unsigned char error = FALSE,\r
                      wasStopped = FALSE;\r
+       unsigned char sreg_saved;\r
+       signed int adcs_avgIBAT_tmp;\r
        \r
        do      {\r
-      // Wait for ADC conversions to complete.\r
+               // Wait for ADC conversions to complete.\r
                ADC_Wait();\r
 \r
                // If Master has flagged for a charge inhibit, pause charging.\r
@@ -100,11 +103,16 @@ unsigned char ConstantCurrent(void)
                                // Timer variables are not reset by this.\r
                                Time_Start();\r
                        }\r
-         \r
+\r
+                       sreg_saved = SREG;\r
+                       cli();\r
+                       adcs_avgIBAT_tmp = ADCS.avgIBAT;\r
+                       SREG = sreg_saved;\r
+\r
                        // Adjust the charge current to within ChargeParameters.Current\r
                        // +/- BAT_CURRENT_HYST.\r
-                       if ((ADCS.avgIBAT < 0) ||\r
-                           (ADCS.avgIBAT < (ChargeParameters.Current - BAT_CURRENT_HYST))) {\r
+                       if ((adcs_avgIBAT_tmp < 0) ||\r
+                           (adcs_avgIBAT_tmp < (ChargeParameters.Current - BAT_CURRENT_HYST))) {\r
                                         \r
                                if(!PWM_IncrementDutyCycle()) {\r
 #ifdef ABORT_IF_PWM_MAX\r
@@ -115,8 +123,8 @@ unsigned char ConstantCurrent(void)
                                        error = TRUE;\r
 #endif\r
                                }\r
-                       } else if ((ADCS.avgIBAT >= 0) &&\r
-                                (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) {\r
+                       } else if ((adcs_avgIBAT_tmp >= 0) &&\r
+                                (adcs_avgIBAT_tmp > (ChargeParameters.Current + BAT_CURRENT_HYST))) {\r
                                         \r
                                if(!PWM_DecrementDutyCycle()) {\r
 #ifdef ABORT_IF_PWM_MIN\r
@@ -155,6 +163,8 @@ unsigned char ConstantVoltage(void)
 {\r
        unsigned char error = FALSE,\r
                      wasStopped = FALSE;\r
+       unsigned char sreg_saved;\r
+       unsigned int adcs_VBAT_tmp;\r
        \r
        do{\r
                \r
@@ -178,9 +188,14 @@ unsigned char ConstantVoltage(void)
                                Time_Start();\r
                        }\r
                        \r
+                       sreg_saved = SREG;\r
+                       cli();\r
+                       adcs_VBAT_tmp = ADCS.VBAT;\r
+                       SREG = sreg_saved;\r
+\r
                        // Adjust the charge voltage to within ChargeParameters.Voltage\r
                        // +/- BAT_VOLTAGE_HYST.\r
-                       if (ADCS.VBAT < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST)) {\r
+                       if (adcs_VBAT_tmp < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST)) {\r
 \r
                                if(!PWM_IncrementDutyCycle()) {\r
 #ifdef ABORT_IF_PWM_MAX\r
@@ -191,7 +206,7 @@ unsigned char ConstantVoltage(void)
                                        error = TRUE;\r
 #endif\r
                                }\r
-                       } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) {\r
+                       } else if (adcs_VBAT_tmp > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) {\r
 \r
                                if(!PWM_DecrementDutyCycle()) {\r
 #ifdef ABORT_IF_PWM_MIN\r
@@ -238,6 +253,9 @@ unsigned char ConstantVoltage(void)
 unsigned char HaltNow(void)\r
 {\r
        unsigned char i, halt = FALSE;\r
+       unsigned int adcs_rawNTC_tmp, adcs_VBAT_tmp;\r
+       signed int adcs_avgIBAT_tmp;\r
+       unsigned char sreg_saved;\r
        \r
        // Wait for a full ADC-cycle to finish.\r
        ADC_Wait();\r
@@ -247,14 +265,20 @@ unsigned char HaltNow(void)
        // (Gets overridden if either mains is failing, or the battery changes.)\r
        for (i = 0x01; i != 0; i <<= 1) {\r
                if (HaltParameters.HaltFlags & i) {\r
+                       \r
+                       sreg_saved = SREG;\r
+                       cli();\r
+                       adcs_VBAT_tmp = ADCS.VBAT;\r
+                       adcs_avgIBAT_tmp  = ADCS.avgIBAT;\r
+                       SREG = sreg_saved;\r
+                       \r
                        switch (i) {\r
                        // Is VBAT less than the recorded maximum?\r
                        case HALT_VOLTAGE_DROP:\r
-\r
                                // Update VBATMax if VBAT is higher. Evaluate for halt otherwise.\r
-                               if (ADCS.VBAT > HaltParameters.VBATMax) {\r
-                                       HaltParameters.VBATMax = ADCS.VBAT;\r
-                               } else if((HaltParameters.VBATMax - ADCS.VBAT) >= \r
+                               if (adcs_VBAT_tmp > HaltParameters.VBATMax) {\r
+                                       HaltParameters.VBATMax = adcs_VBAT_tmp;\r
+                               } else if((HaltParameters.VBATMax - adcs_VBAT_tmp) >= \r
                                          HaltParameters.VoltageDrop) {\r
                                        halt = TRUE;\r
                                }\r
@@ -264,7 +288,7 @@ unsigned char HaltNow(void)
                        // Has VBAT reached the maximum limit?\r
                        case HALT_VOLTAGE_MAX:  \r
                                \r
-                               if (ADCS.VBAT >= HaltParameters.VoltageMax) {\r
+                               if (adcs_VBAT_tmp >= HaltParameters.VoltageMax) {\r
                                        halt = TRUE;\r
                                }\r
                                break;\r
@@ -273,7 +297,7 @@ unsigned char HaltNow(void)
                        // Has IBAT reached the minimum limit?\r
                        case HALT_CURRENT_MIN:\r
                                \r
-                               if (ADCS.avgIBAT <= HaltParameters.CurrentMin) {\r
+                               if (adcs_avgIBAT_tmp <= HaltParameters.CurrentMin) {\r
                                        halt = TRUE;\r
                                }\r
                                break;\r
@@ -281,16 +305,20 @@ unsigned char HaltNow(void)
                                \r
                        // Is the temperature rising too fast?\r
                        case HALT_TEMPERATURE_RISE:\r
-\r
+                               \r
+                               sreg_saved = SREG;\r
+                               cli();\r
+                               adcs_rawNTC_tmp = ADCS.rawNTC;\r
+                               SREG = sreg_saved;\r
                                // If rawNTC has increased, the temperature has dropped.\r
                                // We can store this value for now, and start the timer.\r
                                // Otherwise, check if NTC has changed too fast.\r
-                               if (ADCS.rawNTC > HaltParameters.LastNTC) {\r
-                                       HaltParameters.LastNTC = ADCS.rawNTC;\r
+                               if (adcs_rawNTC_tmp > HaltParameters.LastNTC) {\r
+                                       HaltParameters.LastNTC = adcs_rawNTC_tmp;\r
                                        Time_Set(TIMER_TEMP,0,30,0);\r
                                        \r
                                // Is the increase in temperature greater than the set threshold?\r
-                               } else  if ((HaltParameters.LastNTC - ADCS.rawNTC) >=\r
+                               } else  if ((HaltParameters.LastNTC - adcs_rawNTC_tmp) >=\r
                                  (BattData.ADCSteps * HaltParameters.TemperatureRise)) {\r
                                        \r
                                        // If this happened within a timeframe of 30 seconds, the \r
@@ -299,7 +327,7 @@ unsigned char HaltNow(void)
                                        if (Time_Left(TIMER_TEMP))  {\r
                                                halt = TRUE;\r
                                        } else {\r
-                                               HaltParameters.LastNTC = ADCS.rawNTC;\r
+                                               HaltParameters.LastNTC = adcs_rawNTC_tmp;\r
                                                Time_Set(TIMER_TEMP,0,30,0);\r
                                        }\r
                                }\r
@@ -317,8 +345,8 @@ unsigned char HaltNow(void)
                                        if (HaltParameters.HaltFlags & HALT_FLAG_EXHAUSTION) {\r
                                                        PWM_Stop();\r
                                                        Battery_t tmp = eeprom_read_byte(&BattControl[BattActive]);\r
-                                                        tmp &= ~BIT_BATTERY_ENABLED; // Enabled = FALSE;\r
-                                                        eeprom_write_byte(&BattControl[BattActive], tmp);\r
+                                                                                        tmp &= ~BIT_BATTERY_ENABLED; // Enabled = FALSE;\r
+                                                                                        eeprom_write_byte(&BattControl[BattActive], tmp);\r
                                                        BattData.Exhausted = TRUE;\r
                                                        SetErrorFlag(ERR_BATTERY_EXHAUSTED);\r
                                                        ChargeParameters.NextState = ST_ERROR;\r
index 62f46d3060f862836ef04720e0c1c1889c1f5e11..919c965b84fa78434f958e619f7b3df51fdc6fe4 100644 (file)
@@ -108,8 +108,8 @@ int main( void )
        \r
        // Look for function associated with current state, get its address.\r
        for (i = 0; pgm_read_byte(&menu_state[i].state) != 0; i++) {\r
-          if (pgm_read_byte(&menu_state[i].state) == CurrentState) {\r
-            pStateFunc = (PGM_VOID_P) pgm_read_word(&menu_state[i].pFunc);\r
+               if (pgm_read_byte(&menu_state[i].state) == CurrentState) {\r
+                       pStateFunc = (PGM_VOID_P) pgm_read_word(&menu_state[i].pFunc);\r
                }\r
        }\r
 \r
@@ -123,8 +123,8 @@ int main( void )
                if (nextstate != CurrentState) {\r
                        CurrentState = nextstate;\r
                        for ( i = 0; pgm_read_byte(&menu_state[i].state) != 0; i++) {\r
-                          if (pgm_read_byte(&menu_state[i].state) == CurrentState) {\r
-                            pStateFunc = (PGM_VOID_P) pgm_read_word(&menu_state[i].pFunc);\r
+                               if (pgm_read_byte(&menu_state[i].state) == CurrentState) {\r
+                                       pStateFunc = (PGM_VOID_P) pgm_read_word(&menu_state[i].pFunc);\r
                                }\r
                        }\r
                }\r
index 9df2b5c93ea086c8c0d2611d1f8cec4141e571d5..ef1464dcab714766f0addf4d6fb0261e04cec53b 100644 (file)
@@ -103,7 +103,7 @@ unsigned char Initialize(unsigned char inp)
        // Clear on-chip EEPROM.\r
        for (page = 0; page < 4; page++)        {\r
                for (i = 0; i < 32; i++) {\r
-                  eeprom_write_byte(&BattEEPROM[page][i], 0);\r
+                       eeprom_write_byte(&BattEEPROM[page][i], 0);\r
                }\r
        }\r
 \r
@@ -113,13 +113,16 @@ unsigned char Initialize(unsigned char inp)
        ADC_Init();\r
        Time_Init();\r
 \r
+       // Enable interrupts\r
+       sei();\r
+\r
        // Attempt to get ADC-readings (also gets RID-data) from both batteries.\r
        for (i = 0; i < 2; i++) {\r
                EnableBattery(i);\r
                ADC_Wait();\r
                BatteryStatusRefresh();\r
        }\r
-    \r
+\r
        DisableBatteries();\r
        \r
        BattActive = 0;               // We have to start somewhere..\r
@@ -166,7 +169,7 @@ unsigned char BatteryControl(unsigned char inp)
        // Get ADC-readings, try to read EPROM, and start prequalification\r
        // of any uncharged battery.\r
        for (i = 0; i < 2; i++) {\r
-          if (eeprom_read_byte(&BattControl[i]) & BIT_BATTERY_ENABLED) {      \r
+               if (eeprom_read_byte(&BattControl[i]) & BIT_BATTERY_ENABLED) {\r
                        EnableBattery(i);\r
                        ADC_Wait();\r
 \r
@@ -174,7 +177,7 @@ unsigned char BatteryControl(unsigned char inp)
                                if (!BattData.Charged) {\r
                                        BatteryDataRefresh();\r
 \r
-                                       return(ST_PREQUAL);       \r
+                                       return(ST_PREQUAL);\r
                                }\r
                        }\r
                }\r
@@ -246,7 +249,7 @@ void Doze(void)
        ADCS.Flag = FALSE;\r
        \r
        do {\r
-       } while (ADCS.Flag == FALSE);    \r
+       } while (ADCS.Flag == FALSE);\r
        \r
        WDTCR = (1<<WDP3)|(1<<WDP0);            // 8.0 seconds at 5 volts VCC.\r
        WDTCR |= (1<<WDIF)|(1<<WDIE)|(1<<WDE);  // Clear flag and enable watchdog.\r
@@ -313,7 +316,7 @@ unsigned char Error(unsigned char inp)
 \r
                                case  ERR_NO_BATTERIES_ENABLED:\r
                                        // Clear if any battery gets enabled.\r
-                                  if ((eeprom_read_byte(&BattControl[0]) & BIT_BATTERY_ENABLED) || (eeprom_read_byte(&BattControl[1]) & BIT_BATTERY_ENABLED)) {\r
+                                       if ((eeprom_read_byte(&BattControl[0]) & BIT_BATTERY_ENABLED) || (eeprom_read_byte(&BattControl[1]) & BIT_BATTERY_ENABLED)) {\r
                                                        ErrorFlags &= ~i;\r
                                        }\r
                                break;\r
@@ -378,6 +381,10 @@ void SetErrorFlag(unsigned char Flag)
  */\r
 unsigned char JumperCheck(void)\r
 {\r
+       unsigned char sreg_saved;\r
+       unsigned int adcs_rawVBAT_tmp, adcs_VIN_tmp, adcs_VBAT_tmp;\r
+       signed int adcs_IBAT_tmp;\r
+\r
         DisableBatteries();       // Disconnect, or loads may be destroyed!\r
         \r
         PWM_Start();              // Start PWM (controls the buck charger).\r
@@ -388,14 +395,22 @@ unsigned char JumperCheck(void)
        do {\r
                // If the PWM output voltage saturates the ADC, stop PWM output and\r
                // report a failure.\r
-               if (ADCS.rawVBAT == 1023) {\r
+               sreg_saved = SREG;\r
+               cli();\r
+               adcs_rawVBAT_tmp = ADCS.rawVBAT;\r
+               adcs_VBAT_tmp = ADCS.VBAT;\r
+               adcs_VIN_tmp = ADCS.VIN;\r
+               adcs_IBAT_tmp = ADCS.IBAT;\r
+               SREG = sreg_saved;\r
+\r
+               if (adcs_rawVBAT_tmp == 1023) {\r
                        PWM_Stop();\r
                        return(FALSE);\r
                }\r
 \r
                // If the absolute difference between measured (VIN - VBAT) and the\r
                // typical value are below our set maximum, everything is OK.\r
-               if (abs((signed int)(ADCS.VIN - VIN_VBAT_DIFF_TYP - ADCS.VBAT)) <\r
+               if (abs((signed int)(adcs_VIN_tmp - VIN_VBAT_DIFF_TYP - adcs_VBAT_tmp)) <\r
                                     VIN_VBAT_DIFF_MAX ) {\r
                                 \r
                        PWM_Stop();\r
@@ -403,7 +418,7 @@ unsigned char JumperCheck(void)
                }\r
 \r
                // Charge current is too high -> check load and jumper J405 and J406.\r
-               if (abs(ADCS.IBAT) > 100) {\r
+               if (abs(adcs_IBAT_tmp) > 100) {\r
                        PWM_Stop();\r
                        return(FALSE);\r
                }\r
@@ -415,7 +430,7 @@ unsigned char JumperCheck(void)
                        return(FALSE);\r
                }\r
                \r
-      // Wait for ADC conversions to complete\r
+               // Wait for ADC conversions to complete\r
                ADC_Wait();\r
        } while (Time_Left(TIMER_GEN));\r
        \r
index ee738bd3e63286842e5389d4ada7a76646d30c81..61df5c04e66bfb7217ce971d6c5c44945a9c4716 100644 (file)
@@ -38,7 +38,7 @@
 //******************************************************************************\r
 // Variables\r
 //******************************************************************************\r
-unsigned long timeval[TIMERS];  //!< Contains the values for each timer.\r
+volatile unsigned long timeval[TIMERS];  //!< Contains the values for each timer.\r
 \r
 // timer runs at 1 MHz and overflow will occur every 255 / 1 Mz ~= 0.25 ms \r
 //#pragma vector = TIM0_OVF_vect\r
@@ -76,7 +76,15 @@ ISR(TIMER0_COMPA_vect)
  */ \r
 unsigned char Time_Left(unsigned char timer)\r
 {\r
-       if(timeval[timer] > 0) {\r
+       unsigned long tval;\r
+       unsigned char sreg_saved;\r
+\r
+       sreg_saved = SREG;\r
+       cli();\r
+       tval = timeval[timer];\r
+       SREG = sreg_saved;\r
+\r
+       if( tval > 0 ) {\r
                return(TRUE);\r
        } else {\r
                return(FALSE);\r
@@ -99,9 +107,18 @@ void Time_Set(unsigned char timer, unsigned int min, unsigned char sec,
 //     timeval[i] += 4000 * (unsigned long)sec;\r
 //     timeval[i] += 4 * (unsigned long)ms;\r
 \r
-       timeval[timer] = 60000 * (unsigned long)min;\r
-       timeval[timer] += 1000 * (unsigned long)sec;\r
-       timeval[timer] += 1 * (unsigned long)ms;\r
+       unsigned long tval;\r
+       unsigned char sreg_saved;\r
+       \r
+\r
+       tval  = 60000 * (unsigned long)min;\r
+       tval += 1000 * (unsigned long)sec;\r
+       tval += 1 * (unsigned long)ms;\r
+\r
+       sreg_saved = SREG;\r
+       cli();\r
+       timeval[timer] = tval;\r
+       SREG = sreg_saved;\r
 }\r
 \r
 \r
@@ -133,10 +150,14 @@ void Time_Start(void)
 void Time_Init(void)\r
 {\r
        unsigned char i;\r
+       unsigned char sreg_saved;\r
        \r
+       sreg_saved = SREG;\r
+       cli();\r
        for (i = 0; i<<TIMERS; i++)     {\r
                timeval[i] = 0;\r
        }\r
+       SREG = sreg_saved;\r
 \r
        //    OCR0A = 0;  // Doesn't matter, will run in normal mode.\r
        \r
@@ -155,7 +176,4 @@ void Time_Init(void)
        //    TIMSK |= (1<<TOIE0);      // Overflow interrupt enabled.\r
 \r
        TIMSK |= (1<<OCIE0A);  // Timer 0, Compare match A interrupt enabled.\r
-\r
-       // Enable interrupts, just in case they weren't already.\r
-       sei();       \r
 }\r
index 5dc4f0e0f1a74622cb5339ea77ed6a50ba2c9468..b4c0a75e8558f7877cbfcaab932054dc0fd5f1fa 100644 (file)
@@ -32,7 +32,7 @@
 //******************************************************************************\r
 // Globals\r
 //******************************************************************************\r
-extern unsigned long timeval[];  // Needed for SPI transfer.\r
+extern volatile unsigned long timeval[];  // Needed for SPI transfer.\r
 \r
 \r
 //******************************************************************************\r