Initial commit of 0.0.18 just as it was released!
[freeems-vanilla.git] / src / main.c
blob39d1b47c6a37fcc578f26058eedd4b52174e1906
1 /* main.c
3 Copyright 2008 Fred Cooke
5 This file is part of the FreeEMS project.
7 FreeEMS software is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 FreeEMS software is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with any FreeEMS software. If not, see <http://www.gnu.org/licenses/>.
20 We ask that if you make any changes to this file you send them upstream to us at admin@diyefi.org
22 Thank you for choosing FreeEMS to run your engine! */
24 #include "inc/main.h"
26 int main(){ // TODO maybe move this to paged flash ?
27 // Set everything up.
28 init();
30 //LongNoTime.timeLong = 54;
31 // Run forever repeating.
32 while(TRUE){
33 adjustPWM();
34 // unsigned short start = realTimeClockMillis;
35 /* If ADCs require forced sampling, sample now */
36 if(coreStatusA & FORCE_READING){
37 ATOMIC_START(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
38 /* Atomic block to ensure a full set of readings are taken together */
40 /* Check to ensure that a reading wasn't take before we entered a non interruptable state */
41 if(coreStatusA & FORCE_READING){ // do we still need to do this TODO ?
43 sampleEachADC(ADCArraysRecord); // TODO still need to do a pair of loops and clock these two functions for performance.
44 //sampleLoopADC(&ADCArrays);
45 resetToNonRunningState();
46 Counters.timeoutADCreadings++;
48 /* Set flag to say calc required */
49 coreStatusA |= CALC_FUEL_IGN;
51 /* Clear force reading flag */
52 coreStatusA &= CLEAR_FORCE_READING;
55 ATOMIC_END(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
58 /* If required, do main fuel and ignition calcs first */
59 if(coreStatusA & CALC_FUEL_IGN){
60 ATOMIC_START(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
61 /* Atomic block to ensure that we don't clear the flag for the next data set when things are tight */
63 /* Switch input bank so that we have a stable set of the latest data */
64 if(ADCArrays == &ADCArrays1){
65 RPM = &RPM0; // TODO temp, remove
66 RPMRecord = &RPM1; // TODO temp, remove
67 ADCArrays = &ADCArrays0;
68 ADCArraysRecord = &ADCArrays1;
69 mathSampleTimeStamp = &ISRLatencyVars.mathSampleTimeStamp0; // TODO temp, remove
70 mathSampleTimeStampRecord = &ISRLatencyVars.mathSampleTimeStamp1; // TODO temp, remove
71 }else{
72 RPM = &RPM1; // TODO temp, remove
73 RPMRecord = &RPM0; // TODO temp, remove
74 ADCArrays = &ADCArrays1;
75 ADCArraysRecord = &ADCArrays0;
76 mathSampleTimeStamp = &ISRLatencyVars.mathSampleTimeStamp1; // TODO temp, remove
77 mathSampleTimeStampRecord = &ISRLatencyVars.mathSampleTimeStamp0; // TODO temp, remove
80 /* Clear the calc required flag */
81 coreStatusA &= CLEAR_CALC_FUEL_IGN;
83 ATOMIC_END(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
85 /* Store the latency from sample time to runtime */
86 ISRLatencyVars.mathLatency = TCNT - *mathSampleTimeStamp;
87 /* Keep track of how many calcs we are managing per second... */
88 Counters.calculationsPerformed++;
89 /* ...and how long they take each */
90 unsigned short mathStartTime = TCNT;
92 /* Generate the core variables from sensor input and recorded tooth timings */
93 generateCoreVars();
95 RuntimeVars.genCoreVarsRuntime = TCNT - mathStartTime;
96 unsigned short derivedStartTime = TCNT;
98 /* Generate the derived variables from the core variables based on settings */
99 generateDerivedVars();
101 RuntimeVars.genDerivedVarsRuntime = TCNT - derivedStartTime;
102 unsigned short calcsStartTime = TCNT;
104 /* Perform the calculations TODO possibly move this to the software interrupt if it makes sense to do so */
105 calculateFuelAndIgnition();
107 RuntimeVars.calcsRuntime = TCNT - calcsStartTime;
108 /* Record the runtime of all the math total */
109 RuntimeVars.mathTotalRuntime = TCNT - mathStartTime;
111 RuntimeVars.mathSumRuntime = RuntimeVars.calcsRuntime + RuntimeVars.genCoreVarsRuntime + RuntimeVars.genDerivedVarsRuntime;
113 ATOMIC_START(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
114 /* Atomic block to ensure that outputBank and outputBank Offsets match */
116 /* Switch banks to the latest data */
117 if(injectorMainPulseWidthsMath == injectorMainPulseWidths1){
118 currentDwellMath = &currentDwell0;
119 currentDwellRealtime = &currentDwell1;
120 injectorMainPulseWidthsMath = injectorMainPulseWidths0;
121 injectorMainPulseWidthsRealtime = injectorMainPulseWidths1;
122 injectorStagedPulseWidthsMath = injectorStagedPulseWidths0;
123 injectorStagedPulseWidthsRealtime = injectorStagedPulseWidths1;
124 }else{
125 currentDwellMath = &currentDwell1;
126 currentDwellRealtime = &currentDwell0;
127 injectorMainPulseWidthsMath = injectorMainPulseWidths1;
128 injectorMainPulseWidthsRealtime = injectorMainPulseWidths0;
129 injectorStagedPulseWidthsMath = injectorStagedPulseWidths1;
130 injectorStagedPulseWidthsRealtime = injectorStagedPulseWidths0;
133 ATOMIC_END(); /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
134 }else{
135 /* In the event that no calcs are required, sleep a little before returning to retry. */
136 sleepMicro(RuntimeVars.mathTotalRuntime); // not doing this will cause the ISR lockouts to run for too high a proportion of the time
137 /* Using 0.8 ticks as micros so it will run for a little longer than the math did */
141 if(!(TXBufferInUseFlags)){
142 // unsigned short logTimeBuffer = Clocks.realTimeClockTenths;
143 /* If the flag for com packet processing is set and the TX buffer is available process the data! */
144 if(RXStateFlags & RX_READY_TO_PROCESS){
145 /* Clear the flag */
146 RXStateFlags &= RX_CLEAR_READY_TO_PROCESS;
148 /* Handle the incoming packet */
149 decodePacketAndRespond();
150 }else if(ShouldSendLog){//(lastTime != logTimeBuffer) && (lastCalcCount != Counters.calculationsPerformed)){
152 /* send asynchronous data log if required */
153 if(asyncDatalogType!= asyncDatalogOff){
154 switch (asyncDatalogType) {
155 case asyncDatalogBasic:
157 /* Flag that we are transmitting! */
158 TXBufferInUseFlags |= COM_SET_SCI0_INTERFACE_ID;
159 // SCI0 only for now...
161 // headers including length... *length = configuredBasicDatalogLength;
162 TXBufferCurrentPositionHandler = (unsigned char*)&TXBuffer;
164 /* Initialised here such that override is possible */
165 TXBufferCurrentPositionSCI0 = (unsigned char*)&TXBuffer;
166 TXBufferCurrentPositionCAN0 = (unsigned char*)&TXBuffer;
168 /* Set the flags : firmware, no ack, no addrs, has length */
169 *TXBufferCurrentPositionHandler = HEADER_HAS_LENGTH;
170 TXBufferCurrentPositionHandler++;
172 /* Set the payload ID */
173 *((unsigned short*)TXBufferCurrentPositionHandler) = responseBasicDatalog;
174 TXBufferCurrentPositionHandler += 2;
176 /* Set the length */
177 *((unsigned short*)TXBufferCurrentPositionHandler) = configuredBasicDatalogLength;
178 TXBufferCurrentPositionHandler += 2;
180 /* populate data log */
181 populateBasicDatalog();
182 checksumAndSend();
183 break;
185 case asyncDatalogConfig:
187 // TODO
188 break;
190 case asyncDatalogTrigger:
192 // TODO
193 break;
195 case asyncDatalogADC:
197 // TODO
198 break;
200 case asyncDatalogCircBuf:
202 // TODO
203 break;
205 case asyncDatalogCircCAS:
207 // TODO
208 break;
210 case asyncDatalogLogic:
212 // TODO
213 break;
217 ShouldSendLog = FALSE;
218 // // mechanism to ensure we send once per clock tick without doing it in the RTC section.
219 // lastTime = logTimeBuffer;
220 // // mechanism to ensure we only send something if the data has been updated
221 // lastCalcCount = Counters.calculationsPerformed;
224 // on once per cycle for main loop heart beat (J0)
225 PORTJ ^= 0x01;
228 // debug...
229 if(SCI0CR2 & SCICR2_RX_ENABLE){
230 PORTK |= BIT2;
231 }else{
232 PORTK &= NBIT2;
235 if(SCI0CR2 & SCICR2_RX_ISR_ENABLE){
236 PORTK |= BIT3;
237 }else{
238 PORTK &= NBIT3;
241 // PWM experimentation
242 adjustPWM();