View unanswered posts | View active topics It is currently Sun Dec 17, 2017 2:53 pm



This topic is locked, you cannot edit posts or make further replies.  [ 982 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6 ... 99  Next
Fred's firmware development diary 
Author Message
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 14913
Location: Home sweet home!
I had a bit of a "moment of truth and enlightenment" last night in the shower. I already knew that the hardware timer could be extended by incrementing another variable on overflow, but (of course) that can not be used to switch the hardware outputs. Thus, the input side of counting can be arbitrarily precise out to the nth degree, but the output side is bounded by two things, maximum period, and unit of measure. Obviously we want the unit of measure to be as small as possible, but what about the period... well, we need to be able to inject enough under high load, low rpm, heavy enrichment situations. If we used 16 as the prescaler, we get 400ns units, and 26.2144ms maximum pulse width. That is not enough for all situations. The next step gives 52.4288ms which should be plenty for most situations and still has less than 1us accuracy (800ns/0.8us). There is going to need to be a minimum pulse width limit too because of the latency of the code that switches the hardware timer register. That should be very small indeed. But it will exist as a limitation.

Things that I need to do :
  • Ensure that "pulse width" is above min and below max at all times by force. (maybe set a flag for each condition that says something is wrong)
  • Make overlapping periods transition to full on cleanly and transition back to switching cleanly again
  • Read the signal properly with a good usable on car strategy

That last one needs to involve some or all of the following (and maybe more) :
  • Hardware tooth throwing out (introduces a 256,512,1024 bus cycle delay before interrupt if used)
  • Software tooth throwing out (means performing actions at end of tooth (better for VR anyway)
  • Counter increment on leading edge, decrement on trailing if invalid tooth (needs thought and status)
  • History and comparison of the previous gaps between main teeth
  • History and comparison of the previous tooth widths
  • Comparison of second trigger location with where expected
  • History and comparison of second trigger tooth width

I'm working on it :-)

When thats done, it will be ready for on car manual pulsewidth control idle testing :-)

Admin.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Wed Mar 05, 2008 11:35 am
Profile WWW
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 14913
Location: Home sweet home!
I've been experimenting :-)

What I have discovered is that it is possible to switch edges and interrupt without changing the state of the port (OC mode).

What this means is that we can turn the timer down to really fine grain control and set the edge and counter to interrupt without switching it off, inc a var, reset the same, etc and finally set to go low at the predefined time.

This also means we can have arbitrarily long pulse widths and arbitrarily fine grain control of fueling for awesome precision at ALL RPM and widths :-) Sweet!!!

http://www.google.com/search?hl=en&safe ... tnG=Search

0.1us control anybody? That gives max period of 6.5ms meaning for a typical sort of 20ms high width pulse you would get 3 or 4 interrupts for each injector channel for each injection. Could be worth it, perhaps something to work on later.

I'll stick to making more conventional control work right first.

Admin.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Wed Mar 05, 2008 1:24 pm
Profile WWW
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 14913
Location: Home sweet home!
Additionally, if 16 bits takes 52ms, then the longest measurable period with an overflow counter extension is 3400 seconds or 57 minutes, a little excessive really. If we knock it to 6.5ms period we get 7 minutes which is still WAY more than we need at all.

The worst case tooth measuring is this :

One tooth of 180 degrees on the Cam, so one edge every 2 revolutions.
If you say that it could spin as low as 1rpm then those edges are 1 minute apart and we still hose in. Yet, at high rpm, our input capture is going to be uber fast and accurate. Nice stuff.

Admin.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Wed Mar 05, 2008 1:33 pm
Profile WWW
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 14913
Location: Home sweet home!
Of course, what I didn't mention is that the benefit (large) of this is to be able to do the final pulse width calculation as late as possible before turn off. Combined with my cunning main loop segregation we could have a rather significant increase in transient behaviour accuracy :-)

If only the code could just materialise :-)

Admin.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Wed Mar 05, 2008 1:47 pm
Profile WWW
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 14913
Location: Home sweet home!
Also, careful selection of exactly when those interrupts are at could potentially allow us to use the IC/OC timers to bit bang the staged injectors! That could get complex though, and I'd rather keep it simple, but It should be possible :-)

Damn! I'm on a roll this morning. (making up for a slow yesterday)

Admin.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Wed Mar 05, 2008 1:49 pm
Profile WWW
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 14913
Location: Home sweet home!
This release is significant in that the basics of injection control for a NipponDenso 24/2 are sort of there.

I would NOT try this on a car at this time!!

...because there is NO error checking and it definitely misbehaves when the start and end of pulses overlap, and when the input signal is rough/dodgy.

On the other hand, if you are silly enough to ignore me and get an engine idling on this exact code (or any later one with a similar warning at your option) please share it with us here :-)

0.0.7 - 6/3/08
Moved pins for ignition around
Changed obsolete code in main.c with idea inspired by Alex
Tidied and removed some TODOs
Added port A and B access together for ignition output (registers are conveniently next to each other for word access)
Moved PWM experimentation to a function and init.c
Shifted all macros for main injectors to freeems.h for use in (at least) two source files
Rearranged and changed all global variables
Added new status and settings bitwise variables
Implemented very basic NipponDenso decoder that I would not trust to do much at all.

http://www.youtube.com/watch?v=7WXvQi2gpg8

http://sourceforge.net/project/showfile ... _id=581928

I apologise for the large rate of change of the code. If you are trying to work from it, the best you can hope to do is hand remerge your changes on each release. As things stabillise into the future I expect that the difficulty in merging changes to older releases forward will diminish somewhat.

Enjoy!

Admin.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Wed Mar 05, 2008 5:50 pm
Profile WWW
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 14913
Location: Home sweet home!
Admin wrote:
Additionally, if 16 bits takes 52ms, then the longest measurable period with an overflow counter extension is 3400 seconds or 57 minutes, a little excessive really. If we knock it to 6.5ms period we get 7 minutes which is still WAY more than we need at all.

The worst case tooth measuring is this :

One tooth of 180 degrees on the Cam, so one edge every 2 revolutions.
If you say that it could spin as low as 1rpm then those edges are 1 minute apart and we still hose in. Yet, at high rpm, our input capture is going to be uber fast and accurate. Nice stuff.

Admin.


Of course (and no, I didn't think of this earlier) this also limits the time after the schedule tooth that the pulse can start. Unless you do the same thing with advance, at which point it becomes arbitrary. (code for one should be very much the same as for the other)

Admin.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Wed Mar 05, 2008 8:30 pm
Profile WWW
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 14913
Location: Home sweet home!
EDIT : See next post!

I measured the run time of the really simple switch on code :

Code:
void Injector5ISR(void)
{
   /* Clear the interrupt flag for this channel */
   TFLG1 = MAIN5ON;

   /* If rising edge triggered this */
   if(PTIT & MAIN5ON){ // Stuff for switch on time
      // set the time to turn off again
      MAIN5TIME += ATD0DR7 + totalPulseWidth;

      // display the amount we are adding
      PORTA = ATD0DR7 >> 2;
      
      /* Set the action for compare to switch off */
      MAIN5CTL &= MAIN5GOLOW;
   }
}


193 timer units = 154.4us run time including all loading function handling etc. not including the rest, and unloading etc. just an interesting thing to note...

Admin.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Wed Mar 05, 2008 9:15 pm
Profile WWW
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 14913
Location: Home sweet home!
Not only has the measurement changed (added some caps to the board) but I think I did the calculation wrongly too.

Actually, 8 Timer units seems to be the code run time 6.4us (probably a bit less, but with 4 it jittered on and off) which gives us 128 - 256 bus cycles from output trips to when the timer gets reset. Much more reasonable. There is hope for us yet, off to apologise to Flacid for misleading him about his viagra.

Admin.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Thu Mar 06, 2008 10:14 am
Profile WWW
Moderator
User avatar

Joined: Tue Jan 15, 2008 2:31 pm
Posts: 14913
Location: Home sweet home!
I'm going to fix a few things up such that changing the prescaler for the timer doesn't affect operation (other than max pulsewidth).

Secondly, I realised that the table for timer prescalers in the manual is just an example. not a full table. So we can pick and choose our time base down to the finest grain.

Thirdly, I have some very basic code that piggy backs output compares on top of each other by giving a count and final period.

This can be further optimised by using divide and modulus to ensure that the last time period is not too small.

Then you just take a time count in (arbitrarily large) figure out how many periods fit within it and what the left over is, and find a main period and final period that are all in the large region that is safe.

if a pulse is timeperiod - 1, you use it (or similar)
if it is time period + 1, you cut in half, and add the left over on to one of them ensuring that it doesn't exceed max.

currently I'm doing 7 second periods with 1000 interrupts and 7ms chunks.

Additionally, the output compare code can watch the timer overflow variable and by careful examination of the interrupt flags when it is triggered know exactly where it is at absolute time wise. This only works till the final pulse as these interrupts are generated while trying to switch an On injector On again. Once you set it to switch off, its off... so knowing where you are is useless. However on the second to last you could fine tune the pulsewidth to the latest measurement/calculation if done right.

here is the uber basic code that does this (took far too long to write with a handful of errors here and there) :

Code:
void Injector6ISR(void){
   TFLG1 = MAIN6ON; // clear flag
   PORTK++; // blink k7 if we are still interrupting despite edge being already high
   PORTS_BA = periodCount;
   PORTM = MAIN6CTL;
   
   if(timerTestFlag){
      if(periodCount == 0){
         // configure count variable from spare on Jim
         periodCount = ATD0DR7 + 1;

         // configure final pulse variable
         trimLength = (ATD0DR3 << 6) + 1000;
      }else if(periodCount == 1){
         // set next time to be trimlength from now
         MAIN6TIME += trimLength;
         
         if(MAIN6CTL & MAIN6GOHIGH){ // invert direction prior last edge
            MAIN6CTL &= MAIN6GOLOW; // change to go low
         }else{
            MAIN6CTL |= MAIN6GOHIGH; // change to go high   
         }
      }
      
      periodCount--; // decrement counter      
   }else{
      // turn int off
      TIE &= 0x7F;
      // disable switching
      MAIN6CTL &= MAIN6DISABLE;
      
      // turn of pin(s) lazy...
      PORTT = ZEROS;
   }
}


misc_isrs.c :

Code:
   case 0x08 : // Trigger timed pulse
      if(!timerTestFlag){
         PORTK = ONES; // set k

         // set flag
         timerTestFlag = TRUE;
         
         // configure count variable from spare on Jim
         periodCount = ATD0DR7 + 1;

         // configure final pulse variable
         trimLength = (ATD0DR3 << 6) + 1000;
         
         // configure timer to switch on
         MAIN6CTL |= MAIN1ENABLE;

         // configure time to be (short-max/2 +tcnt later)
         MAIN6TIME = TCNT + 1000; // start very soon for now (could use force too)
         
         // configure the interrupt to be on
         TIE |= 0x80;
      }else{
         PORTK = ZEROS; // clear k

         // unset flag
         timerTestFlag = FALSE;
         
         // turn the interrupt off
         TIE &= 0x7F;
         
         // switch off channel
         PORTT = ZEROS;
         
         // disable compare
         MAIN6CTL &= MAIN6DISABLE;
      }
      break;


some of each is probably superfluous/wrong, but it works as it is and I dont want to do a release for it (there are more changes to some variables and flags in init.c too and commenting out of stuff in enginepos.c

see :

/* section 10.3.5 page 290 68hc11 reference manual e.g. groups.csail.mit.edu/drl/courses/cs54-2001s/pdf/M68HC11RM.pdf */

for timer extension implementation details.

_________________
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!


Fri Mar 07, 2008 1:59 pm
Profile WWW
Display posts from previous:  Sort by  
This topic is locked, you cannot edit posts or make further replies.   [ 982 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6 ... 99  Next

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software for PTF. ColorizeIt.