Page 1 of 3 123 LastLast
Results 1 to 10 of 24

Thread: Need help decoding a one wire databus...

  1. #1
    Variable Bitrate
    Join Date
    Oct 2003
    Location
    Chicago, IL
    Posts
    284

    Need help decoding a one wire databus...

    Hey guys,
    this is going to be a very long and detailed post because I would like to make myself clear as possible. No cliff notes

    I am trying to integrate the navigation controls from the Mazda RX-8 into my setup. I have the unit and I've figured out a sort of pinout of the connector:
    Code:
    Mazda RX-8 Car Navigation Switch Pinout
    
    O M K    I     G    E C A
    * * AA   BB    PWR  * * *
    * * BUS  ILL   GND  * * *
    P N L    J     H    F D B
    
    PWR = Power +12V
    GND = Ground
    ILL = Illumination (+12V)
    BUS = Data Bus 
    AA = Unknown (Always High)
    BB = Unknown (Always Low)
    With this information, I put the data bus on my logic analyzer and got these waveforms:

    This is a full data transaction.
    Line goes low for ~9ms, then high for ~4.5ms. There is a .5ms pulse between each "bit". The longer "bit" (which i guess is 1?) is ~1.5ms (so 3 times the timing pulse...). The shorter "bit" is .5ms also.

    After decoding all the keys ive come up with this: (does not include the ~9ms low, ~4.5ms high part)
    Code:
    Control	 
    /-------------------------------------------------------------|
    |Menu Button         - 1000 0001 0101 0111 0011 0000 1100 1111|
    |Voice Button	     - 1000 0001 0101 0111 0111 0000 1000 1111|
    |Ret Button          - 1000 0001 0101 0111 1001 0000 0110 1111|
    |Pos Button          - 1000 0001 0101 0111 1011 0000 0100 1111|
    |Zoom-in Button	     - 1000 0001 0101 0111 1101 0000 0010 1111|
    |Zoom-out Button     - 1000 0001 0101 0111 0101 0000 1010 1111|
    |Enter Button	     - 1000 0001 0101 0111 0001 0000 1110 1111|
    |Joystick Up	     - 1000 0001 0101 0111 1100 0000 0011 1111|
    |Joystick Down	     - 1000 0001 0101 0111 0000 0000 1111 1111|
    |Joystick Left	     - 1000 0001 0101 0111 0100 0000 1011 1111|
    |Joystick Right	     - 1000 0001 0101 0111 1000 0000 0111 1111|
    |Joystick Up+Left    - 1000 0001 0101 0111 0110 0000 1001 1111|
    |Joystick Up+Right   - 1000 0001 0101 0111 1110 0000 0001 1111|
    |Joystick Down+Left  - 1000 0001 0101 0111 1010 0000 0101 1111|
    |Joystick Down+Right - 1000 0001 0101 0111 0010 0000 1101 1111|
    \-------------------------------------------------------------/
    In addition, I came across this site: http://mazda.davidoshea.homelinux.net/radio/bus.html
    which documents decoding the Mazda3 Radio bus. While similar, this Mazda3 bus is more variable PWM (bit+pulse always = constant timing, whereas with this bus, bit+pulse could either be 1ms - 2ms). It seems to definetly have some sort of protocol going on here. Which *kinda* maps up to the protocol shown on the Mazda3 radio page.

    I've been googling for some time to see if this pattern matches up something already existing. I can't seem to find anything to help make this easier.

    For right now, I'm just trying to get this data nicely into a PIC.
    Here is some pseudocodish stuff ive come up with:
    Code:
    check if bus is low, if not wait
    bus low? yes, now wait till it goes high again...
    bus high? k now wait the 4.5 ms and go into bit collecting routine:
    
    bit collecting
    wait .5ms
    bus high? add to counter
    wait .5ms
    bus high? add to counter
    bus low? drop out (counter would be 1 if bit was low)
    wait .5 ms
    bus high? add to counter (counter would now be 3 if the bit was high)
    bus low? drop out 
    wait .5ms
    bus high? drop out (it shouldnt be high for 2ms)
    
    decrease counter, skip next command if zero (if its a LOW bit, next command will be executed...)
    move 0 bit into variable
    move 1 bit into variable
    go back to bit collecting
    im sure some timing things have been left out but this is the best ive come up with at the moment that seems like it should work kinda okay. I wanted to post this up here and ask for any help or guidance on this little project if anyone is interested. I'm fairly intermediate with PICs, I've done some work with I2C and RS232, so dont be afraid to just throw stuff out there without having to hold my hand.
    Thanks for any help or info you could provide,
    bryan
    Mazdaspeed Car Computer
    gotta redo it all

  2. #2
    Constant Bitrate OdysseyPC's Avatar
    Join Date
    Oct 2003
    Location
    ACT, Australia
    Posts
    114
    That's a pretty cool project you got going on there ...

    One thing I could provide you is some optimisation for your firmware. Your method of decoding is referred to as polling, which can be inefficient if your PIC needs to do other processing.

    Now if you're like me you'd say nah polling will work and I won't need the PIC to do other things, but I think i've grown now to realise go efficient from the start.

    Anyways to the point. You would be best to setup an interrupt routine for your bit collecting. You've already done the hardwork by collecting and decoding the signals your after. You would set your interrupt to trigger on rising/falling edges and simply calculate the time between successive triggers.

    Using this method you can decode the signals by:
    1. detecting the 9ms low/4.5ms high sequence indicating the start of a code sequence.
    2. once a code sequence is detected you then calculate for the next 32 rising/falling edges.
    3. If time between sucessive rising/falling edges is ~.5ms it's a zero, otherwise it's a one.
    4. Once 32 bits have been collected then you can set a flag to indicate you have a valid code for the program to decode.

    This should improve the efficiency of your code, I use this technique a lot for decoding signals of this variety. Hope this helps
    Caputer Mk. II
    '02 VX Holden Commodore Series II Executive
    MII12000, 512MB RAM, 60GB HDD (5400rpm), 16X DVD, TS200V
    Morex 60W DC-DC, Custom S/SDC
    OS/Software: Developing...

  3. #3
    Raw Wave rando's Avatar
    Join Date
    Mar 2004
    Location
    Redondo Beach, CA
    Posts
    1,973
    The interrupt based approach seems easier to me. Also, if your pic has a PWM, I belive it can be used to trigger on an edge and capture the clock all in one shot -- to improve the stability of your measurements a little.

    In looking at the code, there are really only 4 bits needed to detect which button is pressed. Isn't there a 1111 (or 0000 for the inverted 4 bits) code that you receive for when the button is released; or does the bit pattern repeated continuously while the button is down? Or is this the sequence for a button press and release?

    Knowing that only 4 bits are needed, you could optimize the detection routine to only save 4 bits. Whenever those bits are 0111, the next 4 bits are the ones you need -- of course this assumes that the patterns you've shown are all that will ever be on the bus; I dunno if that's true or not.

    Good luck!

  4. #4
    Raw Wave rando's Avatar
    Join Date
    Mar 2004
    Location
    Redondo Beach, CA
    Posts
    1,973
    So the pattern looks like this
    1000 0001 0101 0111 KC 0000 KC# 1111
    or
    8157K0k1

    Where k = ~K
    and K is the keypress code defined below

    0 D
    1 Enter
    2 DR
    3 Menu
    4 L
    5 Zoom-out
    6 UL
    7 Voice
    8 R
    9 Ret
    A DL
    B Pos
    C U
    D Zoom-in
    E UR

  5. #5
    Variable Bitrate
    Join Date
    Oct 2003
    Location
    Chicago, IL
    Posts
    284
    Quote Originally Posted by rando
    The interrupt based approach seems easier to me. Also, if your pic has a PWM, I belive it can be used to trigger on an edge and capture the clock all in one shot -- to improve the stability of your measurements a little.

    In looking at the code, there are really only 4 bits needed to detect which button is pressed. Isn't there a 1111 (or 0000 for the inverted 4 bits) code that you receive for when the button is released; or does the bit pattern repeated continuously while the button is down? Or is this the sequence for a button press and release?

    Knowing that only 4 bits are needed, you could optimize the detection routine to only save 4 bits. Whenever those bits are 0111, the next 4 bits are the ones you need -- of course this assumes that the patterns you've shown are all that will ever be on the bus; I dunno if that's true or not.

    Good luck!
    My PIC I will be doing testing with is a 16F628 or 16F877. Eventually I'd like to get it onto a USB PIC (not sure which one yet).

    And yeah, I did notice I would only need to really save those 4 bits, as it will uniquely idenify the action. This will be the only device on the bus. I'm not planning on interfacing with any other OEM harware. But in order to perhaps make the code reusable for other hardware, I think I will process and save all bits.

    This pattern is generated for a button press and release. If the button is held down, the pattern repeats itself after a pause of roughly 25ms. So after a stream is collected, I can just to back to my "wait if bus is low, wait 9ms..." routine.

    Do you by chance have any more info on this PWM method? I searched for awhile but all I came up with was info on programming FPGAs. Right now, I'm trying to figure out how to implement OdysseyPC's code. I've never used timers before so I'm trying to pick that up and figure it out.

    Much thanks for the response, this really helps alot!
    Mazdaspeed Car Computer
    gotta redo it all

  6. #6
    Variable Bitrate
    Join Date
    Oct 2003
    Location
    Chicago, IL
    Posts
    284
    Quote Originally Posted by OdysseyPC
    That's a pretty cool project you got going on there ...

    One thing I could provide you is some optimisation for your firmware. Your method of decoding is referred to as polling, which can be inefficient if your PIC needs to do other processing.

    Now if you're like me you'd say nah polling will work and I won't need the PIC to do other things, but I think i've grown now to realise go efficient from the start.

    Anyways to the point. You would be best to setup an interrupt routine for your bit collecting. You've already done the hardwork by collecting and decoding the signals your after. You would set your interrupt to trigger on rising/falling edges and simply calculate the time between successive triggers.

    Using this method you can decode the signals by:
    1. detecting the 9ms low/4.5ms high sequence indicating the start of a code sequence.
    2. once a code sequence is detected you then calculate for the next 32 rising/falling edges.
    3. If time between sucessive rising/falling edges is ~.5ms it's a zero, otherwise it's a one.
    4. Once 32 bits have been collected then you can set a flag to indicate you have a valid code for the program to decode.

    This should improve the efficiency of your code, I use this technique a lot for decoding signals of this variety. Hope this helps
    Thanks! This method does seem better that polling. I've used interrupts before but never the timer/counter. I will continue reading up on this stuff and figuring it out. Thanks again.
    Mazdaspeed Car Computer
    gotta redo it all

  7. #7
    Registered User
    Join Date
    May 2003
    Posts
    1,736
    The PWM being mentioned is the CCP module. This can be setup to time the pulse width and return the value in the CCP registers, useful for measuring the pulse width.

    Hmm interrupts? I wont bother with it. The bit change interrupt can be a problem when at the same time trying to access the port, very unlikely you be doing this anyway.

    From microchip apps note >

    Note: If a change on the I/O pin should occur
    when a read operation is being executed
    (start of the Q2 cycle), then the RBIF
    interrupt flag may not get set.

    The interrupt-on-change feature is recommended for
    wake-up on key depression operation and operations
    where PORTB is only used for the interrupt-on-change
    feature. Polling of PORTB is not recommended while
    using the interrupt-on-change feature.


    Applying interrupt, your code wont be doing anything apart from waiting for the line to go low for ~9ms then back high again for ~5ms to indicate a start condition. Once you are in the start theres not much for you to do apart from decoding the stream of data which is going to be part of the interrupt routine.

    Your main will look like >

    Main
    goto main

    Look abit silly. The rest are done in the interrupt routine.

    As for the CCP module, not all PICs have this. Infact you dont even need it.
    If you really want to optimise your design, use a 12C508 or something along those line.

    For measuring the pulse width you can make it this way >

    Setup a 0.1ms timer that set a flag every 0.1ms using interrupts.


    On part of the decoding routine on the main >
    Each time an interrupt occured a counter is incremented. If this counter contains ~5 after a bit changed then you know ~0.5ms has passed. You reset this counter every bit change and of course you have to reset the "0.1ms" elapsed flag every time you increment.

    You now have a pulse width measurement routine accurate to ~0.1ms.

    So from the beginning, your main loop will start incrementing the pulse width counter as soon as a LOW is detected. If the counter does not equate to ~9ms after it goes high then you know this is not a start condition, the code should reset looking for the ~9ms LOW again. If successful, look for a ~5ms high this time.

    All you have to do is keep a track of the pulse width counter and at which state it is measuring, a HIGH or a LOW state. From there you can decode on the fly.

    You can either save all the data and decode from the RAM or just decode whats needed on the fly.

    How are you going to output the decoded bits? Using 4 pins from the PIC or output it to the serial port?

    Outputing it to serial port should be fairly easy.


    How you gonna program it? ASM? C? BASIC?

    Interrupt or polling, hardware or software pulse width measurement thats your choice. But this little project can definitely be done with some of the most basic PIC you can buy.

    Thats about it for now I guess

  8. #8
    Registered User
    Join Date
    May 2003
    Posts
    1,736
    If I missed something, thats because I havent read the thread in details

  9. #9
    Variable Bitrate
    Join Date
    Oct 2003
    Location
    Chicago, IL
    Posts
    284
    Wow, at least i can answer the last two questions
    ASM and serial output

    Thanks! let me try to digest all of that.
    Mazdaspeed Car Computer
    gotta redo it all

  10. #10
    Variable Bitrate
    Join Date
    Aug 2004
    Posts
    316
    cool thread - I'll buy a board + try the software when it's done!


Page 1 of 3 123 LastLast

Similar Threads

  1. In search of an ignition wire
    By witten in forum Power Supplies
    Replies: 16
    Last Post: 07-27-2006, 02:29 AM
  2. lengthening fm transmittor antenna wire
    By hand in forum General Hardware Discussion
    Replies: 2
    Last Post: 03-24-2005, 11:21 PM
  3. Replies: 37
    Last Post: 05-17-2004, 08:01 PM
  4. Replies: 11
    Last Post: 03-09-2004, 10:59 AM
  5. ignition wire for opus psu
    By liquid_smoke in forum Power Supplies
    Replies: 3
    Last Post: 09-09-2003, 11:58 PM

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
  •