Bavarian Soundwerks
Page 14 of 79 FirstFirst ... 4567891011121314151617181920212223243964 ... LastLast
Results 326 to 350 of 1959

Thread: Feeler: Open Source OBC Firmware

  1. #326
    Join Date
    Apr 2005
    Location
    Sammamish, WA
    Posts
    5,600
    My Cars
    95 Hellrot M3/02 MY Z06
    Wow Jason, sweet stuff Dude! Glad your having some serious progress. I hope an OBD1 interface can happen sometime. I'm no programmer but back in '85 I was a Electo-Optics / Laser Tech for Rockwell and was NASA Certified in Soldering, so I can build from a kit! LOL!

    John
    '95 Hellrot M3 w/Dove
    AA Euro HFM Stage II (w/21# Injectors & Software) W/Gen III Exhaust - URI Crank Pully - FDM w/3 Row M Coupe Rad - 3.23 LSD - Vogtland Club Spec/Koni SA - UUC Red w/Enforcers - TMS Shims/Rear Camber Bars w/QA1 inners/Sways - VMC F/TMS R End Links - X-Brace - Perf Ultimate/SS Brake Lines - GC Tower Mounts/RTAB Shims - ZKW's w/5000K Hid - Fog Delete - Alpine 9847/Pioneer TS-C130R Kevlar Components/Pioneer PRS-X340/Stealth Box's/Wired Zune 120GB - OE LTW CF Sills/Glove Box Plate - Staggered Black M-Spoke II's w/235/40 (front), 255/40 (Rear) Nitto NT05's - Rolled Fenders!

    ***Got a '95 M3? (actually pretty common on all years! Even happened to Racer Seth Thomas! ) Check Your LSD! http://forums.bimmerforums.com/forum...d.php?t=390209

  2. #327
    Join Date
    Jun 2004
    Location
    Europe
    Posts
    1,203
    My Cars
    ofc
    Quote Originally Posted by benemorius View Post
    I have to admit I've often wondered why the hell those wires were available to the obc.
    because so the dealer can codify & diagnose the obc directly via ADS or OBD2 port, without removing it.

    well, if you want to do something serious... kw71. Are you able talk to modules until now? you tried?

    are you still planning to start openobc.org ?
    Last edited by nuvola rossa; 06-23-2010 at 08:44 AM.

  3. #328
    Join Date
    Apr 2007
    Location
    Yorba Linda, CA
    Posts
    3,781
    My Cars
    1999 TiAg M3, 2003 E46M3
    Quote Originally Posted by nuvola rossa View Post
    because so the dealer can codify & diagnose the obc directly via ADS or OBD2 port, without removing it.

    well, if you want to do something serious... kw71. Are you able talk to modules until now? you tried?

    are you still planning to start openobc.org ?
    I haven't tried to talk to anything other than the display at this point... it seems benemorius is closing in on that one.

    As for the website, yes, it will be back up shortly. My primary task is documenting everything. Once that is done, the site will be put back online and real progress can be made with it.

    1999 ///M3 TiAg | Heated Power Vaders | DDM Projector36 5000K 55W HIDs | DDM 3000K 35W HID Fogs
    DDM Smoked Corners | DDM Weighted Shift Knob | K&N CAI | Mishimoto AL Rad w/Zionsville AL Shroud
    Stewart HiPo Water Pump | Samco Hose Kit | 16" SPAL Puller Fan | Viper 5701LE Security
    E36 OBC is now open! Join the effort: BF.C Thread | openOBC Wiki

  4. #329
    Join Date
    Nov 2007
    Location
    tallahassee,fl
    Posts
    1,371
    My Cars
    blown 328is
    Waiting for completion...i have paypal ready

  5. #330
    Join Date
    May 2006
    Location
    The Netherlands
    Posts
    16,710
    My Cars
    DE-spec E36 328i/M3 cab
    Quote Originally Posted by m2pc View Post



    Priceless!

    :Rofl
    1998 BMW M3 3.2 Cabrio • Alpinweiί III on Schwarz • German spec • 1 of 12
    SMG • SRA • PDC • AUC • OBC • GSM • HK • UURS • IHKA • FGR • MFL

    IG:
    https://www.instagram.com/iflok/



  6. #331
    Join Date
    May 2007
    Location
    US
    Posts
    942
    My Cars
    '94 325i / s13
    Quote Originally Posted by nuvola rossa View Post
    because so the dealer can codify & diagnose the obc directly via ADS or OBD2 port, without removing it.
    Damn. You're right. Why I never saw the obc as the module to be spoken to is beyond me.

    well, if you want to do something serious... kw71. Are you able talk to modules until now? you tried?
    I've read everything concerning kw71 that I've been able to find. The information is scarce, and what can be found is not exactly what I'd call dataseet material if you catch my drift. In any case, I think I've accumulated enough knowledge to at least get started now.

    Yesterday was the first time I tried talking to anything, and it was less than unsuccessful. Turns out my obc harness had been spliced by a previous owner, and it wasn't a pretty sight. It cost me an npn and a uart rx input. Neither the k nor l lines coming from the car were even connected, along with several others. God only knows which wires I was actually trying to drive. Probably vcc and ground.

    With everything appearing to be in order now, I'm attempting a slow init by sending 0x10 at 5 baud 7o1 on both k and l lines and looking for any kind of reply on the k line. So far I have yet to see either line driven low at all except by me. There does seem to be an excess of capacitance on the k line. I have to add 100 ohms of pullup just to keep acceptable rise times at 9600 baud, though of course I've left that off while trying a slow init. I don't know whether that's normal or not, but I do have to wonder what's going to happen when something tries to reply at 9600 baud with a rise time several times the length of a whole byte.
    Last edited by benemorius; 06-24-2010 at 04:30 AM.

  7. #332
    Join Date
    Apr 2007
    Location
    Yorba Linda, CA
    Posts
    3,781
    My Cars
    1999 TiAg M3, 2003 E46M3
    So are these "K" and "L" lines the same as "Diag RX" and "Diag TX" marked on the OBC wiring harness?

    1999 ///M3 TiAg | Heated Power Vaders | DDM Projector36 5000K 55W HIDs | DDM 3000K 35W HID Fogs
    DDM Smoked Corners | DDM Weighted Shift Knob | K&N CAI | Mishimoto AL Rad w/Zionsville AL Shroud
    Stewart HiPo Water Pump | Samco Hose Kit | 16" SPAL Puller Fan | Viper 5701LE Security
    E36 OBC is now open! Join the effort: BF.C Thread | openOBC Wiki

  8. #333
    Join Date
    May 2007
    Location
    US
    Posts
    942
    My Cars
    '94 325i / s13
    Code:
    [10]
    <55><0><81>
    Just as I hear thunder approaching, I get a reply from the dme on the k-line. Finally I can sit inside and work for a while, and the timing couldn't have been better.

    Quote Originally Posted by m2pc View Post
    So are these "K" and "L" lines the same as "Diag RX" and "Diag TX" marked on the OBC wiring harness?
    Yes. The ones marked tx are k line and rx is l line.
    Last edited by benemorius; 06-24-2010 at 10:42 AM. Reason: Automerged Doublepost

  9. #334
    Join Date
    Apr 2007
    Location
    Yorba Linda, CA
    Posts
    3,781
    My Cars
    1999 TiAg M3, 2003 E46M3
    Quote Originally Posted by benemorius View Post
    Code:
    [10]
    <55><0><81>
    Just as I hear thunder approaching, I get a reply from the dme on the k-line. Finally I can sit inside and work for a while, and the timing couldn't have been better.



    Yes. The ones marked tx are k line and rx is l line.
    Wow, amazing! So how did you actually get this working (what circuit did you use to interface to the vehicle)?

    Also, are you running standalone at this point, or is your OBC still driven from the parallel port of a PC?

    1999 ///M3 TiAg | Heated Power Vaders | DDM Projector36 5000K 55W HIDs | DDM 3000K 35W HID Fogs
    DDM Smoked Corners | DDM Weighted Shift Knob | K&N CAI | Mishimoto AL Rad w/Zionsville AL Shroud
    Stewart HiPo Water Pump | Samco Hose Kit | 16" SPAL Puller Fan | Viper 5701LE Security
    E36 OBC is now open! Join the effort: BF.C Thread | openOBC Wiki

  10. #335
    Join Date
    May 2007
    Location
    US
    Posts
    942
    My Cars
    '94 325i / s13
    It consists of a pair of transistors driving the k and l lines from the uart tx of a sam7, with a very resistive resistor from the k line to uart rx.

    It's been running from the sam7 from the beginning.

    On a side note, something else just responded at 0x90. (I've been running a loop from 0 to ff) I wonder what it was.
    Last edited by benemorius; 06-24-2010 at 10:56 AM.

  11. #336
    Join Date
    Jun 2004
    Location
    Europe
    Posts
    1,203
    My Cars
    ofc
    Quote Originally Posted by benemorius View Post
    It consists of a pair of transistors driving the k and l lines from the uart tx of a sam7, with a very resistive resistor from the k line to uart rx.

    It's been running from the sam7 from the beginning.

    On a side note, something else just responded at 0x90. (I've been running a loop from 0 to ff) I wonder what it was.
    Ok, you're on the right track. To be honest I'm more than two years out of these things and don't remeber now, but I should have a file with some ecus&modules address descriptors somewhere in my external HDDs.

    Even if I don't find that file I should know another way to help you out.

    Give me some time, I need to re focus my mind at those things.

  12. #337
    Join Date
    Apr 2007
    Location
    Yorba Linda, CA
    Posts
    3,781
    My Cars
    1999 TiAg M3, 2003 E46M3
    Quote Originally Posted by benemorius View Post
    It consists of a pair of transistors driving the k and l lines from the uart tx of a sam7, with a very resistive resistor from the k line to uart rx.

    It's been running from the sam7 from the beginning.

    On a side note, something else just responded at 0x90. (I've been running a loop from 0 to ff) I wonder what it was.

    1999 ///M3 TiAg | Heated Power Vaders | DDM Projector36 5000K 55W HIDs | DDM 3000K 35W HID Fogs
    DDM Smoked Corners | DDM Weighted Shift Knob | K&N CAI | Mishimoto AL Rad w/Zionsville AL Shroud
    Stewart HiPo Water Pump | Samco Hose Kit | 16" SPAL Puller Fan | Viper 5701LE Security
    E36 OBC is now open! Join the effort: BF.C Thread | openOBC Wiki

  13. #338
    Join Date
    May 2007
    Location
    US
    Posts
    942
    My Cars
    '94 325i / s13
    Ok, so I've got some code talking to my dme now.
    Code:
    querying...
    [10]<55><00><81>[7e]<0d><01><f6><33><31><34><30><30><32><31><36><32><30><03>got 0xd bytes
    [03][02][09][03]<0d><03><f6><33><32><36><37><35><33><37><36><32><31><03>got 0xd bytes
    type (f6)
    [03][04][09][03]<0a><05><f6><33><36><35><33><30><37><31><03>got 0xa bytes
    type (f6)
    [03][06][09][03]<06><07><f6><30><30><30><03>got 0x6 bytes
    type (f6)
    [03][08][09][03]<06><09><f6><34><36><31><03>got 0x6 bytes
    type (f6)
    [03][0a][09][03]<03><0b><09><03>got 0x3 bytes
    type (09)
    [06][0c][01][01][00][3b][03]<04><0d><fe><00><03>got 0x4 bytes
    [03][0e][09][03]good (type: 0xfe, length: 0x01 data: { 00 })
    That's a log of it spitting out some backwards ascii strings to identify itself, then me asking it to read the ram at 0x3b, and finally the reply. I was hoping to find rpm there. I don't know what it is, but rpm it is not.

    I'm now googling for some addresses while waiting to see what nuvola has already collected.

  14. #339
    Join Date
    Apr 2007
    Location
    Yorba Linda, CA
    Posts
    3,781
    My Cars
    1999 TiAg M3, 2003 E46M3
    Excellent work!

    Do you mind posting details on how you interfaced to the car? Schematic and code if you'd be so kind.
    The more people working on this in parallel, the better!

    As a side note: I found the perfect LED replacement for the incandescent bulbs in the obc.
    I used an RGB LED and powered on the green and red segments simultaneously;
    The result is a perfect match to the original bulbs.

    Eventually I plan to replace the amber filter in the display with a smoked white so we can use RGB LEDs to "tune" the color.

    We can use this to do things like turn the display a different color when some sensor reading goes out of bounds, etc.
    Last edited by m2pc; 06-24-2010 at 08:03 PM.

    1999 ///M3 TiAg | Heated Power Vaders | DDM Projector36 5000K 55W HIDs | DDM 3000K 35W HID Fogs
    DDM Smoked Corners | DDM Weighted Shift Knob | K&N CAI | Mishimoto AL Rad w/Zionsville AL Shroud
    Stewart HiPo Water Pump | Samco Hose Kit | 16" SPAL Puller Fan | Viper 5701LE Security
    E36 OBC is now open! Join the effort: BF.C Thread | openOBC Wiki

  15. #340
    Join Date
    May 2007
    Location
    US
    Posts
    942
    My Cars
    '94 325i / s13
    ram dump:
    Code:
    0x000   ff ff ff ff  ff ff 08 03   ad 02 73 7c  00 00 6a fb
    0x010   fb ff ff ff  ff ff ff ff   fa 00 70 e9  04 ff 1e 00
    0x020   00 01 14 00  28 00 01 00   00 00 ff ff  00 00 00 00
    0x030   00 00 00 00  00 00 00 00   00 00 00 00  00 00 00 00
    0x040   00 00 00 00  9a 12 9c d2   56 7a 00 20  c9 d5 06 00
    0x050   00 14 0f 00  00 30 05 01   00 8f 00 05  56 56 80 10
    0x060   00 00 00 00  ce 35 16 00   b2 e7 06 d1  8e d2 6a e9
    0x070   7e 42 00 00  00 00 06 00   2d 14 e2 04  06 40 00 00
    0x080   00 00 a9 8f  c4 09 0f 7f   b3 be f0 00  00 00 00 80
    0x090   00 00 00 00  00 00 00 00   00 00 1c 24  00 00 06 20
    0x0a0   9f 0c fb ff  4b 8c 00 00   18 00 00 00  00 00 00 00
    0x0b0   00 00 00 00  00 00 04 a0   00 80 02 00  00 08 08 00
    0x0c0   08 00 00 00  00 00 00 00   00 00 01 00  00 00 00 5f
    0x0d0   00 00 00 6f  00 3c 3c 7a   00 00 00 00  03 00 03 00
    0x0e0   00 00 c0 00  00 00 00 00   00 00 00 00  00 00 00 00
    0x0f0   00 00 00 00  84 23 ad 7a   f2 25 51 3c  6a 3b 28 00
    
    0x100   26 21 22 23  24 25 26 27   2a 29 2a 2b  2c 2d 2e 2f
    0x110   32 31 32 33  34 35 36 37   1a 19 1a 1b  1c 1d 1e 1f
    0x120   22 21 22 23  24 25 26 27   2a 29 2a 2b  2c 2d 2e 2f
    0x130   32 31 32 33  34 35 36 37   3a 39 3a 3b  3c 3d 3e 3f
    0x140   62 61 62 63  64 65 66 47   4a 49 4a 4b  4c 4d 4e 4f
    0x150   52 51 52 53  54 55 56 57   5a 59 5a 5b  5c 5d 5e 5f
    0x160   62 61 62 63  64 65 66 67   6a 69 6a 6b  6c 6d 6e 6f
    0x170   72 71 72 73  74 75 76 77   7a 79 7a 7b  7c 7d 7e 7f
    0x180   a2 a1 a2 a3  a4 a5 a6 a7   aa a9 aa ab  ac ad ae af
    0x190   b2 91 92 93  94 95 96 97   9a 99 9a 9b  9c 9d 9e 9f
    0x1a0   a2 a1 a2 a3  a4 a5 a6 a7   aa a9 aa ab  ac ad ae af
    0x1b0   b2 b1 b2 b3  b4 b5 b6 b7   ba b9 ba bb  bc bd be bf
    0x1c0   c2 c1 c2 c3  c4 c5 c6 c7   ca c9 ca cb  cc cd ce cf
    0x1d0   d2 d1 d2 d3  d4 d5 d6 d7   da 13 0d fe  d2 d1 d2 d3
    0x1e0   e2 e1 e2 e3  e4 e5 e6 e7   ea e9 ea eb  ec ed ee ef
    0x1f0   f2 f1 f2 f3  f4 f5 f6 f7   fa f9 fa fb  fc fd fe ff
    0x200   26 21 22 23  24 25 26 27   2a 29 2a 2b  2c 2d 2e 2f
    0x210   32 31 32 33  34 35 36 17   1a 19 1a 1b  1c 1d 1e 1f
    0x220   22 21 22 23  24 25 26 27   2a 29 2a 2b  2c 2d 2e 2f
    0x230   32 31 32 33  34 35 36 37   3a 39 3a 3b  3c 3d 3e 3f
    0x240   62 61 62 63  64 65 66 47   4a 49 4a 4b  4c 4d 4e 4f
    0x250   52 51 52 53  54 55 56 57   5a 59 5a 5b  5c 5d 5e 5f
    0x260   62 61 62 63  64 65 66 67   6a 69 6a 6b  6c 6d 6e 6f
    0x270   72 71 72 73  74 75 76 77   7a 79 7a 7b  7c 7d 7e 7f
    0x280   a2 a1 a2 a3  a4 a5 a6 a7   aa a9 aa ab  ac ad ae af
    0x290   b2 91 92 93  94 95 96 97   9a 99 9a 9b  9c 9d 9e 9f
    0x2a0   a2 a1 a2 a3  a4 a5 a6 a7   aa a9 aa ab  ac ad ae af
    0x2b0   b2 b1 b2 b3  b4 b5 b6 b7   ba b9 ba bb  bc bd be bf
    0x2c0   c2 c1 c2 c3  c4 c5 c6 c7   ca c9 ca cb  cc cd ce cf
    0x2d0   d2 d1 d2 d3  d4 d5 d6 d7   da d9 da db  dc dd de df
    0x2e0   e2 e1 e2 e3  e4 e5 e6 e7   ea e9 ea eb  ec ed ee ef
    0x2f0   f2 f1 f2 f3  f4 f5 f6 f7   fa f9 fa fb  fc fd fe ff
    0x300   22 21 22 23  24 25 26 27   2a 29 2a 2b  2c 2d 2e 2f
    0x310   32 31 32 33  34 35 36 17   1a 19 1a 1b  1c 1d 1e 1f
    0x320   22 21 22 23  24 25 26 27   2a 29 2a 2b  2c 2d 2e 2f
    0x330   32 31 32 33  34 35 36 37   3a 39 3a 3b  3c 3d 3e 3f
    0x340   62 61 62 63  64 65 66 47   4a 49 4a 4b  4c 4d 4e 4f
    0x350   52 51 52 53  54 55 56 57   5a 59 5a 5b  5c 5d 5e 5f
    0x360   62 61 62 63  64 65 66 67   6a 69 6a 6b  6c 6d 6e 6f
    0x370   72 71 72 73  74 75 76 77   7a 79 7a 7b  7c 7d 7e 7f
    0x380   a2 a1 a2 a3  a4 a5 a6 a7   aa a9 aa ab  ac ad ae af
    0x390   b2 91 92 93  94 95 96 97   9a 99 9a 9b  9c 9d 9e 9f
    0x3a0   a2 a1 a2 a3  a4 a5 a6 a7   aa a9 aa ab  ac ad ae af
    0x3b0   b2 b1 b2 b3  b4 b5 b6 b7   ba b9 ba bb  bc bd be bf
    0x3c0   c2 c1 c2 c3  c4 c5 c6 c7   ca c9 ca cb  cc cd ce cf
    0x3d0   d2 d1 d2 d3  d4 d5 d6 d7   da d9 da db  dc dd de df
    0x3e0   e2 e1 e2 e3  e4 e5 e6 e7   ea e9 ea eb  ec ed ee ef
    0x3f0   f2 f1 f2 f3  f4 f5 f6 f7   fa f9 fa fb  fc fd fe ff
    0x400   22 21 22 23  24 25 26 27   2a 29 2a 2b  2c 2d 2e 2f
    0x410   32 31 32 33  34 35 36 17   1a 19 1a 1b  1c 1d 1e 1f
    0x420   22 21 22 23  24 25 26 27   2a 29 2a 2b  2c 2d 2e 2f
    0x430   32 31 32 33  34 35 36 37   3a 39 3a 3b  3c 3d 3e 3f
    0x440   09 33 62 43  64 45 46 47   4a 49 4a 4b  4c 4d 4e 4f
    0x450   52 51 52 53  54 55 56 57   5a 59 5a 5b  5c 5d 5e 5f
    0x460   62 61 62 63  64 65 66 67   6a 69 6a 6b  6c 6d 6e 6f
    0x470   72 71 72 73  74 75 76 77   7a 79 7a 7b  7c 7d 7e 7f
    0x480   ff c1 a2 a3  a4 a5 a6 a7   aa a9 aa ab  ac ad ae af
    0x490   92 91 92 93  94 95 96 97   9a 99 9a 9b  9c 9d 9e 9f
    0x4a0   a2 a1 a2 a3  a4 a5 a6 a7   aa a9 aa ab  ac ad ae af
    0x4b0   b2 b1 b2 b3  b4 b5 b6 b7   ba b9 ba bb  bc bd be bf
    0x4c0   c2 c1 c2 c3  c4 c5 c6 c7   ca c9 ca cb  cc cd ce cf
    0x4d0   d2 d1 d2 d3  d4 d5 d6 d7   da d9 da db  dc dd de df
    0x4e0   e2 e1 e2 e3  e4 e5 e6 e7   ea e9 ea eb  ec ed ee ef
    0x4f0   f2 f1 f2 f3  f4 f5 f6 f7   fa f9 fa fb  fc fd fe ff
    0x500   22 21 22 23  24 25 26 27   2a 29 2a 2b  2c 2d 2e 2f
    0x510   32 31 32 33  34 35 36 17   1a 19 1a 1b  1c 1d 1e 1f
    0x520   22 21 22 23  24 25 26 27   2a 29 2a 2b  2c 2d 2e 2f
    0x530   32 31 32 33  34 35 36 37   3a 39 3a 3b  3c 3d 3e 3f
    0x540   09 33 62 63  64 65 46 47   4a 49 4a 4b  4c 4d 4e 4f
    0x550   52 51 52 53  54 55 56 57   5a 59 5a 5b  5c 5d 5e 5f
    0x560   62 61 62 63  64 65 66 67   6a 69 6a 6b  6c 6d 6e 6f
    0x570   72 71 72 73  74 75 76 77   7a 79 7a 7b  7c 7d 7e 7f
    0x580   00 d6 a2 a3  a4 a5 a6 a7   aa a9 aa ab  ac ad ae af
    0x590   92 91 92 93  94 95 96 97   9a 99 9a 9b  9c 9d 9e 9f
    code:

    This is very ugly and nonportable, but it's an accurate record of what I'm doing. It also includes a lot of less relevant code. I'll have more finished code later.
    Code:
    #include <stdint.h>
    #include <stdio.h>
    
    #include "board.h"
    #include "dbgu.h"
    #include "common/swi.h"
    
    #define nop()  __asm__ __volatile__("nop")
    
    #define RTTC_INTERRUPT_LEVEL   0
    #define PIV_200_MS             600000  //* 200 ms for 48 MHz
    
    #define MCK 48054857
    #define BAUD 115200
    
    #define LED_A      (1<<8)
    
    #define CLKOUT (1<<30)
    #define LCD_UNK0 (1<<28)
    #define LCD_REFRESH (1<<26)
    #define LCD_DATA (1<<24)
    #define LCD_CLOCK (1<<22)
    #define LCD_SELECT (1<<20)
    #define LCD_STOP (1<<14)
    #define LCD_UNK1 (1<<18)
    
    #define SERIAL_RX AT91C_PA5_RXD0
    #define SERIAL_TX AT91C_PA6_TXD0
    
    #define K_LINE_RX AT91C_PA9_DRXD
    #define K_LINE_TX AT91C_PA10_DTXD
    #define L_LINE (0<<0)
    
    #define STALK_BUTTON AT91C_PIO_PA12
    #define FUEL_CONS AT91C_PIO_PA4
    #define VBAT AT91C_ADC_CH5
    
    #define REMOTE_TX FUEL_CONS
    #define REMOTE_RX STALK_BUTTON
    
    
    #define OBD_ADDR_DME 0x10
    
    #include <string.h>
    
    volatile AT91PS_PMC pPMC = AT91C_BASE_PMC;
    volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;
    volatile AT91PS_AIC pAIC = AT91C_BASE_AIC;
    volatile AT91PS_TC pTC0 = AT91C_BASE_TC0;
    volatile AT91PS_TC pTC1 = AT91C_BASE_TC1;
    volatile AT91PS_USART pUSART0 = AT91C_BASE_US0;
    volatile AT91PS_USART pUSART1 = AT91C_BASE_US1;
    volatile AT91PS_DBGU pDBGU = AT91C_BASE_DBGU;
    volatile AT91PS_ADC pADC = AT91C_BASE_ADC;
    
    int voltagewhole;
    int voltagepart;
    
    char clock_buffer[5] = "131v";
    char lcd_buffer[40] = "";
    int freeze_lcd = 0;
    unsigned int freeze_clock = 0;
    int clock_type = 0;
    
    void lcd_update();
    
    void delayhus(unsigned int hus)
    {
       while(hus--)
       {
          nop();
          nop();
          nop();
          nop();
          nop();
          nop();
       }
    }
    
    void delayus(unsigned int us)
    {
       while(us--)
       {
    //       for(volatile int i = 0; i < 1; i++);
    
          nop();
          nop();
          nop();
          nop();
          nop();
          nop();
          nop();
          nop();
    
       }
    }
    
    void delayms(unsigned int ms)
    {
       unsigned int i;
       while(ms--)
       {
          //       delayus(1000);
          i = 2000;
          while(i--)
             nop();
       }
    }
    
    void int_pit(void)
    {
    	volatile uint32_t status;
    	// Interrupt Acknowledge
    	status = AT91C_BASE_PITC->PITC_PIVR;
    
       if(pPIO->PIO_ODSR & LED_A)
          pPIO->PIO_CODR = LED_A;
       else
          pPIO->PIO_SODR = LED_A;
    
    
       int voltage = pADC->ADC_CDR5;
       pADC->ADC_CR = AT91C_ADC_START;
    
       voltagewhole = voltage * 18.4 / 1023;
       voltagepart = voltage * 18.4 / 1023 * 10;
       voltagepart = voltagepart % 10;
    
    
    //    printf("(%iv%i)\n", voltagewhole, voltagepart);
    
    //    float voltagef = (float)voltage * 15.51 / 1023;
    
    
    //    sprintf(clockstring, "%.1f", voltagef);
    
       if(!freeze_clock)
       {
          switch(clock_type)
          {
             case 0:
    //             sprintf(clockstring, "%i", voltage);
                sprintf(clock_buffer, "%iv%i", voltagewhole, voltagepart);
                break;
             case 1:
                sprintf(clock_buffer, "29C ");
                break;
             case 2:
                if(pPIO->PIO_PDSR & FUEL_CONS)
                   clock_buffer[3] = '1';
                else
                   clock_buffer[3] = '0';
    
                if(pPIO->PIO_PDSR & STALK_BUTTON)
                   clock_buffer[2] = '1';
                else
                   clock_buffer[2] = '0';
                break;
    
             default:
                clock_type = 0;
          }
       }
       else
          freeze_clock--;
    
       if(!freeze_lcd)
          sprintf(lcd_buffer, "EXT:29C  INT:31C");
       else
          freeze_lcd--;
    
       lcd_update();
    }
    
    
    static void int_timer_clock(void)
    {
       pTC1->TC_SR;
    
       if(pPIO->PIO_ODSR & CLKOUT)
          pPIO->PIO_CODR = CLKOUT;
       else
          pPIO->PIO_SODR = CLKOUT;
    }
    
    static void int_pio(void)
    {
       unsigned int before = pPIO->PIO_ISR;
       delayms(20);
    
       if(before & STALK_BUTTON && !(pPIO->PIO_PDSR & STALK_BUTTON))
       {
          static int status = 0;
    
          status++;
          if(status > 2)
             status = 0;
    
          switch(status)
          {
             case 0:
                sprintf(clock_buffer, "131v");
                break;
             case 1:
                sprintf(clock_buffer, "29C ");
                break;
             case 2:
                sprintf(clock_buffer, "0342");
                break;
          }
    
          lcd_update();
    
          while(!(pPIO->PIO_PDSR & STALK_BUTTON));
       }
    }
    
    void init_lcd(void)
    {
       pPMC->PMC_PCER = (1 << AT91C_ID_PIOA);
    
       pPIO->PIO_PPUDR = CLKOUT | LCD_CLOCK | LCD_DATA | LCD_SELECT | LCD_REFRESH | LCD_STOP | LCD_UNK0 | LCD_UNK1;
       pPIO->PIO_MDER = CLKOUT | LCD_CLOCK | LCD_DATA | LCD_SELECT | LCD_REFRESH | LCD_STOP | LCD_UNK0 | LCD_UNK1;
       pPIO->PIO_PER = CLKOUT | LCD_CLOCK | LCD_DATA | LCD_SELECT | LCD_REFRESH | LCD_STOP | LCD_UNK0 | LCD_UNK1;
       pPIO->PIO_CODR = CLKOUT | LCD_CLOCK | LCD_DATA | LCD_SELECT | LCD_REFRESH | LCD_STOP | LCD_UNK0 | LCD_UNK1;
       pPIO->PIO_SODR = LCD_DATA | LCD_SELECT;
       pPIO->PIO_OER = CLKOUT | LCD_CLOCK | LCD_DATA | LCD_SELECT | LCD_REFRESH | LCD_STOP | LCD_UNK0 | LCD_UNK1;
    
       pAIC->AIC_IDCR = 1 << AT91C_ID_TC1;
       pAIC->AIC_SVR[AT91C_ID_TC1] = (unsigned)&int_timer_clock;
       pAIC->AIC_SMR[AT91C_ID_TC1] = AT91C_AIC_PRIOR_HIGHEST | AT91C_AIC_SRCTYPE_HIGH_LEVEL;
       pPMC->PMC_PCER = (1 << AT91C_ID_TC1);
       pTC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_CPCTRG;
       pTC1->TC_RC = 156;
       pTC1->TC_IER = AT91C_TC_CPCS;
       pTC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
       pAIC->AIC_ICCR = (1 << AT91C_ID_TC1);
       pAIC->AIC_IECR = (1 << AT91C_ID_TC1);
    
    }
    
    void init_security(void)
    {
       pPMC->PMC_PCER = (1 << AT91C_ID_PIOA);
    
       pPIO->PIO_ODR = REMOTE_RX | REMOTE_TX;
       pPIO->PIO_PPUDR = REMOTE_TX | REMOTE_RX;
       pPIO->PIO_MDER = REMOTE_TX;
       pPIO->PIO_SODR = REMOTE_TX;
       pPIO->PIO_PER = REMOTE_RX | REMOTE_TX;
       pPIO->PIO_OER = REMOTE_TX;
    
    //    pAIC->AIC_IDCR = 1 << AT91C_ID_PIOA;
    //    pAIC->AIC_SVR[AT91C_ID_PIOA] = (unsigned int)&int_remote;
    //    pAIC->AIC_SMR[AT91C_ID_PIOA] = AT91C_AIC_PRIOR_HIGHEST;
    //    pPIO->PIO_IER = REMOTE_TX;
    //    pPIO->PIO_ISR;
    //    pAIC->AIC_ICCR = (1 << AT91C_ID_PIOA);
    //    pAIC->AIC_IECR = (1 << AT91C_ID_PIOA);
    }
    
    void init_input(void)
    {
       pPMC->PMC_PCER = (1 << AT91C_ID_PIOA);
    
    //    pPIO->PIO_ODR = STALK_BUTTON | FUEL_CONS;
    //    pPIO->PIO_PPUDR = STALK_BUTTON | FUEL_CONS | VBAT;
    //    pPIO->PIO_IFER = STALK_BUTTON;
    //    pPIO->PIO_PER = STALK_BUTTON | FUEL_CONS;
    
       pPIO->PIO_PDR = VBAT;
    
    
    //    pAIC->AIC_IDCR = 1 << AT91C_ID_PIOA;
    //    pAIC->AIC_SVR[AT91C_ID_PIOA] = (unsigned int)&int_pio;
    //    pAIC->AIC_SMR[AT91C_ID_PIOA] = AT91C_AIC_PRIOR_LOWEST;
    //    pPIO->PIO_IER = STALK_BUTTON;
    //    pAIC->AIC_ICCR = (1 << AT91C_ID_PIOA);
    //    pAIC->AIC_IECR = (1 << AT91C_ID_PIOA);
    
    
       pADC->ADC_MR = AT91C_ADC_TRGEN_DIS | AT91C_ADC_TRGSEL_TIOA0 | AT91C_ADC_LOWRES_10_BIT | AT91C_ADC_SLEEP_NORMAL_MODE | AT91C_ADC_PRESCAL | AT91C_ADC_STARTUP | AT91C_ADC_SHTIM;
       pADC->ADC_CHER = VBAT;
       pADC->ADC_CR = AT91C_ADC_START;
    
    }
    
    void init_obd(void)
    {
       pPMC->PMC_PCER = 1 << AT91C_ID_PIOA | 1 << AT91C_ID_US0;
    
       pPIO->PIO_PPUDR = K_LINE_RX | K_LINE_TX | L_LINE;
       pPIO->PIO_MDDR = K_LINE_RX | K_LINE_TX | L_LINE;
       pPIO->PIO_ODR = K_LINE_RX;
    
       pPIO->PIO_ASR = K_LINE_TX | K_LINE_RX;
       pPIO->PIO_PDR = K_LINE_TX | K_LINE_RX;
    //    pPIO->PIO_PER = K_LINE_RX;
       //    pPIO->PIO_SODR = L_LINE;
    
    
    //    pUSART0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
    //    pUSART0->US_MR = AT91C_US_USMODE_NORMAL | AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_7_BITS | AT91C_US_PAR_ODD | AT91C_US_NBSTOP_1_BIT;
    //    pUSART0->US_BRGR = MCK/16/6;
    //    pUSART0->US_CR = AT91C_US_TXEN;
    
       pDBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
       pDBGU->DBGU_MR = AT91C_US_USMODE_NORMAL | AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT;
       pDBGU->DBGU_BRGR = MCK/16/9600;
       pDBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN;
    
    }
    
    static void init(void)
    {
    	// Enable User Reset and set its minimal assertion to 960 us
    	AT91C_BASE_RSTC->RSTC_RMR = AT91C_RSTC_URSTEN | (0x4<<8) | (unsigned int)(0xA5<<24);
    
    
       pPMC->PMC_PCER = (1 << AT91C_ID_PIOA);
    
       AT91F_DBGU_Init();
    
       init_input();
       init_security();
       init_lcd();
       init_obd();
    
    
       pPIO->PIO_MDDR = LED_A;
       pPIO->PIO_PER = LED_A;
       pPIO->PIO_CODR = LED_A;
       pPIO->PIO_OER = LED_A;
    
    
       pAIC->AIC_IDCR = 1 << AT91C_ID_SYS;
       pAIC->AIC_SVR[AT91C_ID_SYS] = (unsigned int)&int_pit;
       pAIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE | 5;
       AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN | AT91C_PITC_PITIEN | (MCK/16/1000*200);
       pAIC->AIC_ICCR = 1 << AT91C_ID_SYS;
       pAIC->AIC_IECR = 1 << AT91C_ID_SYS;
    
    
    }
    
    int dbgu_putc(int c)
    {
       while(!(AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXRDY));
       return(AT91C_BASE_DBGU->DBGU_THR = c);
    }
    
    int dbgu_getc(void)
    {
       while(!(AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_RXRDY));
       return(AT91C_BASE_DBGU->DBGU_RHR & 0xff);
    }
    
    int uart0_putc(int c)
    {
       while(!(AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY));
       return(AT91C_BASE_US0->US_THR = c);
    }
    
    // int uart0_getc(void)
    // {
    //    while(!(AT91C_BASE_US0->US_CSR & AT91C_US_RXRDY));
    //    return(AT91C_BASE_US0->US_RHR & 0xff);
    // }
    
    int obd_send(char* data, int bytes)
    {
       for(int byte = 0; byte < bytes; byte++)
       {
    //       printf("[%02x]", data[byte]);
          dbgu_putc(data[byte]);
          while(!(pDBGU->DBGU_CSR & AT91C_US_TXRDY));
          delayus(1000);
          if(!(pDBGU->DBGU_CSR & AT91C_US_RXRDY))
          {
             printf("!");
             return 0;
          }
          char c = dbgu_getc();
          if(c != data[byte])
          {
             printf("?%02x?", c);
             return 0;
          }
    
          if(byte == bytes - 1)
             return bytes;
    
          double wait = 0;
          for(wait = 0; wait < 500000; wait++)
          {
             if(!(pDBGU->DBGU_CSR & AT91C_US_RXRDY))
                continue;
             char c = dbgu_getc();
    //          printf("<%02x>", c);
             if(c != (data[byte] ^ 0xff))
             {
                printf("?%02x?", c);
                return 0;
             }
             else
                break;
          }
          if(wait == 500000)
             printf("*");
       }
       return bytes;
    }
    
    int obd_get(char* data, int length)
    {
       int bytes = 0;
       for(double wait = 0; wait < 500000; wait++)
       {
          if(!(pDBGU->DBGU_CSR & AT91C_US_RXRDY))
             continue;
          char c = dbgu_getc();
          data[bytes]  = c;
    //       printf("<%02x>", c);
    
          if(bytes == data[0] || bytes == length-1)
          {
    //          printf("got 0x%x bytes\n", bytes);
             data[bytes+1] = '\0';
             return bytes;
          }
    
    //       printf("[%02x]", data[bytes] ^ 0xff);
          dbgu_putc(data[bytes] ^ 0xff);
          while(!(pDBGU->DBGU_CSR & AT91C_US_TXRDY));
          delayus(1000);
          if(!(pDBGU->DBGU_CSR & AT91C_US_RXRDY))
          {
             printf("!");
             return 0;
          }
          c = dbgu_getc();
          if(c != (data[bytes] ^ 0xff))
          {
             printf("?%02x?", c);
             return 0;
          }
    
    //       bytes++;
    
    
          bytes++;
       }
       return bytes;
    }
    
    int obd_init_l(int address, int keycode)
    {
       char reply[10];
    
       delayms(3000);
    
       pDBGU->DBGU_CR = AT91C_US_RXDIS;
    
       pPIO->PIO_SODR = K_LINE_TX;
       pPIO->PIO_OER = K_LINE_TX;
       pPIO->PIO_PER = K_LINE_TX;
    
    
       pPIO->PIO_CODR = K_LINE_TX;
       delayms(1);
       if(pPIO->PIO_PDSR & K_LINE_RX)
       {
          printf("not low!\n");
          freeze_lcd = 65500;
          sprintf(lcd_buffer, "not low!!");
          return 0;
       }
       pPIO->PIO_SODR = K_LINE_TX;
       delayms(1);
       if(!(pPIO->PIO_PDSR & K_LINE_RX))
       {
          printf("not high!\n");
          freeze_lcd = 65500;
          sprintf(lcd_buffer, "not high!!");
          return 0;
       }
    
    
       bool parity = 1;
    
       printf("[%02x]", address);
       freeze_clock = 5;
       sprintf(clock_buffer, "0x%02x", address);
    
       pPIO->PIO_OER = K_LINE_TX;
    
       //start bit
       pPIO->PIO_CODR = K_LINE_TX;
       delayms(200);
       for(int bit = 0; bit < 7; bit++)
       {
          if(address & (1 << bit))
          {
             pPIO->PIO_SODR = K_LINE_TX;
             parity ^= 1;
          }
          else
             pPIO->PIO_CODR = K_LINE_TX;
          delayms(200);
       }
       //parity bit
       if(parity)
          pPIO->PIO_SODR = K_LINE_TX;
       else
          pPIO->PIO_CODR = K_LINE_TX;
       delayms(200);
       //stop bit
       pPIO->PIO_SODR = K_LINE_TX;
       delayms(200);
    
    
       pPIO->PIO_ODR = K_LINE_TX;
       pPIO->PIO_PDR = K_LINE_TX;
    
       pDBGU->DBGU_CR = AT91C_US_RXEN;
    
       int bytes = 0;
       for(double wait = 0; wait < 500000; wait++)
       {
          if(!(pDBGU->DBGU_CSR & AT91C_US_RXRDY))
             continue;
          char c = dbgu_getc();
          reply[bytes]  = c;
          printf("<%02x>", c);
    
          if(reply[0] == 0x55 && bytes == 2)
          {
             printf("[%02x]", reply[bytes] ^ 0xff);
             dbgu_putc(reply[bytes] ^ 0xff);
             while(!(pDBGU->DBGU_CSR & AT91C_US_TXRDY));
             delayus(1000);
             if(!(pDBGU->DBGU_CSR & AT91C_US_RXRDY))
             {
                printf("!");
                return 0;
             }
             c = dbgu_getc();
             if(c != (reply[bytes] ^ 0xff))
             {
                printf("?%02x?", c);
                return 0;
             }
             if(reply[1] == (keycode >> 8) && reply[2] == (keycode & 0xff))
                return 1;
             else
                return 0;
          }
          bytes++;
       }
       return 0;
    }
    
    int obd_query(int command, char* data, int length, int* reply_type, char* reply_data, int* reply_length)
    {
       char input[64];
       int seq = 0;
       char ack[4] = {0x03, 0x00, 0x09, 0x03};
    
       if(!obd_init_l(OBD_ADDR_DME, 0x81))
          return 0;
    
       if(!obd_get(input, sizeof(input)))
          return 0;
       seq = input[1];
    
       while(input[2] != 0x09)
       {
          ack[1] = ++seq;
          if(!obd_send(ack, 4))
             return 0;
    
          if(!obd_get(input, sizeof(input)))
             return 0;
          seq = input[1];
    
    //       printf("type (%02x)\n", input[2]);
       }
    
       char query[64];
       query[0] = length + 3;
       query[1] = ++seq;
       query[2] = command;
       memcpy(query+3, data, length);
       query[query[0]] = 0x03;
    
       if(!obd_send(query, length+4))
          return 0;
    
       if(!obd_get(input, sizeof(input)))
          return 0;
    
       seq = input[1];
       ack[1] = ++seq;
       obd_send(ack, 4);
    
       *reply_type = (int)input[2];
       *reply_length = input[0] - 3;
       memcpy(reply_data, input+3, *reply_length);
    
    //    while(input[input[0]] == 0xc8)
    //    {
    //       if(!obd_get(input, sizeof(input)))
    //          return 0;
    //       
    //       seq = input[1];
    //       ack[1] = ++seq;
    //       obd_send(ack, 4);
    // 
    //       *reply_length += input[0] - 3;
    //       memcpy(reply_data + (*reply_length - input[0] - 3), input+3, *reply_length);
    //    }
    
       return 1;
    
    }
    
    void obd_test(void)
    {
       for(int address = 0; address < 0x1000; address += 0x10)
       {
          printf("\n%iv%i\n", voltagewhole, voltagepart);
    
          printf("querying...\n");
          int type;
          char data[64];
          int length;
          char args[16] = {0x10, address >> 8, address & 0xff};
          if(!obd_query(0x01, args, 0x03, &type, data, &length))
          {
             address -= 0x10;
             if(address < -0x10)
                address = 0;
             printf("bad\n");
             freeze_lcd = 100;
             sprintf(lcd_buffer, "RPM: bad");
          }
          else
          {
             char string[128] = "";
             for(int i = 0; i < length && i < 8; i++)
             {
                char buffer[10];
                sprintf(buffer, "%02x ", data[i]);
                strcat(string, buffer);
             }
    //          printf("good (type: 0x%02x, length: 0x%02x data: { %s})\n", type, length, string);
    
             int byte = 0;
    //          for(int row = 0; row < 0x10; row++)
    //          {
    //             if(byte >= length)
    //                break;
                printf("\n0x%02x ", address);
                for(int col = 0; col < 0x10; col++)
                {
                   if(byte >= length)
                      break;
                   printf("%02x ", data[byte++]);
                }
                printf("\n");
    //          }
    
          }
    
    //       delayms(5000);
       }
    
       while(1);
    }
    
    void lcd_putc(unsigned char c)
    {
       int bit = 8;
       while(bit--)
       {
          if(c & (1 << bit))
             pPIO->PIO_SODR = LCD_DATA;
          else
             pPIO->PIO_CODR = LCD_DATA;
          delayhus(1);
          pPIO->PIO_SODR = LCD_CLOCK;
          delayhus(1);
          pPIO->PIO_CODR = LCD_CLOCK;
       }
       pPIO->PIO_SODR = LCD_DATA;
       delayus(1);
       //    if(c != 8)
       //    {
          pPIO->PIO_SODR = LCD_STOP;
          delayhus(1);
          pPIO->PIO_CODR = LCD_STOP;
          delayus(1);
          //    }
    }
    
    void lcd_update()
    {
       if(lcd_buffer[strlen(lcd_buffer)-1] != ' ' && strlen(lcd_buffer) / 2 < 10)
       {
          for(int i = strlen(lcd_buffer) / 2; i < 10; i++)
             strcat(lcd_buffer, " ");
       }
       char buffer[80];
       sprintf(buffer, "                    %s%s    ", lcd_buffer, clock_buffer);
       char *output = buffer;
    
       pPIO->PIO_CODR = LCD_SELECT;
       delayhus(1);
       while(*output != '\0')
       {
          lcd_putc(*output++);
       }
    
       delayhus(1);
       pPIO->PIO_SODR = LCD_REFRESH;
       delayus(1);
       pPIO->PIO_CODR = LCD_REFRESH;
       delayhus(1);
       pPIO->PIO_SODR = LCD_SELECT;
       delayhus(1);
    
    }
    
    void remote_send(int data)
    {
    #define CLOCK_WIDTH 800
    
    //    pPIO->PIO_OER = REMOTE_TX;
    
    
    
       for(int repeat = 0; repeat < 10; repeat++)
       {
          pPIO->PIO_CODR = REMOTE_TX;
          delayus(4300);
    
          for(int bit = 30; bit; )
          {
             bit--;
    
             pPIO->PIO_CODR = REMOTE_TX;
             delayus(CLOCK_WIDTH);
             pPIO->PIO_SODR = REMOTE_TX;
             delayus(CLOCK_WIDTH);
    
             if(data & (1<<bit))
             {
                delayus(CLOCK_WIDTH + 400);
       //          pPIO->PIO_SODR = REMOTE_TX;
       //          delayus(CLOCK_WIDTH);
       //          pPIO->PIO_CODR = REMOTE_TX;
             }
             else
             {
    
             }
          }
          pPIO->PIO_CODR = REMOTE_TX;
          delayus(CLOCK_WIDTH);
    
       }
       pPIO->PIO_SODR = REMOTE_TX;
       delayus(CLOCK_WIDTH);
    
    //    pPIO->PIO_ODR = REMOTE_TX;
    }
    
    int main(void)
    {
    	init();
    
    	IntEnable();  // thu swi-call
    
    
       pPIO->PIO_CODR = LCD_UNK0 | LCD_UNK1;
       delayus(10);
       pPIO->PIO_SODR = LCD_UNK0 | LCD_UNK1;
       delayus(10);
    
    
       delayms(1000);
    
       printf("\nstart\n");
       printf("%iv%i\n", voltagewhole, voltagepart);
    
    
       while(1)
       {
         obd_test();
         delayms(1000);
       }
    
    
    #define CHANNELS 1
    #define SAMPLESIZE 440
    #define SAMPLE_RATE_HZ 10000
    #define DELAY (1000000 / SAMPLE_RATE_HZ)
    #define HEIGHT 6
    
    
       int intsave = pAIC->AIC_IMR;
    //    pAIC->AIC_IDCR = 0xff;
    
       int period = 0;
       int periodd = 0;
    
       while(0)
       {
    
    
          for(int clocks = 0; clocks < 7;)
          {
             int timeup = 0;
             int timedown = 0;
             while(!(pPIO->PIO_PDSR & REMOTE_RX));
             while(pPIO->PIO_PDSR & REMOTE_RX)
             {
                timeup++;
                delayus(5);
             }
             if(!(timeup > 100 && timeup < 140))
             {
                clocks = 0;
                period = 0;
                periodd = 0;
                continue;
             }
             while(!(pPIO->PIO_PDSR & REMOTE_RX))
             {
                timedown++;
                delayus(5);
             }
             if(!(timedown > 60 && timedown < 100))
             {
                clocks = 0;
                period = 0;
                periodd = 0;
                continue;
             }
    //          if(clocks > 3)
    //          {
    //             char buffer[20];
    //             sprintf(buffer, "%i %i\r\n", timeup, timedown);
    //             debug(buffer);
    //          }
             clocks++;
             period += timeup;
             periodd += timedown;
    
          }
          intsave = pAIC->AIC_IMR;
          pAIC->AIC_IDCR = 0xff;
          period /= 7;
    //       periodd /= 7;
    
    
          while((pPIO->PIO_PDSR & REMOTE_RX));
          while(!(pPIO->PIO_PDSR & REMOTE_RX));
    
    
          int input = 0;
    
          for(int bit = 24; bit;)
          {
             bit--;
             delayus(5 * periodd / 4);
             if(pPIO->PIO_PDSR & REMOTE_RX)
               input += (1 << bit);
             while(pPIO->PIO_PDSR & REMOTE_RX);
             while(!(pPIO->PIO_PDSR & REMOTE_RX));
          }
    
    
    #define ALARM_REMOTE_TEST 0x00
    #define ALARM_ARM 0x01
    #define ALARM_DISARM 0x02
    #define ALARM_ARMED_DOOR 0x03
    #define ALARM_DISARMED 0x04
    #define ALARM_ALARM_SHOCK 0x05
    #define ALARM_ALARM_DOOR 0x06
    #define ALARM_ENGINE_STOP 0x07
    #define ALARM_TRUNK_OPEN 0x08
    #define ALARM_ENGINE_STOP 0x09
    #define ALARM_ENGINE_FLASH 0x0a
    #define ALARM_ENGINE_START 0x0b
    #define ALARM_CALL 0x0c
    #define ALARM_SIREN_OFF 0x0d
    #define ALARM_SIREN_ON 0x0e
    #define ALARM_ARM_DISARMED 0x0f
    #define ALARM_AUX2 0x12
    #define ALARM_SHOCK_WARN 0x14
    #define ALARM_SIREN_HD 0x15
    #define ALARM_SIREN_PAN 0x1a
    #define ALARM_AUX1 0x1b
    #define ALARM_ENGINE_START 0x1c
    #define ALARM_ON 0x1d
    #define ALARM_OFF 0x1e
    #define ALARM_VALET_OFF 0x1f
    #define ALARM_VALET_ON 0x20
    #define ALARM_ALARM_TRUNK 0x23
    #define ALARM_SHOCK_OFF 0x30
    #define ALARM_NUMBER 0x31
    #define ALARM_TEMP 0x32
    
    #define ALARM_IN_1_1 0x01
    #define ALARM_IN_1_2 0x03
    #define ALARM_IN_1_3 0x04
    #define ALARM_IN_1_4 0x02
    #define ALARM_IN_2_1 0x00
    #define ALARM_IN_2_2 0x0f
    #define ALARM_IN_2_3 0x0a
    #define ALARM_IN_2_4 0x0c
    #define ALARM_IN_3_1 0x0
    #define ALARM_IN_3_2 0x01
    #define ALARM_IN_3_3 0x02
    #define ALARM_IN_3_4 0x01
    #define ALARM_IN_4_1 0x00
    #define ALARM_IN_4_2 0x07
    #define ALARM_IN_4_3 0x05
    #define ALARM_IN_4_4 0x06
    #define ALARM_IN_PANIC 0x05
    #define ALARM_IN_STATUS 0x07
    #define ALARM_IN_DEG 0x09
    #define ALARM_IN_VALET 0x0b
    #define ALARM_IN_CHIRP 0x06
    #define ALARM_IN_PASIVE 0x08
    #define ALARM_IN_COLD 0x04
    #define ALARM_IN_HOT 0x05
    
    #define ALARM_ADDR1 (0x8c1 << 18)
    #define ALARM_ADDR2 (0xa53 << 6)
    
    
    
          static int send = 0x8c1 << 18 | 0x8c1 << 6 | ALARM_VALET_ON;
    
          char buffer[20];
          sprintf(buffer, "0x %03x %02x %02x  ", input >> 12, input >> 6 & 0x3f, input & 0x3f);
          debug(buffer);
    
          freeze_lcd = 25;
          pAIC->AIC_IECR = intsave;
    
    
          switch(input & 0x3f)
          {
             case ALARM_IN_1_1:
                sprintf(lcd_buffer, "ARMED");
                freeze_clock = 10;
                sprintf(clock_buffer, "0x%02x", send & 0x3f);
                remote_send(ALARM_ADDR1 | ALARM_ARM);
                send--;
                break;
    
             case ALARM_IN_1_2:
                sprintf(lcd_buffer, "DISARMED");
                freeze_clock = 10;
                sprintf(clock_buffer, "0x%02x", send & 0x3f);
                remote_send(ALARM_ADDR1 | ALARM_DISARM);
                send++;
                break;
    
             case ALARM_IN_1_3:
                sprintf(lcd_buffer, "AUX1");
                remote_send(ALARM_ADDR1 | ALARM_AUX1);
                break;
    
             case ALARM_IN_1_4:
                sprintf(lcd_buffer, "ENGINE STOP");
                remote_send(ALARM_ADDR1 | ALARM_ENGINE_STOP);
                break;
    
             case ALARM_IN_2_3:
                sprintf(lcd_buffer, "SENDING 0x%02x", send & 0x3f);
                remote_send(send);
                break;
    
             case ALARM_IN_2_4:
                sprintf(lcd_buffer, "ENGINE START");
                remote_send(ALARM_ADDR1 | ALARM_ENGINE_START);
                break;
    
             case ALARM_IN_4_4:
                sprintf(lcd_buffer, "REMOTE LCD TEST");
                remote_send(ALARM_ADDR1 | ALARM_REMOTE_TEST);
                break;
    
             case ALARM_IN_2_2:
                clock_type++;
                break;
    
          }
    
    //       sprintf(clockstring, "0x%02x", send & 0x3f);
          printf("0x %03x %03x %02x\r\n", send >> 18, send >> 6 & 0xfff, send & 0x3f);
    
          lcd_update();
    
          delayms(300);
    //       remote_send(send);
    
    
    //       intsave = pAIC->AIC_IMR;
    //       pAIC->AIC_IDCR = 0xff;
    
    
       }
       while(1)
       {
    
          while(!(pPIO->PIO_PDSR & K_LINE_RX));
    
          bool samples[2][SAMPLESIZE];
    
          for(int i = 0; i < SAMPLESIZE; i++)
          {
             int sample = pPIO->PIO_PDSR;
    
             if(sample & K_LINE_RX)
                samples[0][i] = 1;
             else
                samples[0][i] = 0;
    
             if(sample & REMOTE_RX)
                samples[1][i] = 1;
             else
                samples[1][i] = 0;
    
             delayus(DELAY);
          }
    
    //       for(int i = 0; i < 3500; i++)
    //       {
    //          if(samples[i])
    //             debug("1");
    //          else
    //             debug("0");
    //       }
    //       debug("\r\n\n");
    
          printf("rate: %iHz samples: %i time: %ims sample width: %ius\r\n", SAMPLE_RATE_HZ, SAMPLESIZE, SAMPLESIZE / (SAMPLE_RATE_HZ / 1000), DELAY);
    
          for(int channel = 0; channel < CHANNELS; channel++)
          {
    
             for(int i = 0; i < SAMPLESIZE; i++)
             {
                if(samples[channel][i])
                   debug("_");
                else
                   debug(" ");
             }
             debug("\r\n");
             for(int n = 0; n < HEIGHT; n++)
             {
                for(int i = 0; i < SAMPLESIZE; i++)
                {
                   if(samples[channel][i] && !samples[channel][i+1])
                      debug("|");
                   else if(!samples[channel][i] && samples[channel][i+1])
                      debug("|");
                   else
                      debug(" ");
                }
                debug("\r\n");
             }
             for(int i = 0; i < SAMPLESIZE; i++)
             {
                if(samples[channel][i] && !samples[channel][i+1])
                   debug("|");
                else if(!samples[channel][i] && samples[channel][i+1])
                   debug("|");
                else if(!samples[channel][i])
                   debug("_");
                else
                   debug(" ");
             }
             printf("\r\nchannel: %i\r\n\n", channel);
          }
          printf("rate: %iHz samples: %i time: %ims sample width: %ius\r\n\r\n", SAMPLE_RATE_HZ, SAMPLESIZE, SAMPLESIZE / (SAMPLE_RATE_HZ / 1000), DELAY);
          delayms(500);
    
       }
    
       return(0);
    }
    schematic: (attached)

    I'll add values and double check it next time I bring my obc back inside.

    My two good sources thus far:
    http://www.cardiagnostics.be/GT1-MOD...ocol KW-71.htm (100% pertinent to my 94 325 as far as I can tell, but it's a horrid translation)
    http://www.hex.co.za/vaginfo/index.html (dissimilar hardware interface and addresses, but the transaction structure is right)
    Attached Images Attached Images
    Last edited by benemorius; 09-19-2012 at 06:44 AM.

  16. #341
    Join Date
    May 2007
    Location
    US
    Posts
    942
    My Cars
    '94 325i / s13
    Quote Originally Posted by m2pc View Post
    Eventually I plan to replace the amber filter in the display with a smoked white so we can use RGB LEDs to "tune" the color.

    We can use this to do things like turn the display a different color when some sensor reading goes out of bounds, etc.
    I like!

    Speaking of other additional features, I wonder what's stopping the boosted crowd from using their openobc to do their retuning at this point.
    Last edited by benemorius; 06-24-2010 at 10:00 PM. Reason: Automerged Doublepost

  17. #342
    Join Date
    Jul 2009
    Location
    Toronto, Ontario, Canada
    Posts
    311
    My Cars
    328is,Integra TypeR
    is it possible to make a message and a beeping noise as soon as the car over heats by say 10-25 degrees.... would help alot! also if there is a low tire pressure warning,

    And if you can add a Police scanner to it xD... now that I WOULD BUY FOR SURE!
    e39 M5 - LED Angel eye upgrade, E60 SSK with ZHP knob DSSR and clutch stop, Hotrod Scott X-pipe and exhaust, Dinan air ducts, K&N Drop-in filter, Beastpower Swaybar mounts, X5 Thrust arm bushings, Rogue Tranny mounts, Bilstein pss9 kit, SS Headers, Spal electric fan, DSW Subwoofer and overhead trunk enclosure

    Previous BMW's
    e46 M3
    e36 328is
    - Intake,Straight pipe,Racing Dynamic Strut, Spal fan,Depo,DDM HD Led Angel, LTW wing, m3 rear end, 3.23 LSD, poly RTABs, M3 brakes, Eibach Swaybars,Apex Lowering Springs, Koni Yellow.
    e36 M3 - AA SuperCharger, M50 Mani, ZF Tranny to 3.23 LSD, EBC Brakes, Enforced Subframe w/Polybushing, Eibach Swaybars,Apex Lowering Springs, Koni Yellow, Racing Dynamic Strut, LTW wing
    e30 325i Hard top convertibleM52 swap

  18. #343
    Join Date
    May 2007
    Location
    US
    Posts
    942
    My Cars
    '94 325i / s13
    Quote Originally Posted by iverson03tj View Post
    is it possible to make a message and a beeping noise as soon as the car over heats by say 10-25 degrees.... would help alot! also if there is a low tire pressure warning,

    And if you can add a Police scanner to it xD... now that I WOULD BUY FOR SURE!
    A temperature warning is easy enough, and I'm already planning to include it.

    Tire pressure is a bit more complicated. Ideally, we'd want to try to source some sensors to go in each tire. We'd then need to either interface with the display module that goes with them or duplicate its functionality in our hardware. If I had to just throw out a guess, I'd expect the sensors to be overpriced but available, and I'd expect the wireless interface to be simple enough to duplicate. Alternately, we may be able to access wheel speeds from the abs module and use them to detect asymmetrical tire circumference. This isn't nearly as good, but it's better than nothing and has no additional cost.

    A police scanner would add a lot of sensitive components and pcb work, not to mention size. Truthfully, I doubt we have the room to do it and I doubt we can afford all the pcb revisions to get it working.

  19. #344
    Join Date
    May 2007
    Location
    US
    Posts
    942
    My Cars
    '94 325i / s13
    Finally something useful.
    Attached Images Attached Images

  20. #345
    Join Date
    Mar 2008
    Location
    Portland, OR, USA
    Posts
    106
    My Cars
    1999 M3 Conv.
    Very cool benemorious!!

    So this code is interpreting the data on the data lines?

  21. #346
    Join Date
    May 2007
    Location
    US
    Posts
    942
    My Cars
    '94 325i / s13
    Quote Originally Posted by Mefis View Post
    Very cool benemorious!!

    So this code is interpreting the data on the data lines?
    Yes. I'm able to read 8 adc channels from the dme at this point. I'm still working on requesting parametric data, which is where most of the live sensor data lies.

    After that, I still need to figure out how to talk to other modules such as srs, abs, and zke. We need things like door ajar warnings, wheel speed, and the "I removed my seats with my battery still connected" lifesaver button.


    Here's another random thought. Given that it would be easy to do, would it be worth hijacking the mpg gauge in the instrument panel to let the obc use it for something like oil pressure? The scale is only 0-40 on US models.
    Last edited by benemorius; 06-25-2010 at 02:06 PM. Reason: Automerged Doublepost

  22. #347
    Join Date
    Jun 2004
    Location
    Europe
    Posts
    1,203
    My Cars
    ofc
    Quote Originally Posted by benemorius View Post
    Given that it would be easy to do, would it be worth hijacking the mpg gauge in the instrument panel to let the obc use it for something like oil pressure? The scale is only 0-40 on US models.
    Or boost for FI people (nothing new, it's already been done, but not driven from obc )

    well. I don't have access to my HDDs for all this week. Having two houses in two far locations sucks.
    but I'm following what you're doing.

    Well, maybe this will do things faster. Do you use EDIABAS (especially Tool32)?
    If you use them there is a option to trace the data it sends to the interface. Basically if you choose one module, and run identification job, you'll see in the txt trace what it ask to the car, and how it ask this (addresses etc.. )
    This works for every ecu, module, every job that has been programmed.

    You'll know EVERYTHING you need to identify modules that way. You can do a lot with that.

    I don't know if you catch my drift. if you can catch my drift I want to be first beta tester for openOBC in Europe .

    I hope others too understand this without too many question and they give freedom to their madness

    openOBC with all Ediabas data has no limits. you could for example comand the A/C from the obc, purge ABS valve while bleeding brakes. everything, you could too reset memory faults in modules.
    Last edited by nuvola rossa; 06-25-2010 at 02:35 PM.

  23. #348
    Join Date
    Mar 2008
    Location
    Metavers
    Posts
    782
    My Cars
    99 M3
    OMG I WANT!!!!!!

    SUBSCRIBED!

    Great idea let me know if you need anything i might have a OBC laying around that is in working order too.

    I also designed a bezel that will allow you to remount the OBC to the center console and be FLUSH with the rest of the cup holders and everything.

    if i get enough interested i would be glad to make them for people.
    sorry to thread jack :P

  24. #349
    Join Date
    May 2007
    Location
    US
    Posts
    942
    My Cars
    '94 325i / s13
    Quote Originally Posted by nuvola rossa View Post
    Well, maybe this will do things faster. Do you use EDIABAS (especially Tool32)?
    If you use them there is a option to trace the data it sends to the interface. Basically if you choose one module, and run identification job, you'll see in the txt trace what it ask to the car, and how it ask this (addresses etc.. )
    This works for every ecu, module, every job that has been programmed.

    You'll know EVERYTHING you need to identify modules that way. You can do a lot with that.
    Indeed, if I had access to something like that I'd have been done with this long before openobc came along. Like you, I haven't read about any of this in quite some time, but I seem to remember needing some kind of complicated and expensive ads interface for obd-I cars. Actually now that I think about it, I wonder why that should be so. Perhaps it's only to accommodate the impossibly slow 5 baud init. I should take another look at it. That'll be another week or two to go try to find a laptop with a serial port. I too must travel some distance to reach a number of my belongings that are packed away. I do need to get my logic analyzer anyway though, not that I know where that is either. I'm a packrat.

    openOBC with all Ediabas data has no limits. you could for example comand the A/C from the obc, purge ABS valve while bleeding brakes. everything, you could too reset memory faults in modules.
    I'm glad someone else sees why I want this so badly.

  25. #350
    Join Date
    Mar 2009
    Location
    athens
    Posts
    10
    My Cars
    m3,318is
    very very cool!

Page 14 of 79 FirstFirst ... 4567891011121314151617181920212223243964 ... LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •