Shop OBEX P1 Docs P2 Docs Learn Events
SEROUT ASM Question — Parallax Forums

SEROUT ASM Question

YendorYendor Posts: 288
edited 2008-08-22 01:52 in General Discussion
I have a question for someone to help shed some light for me...

Below is the SX/B ASM code output·for the SEROUT·(OT) function.

I'm understanding what's going on except for why the CLRB MidiOut is needed after the MOV !RA,IND·in the code below.· It seems to be doing the same thing, and works without it, but was wondering if I was not realizing something·for leaving it out?·

Maybe it's needed to cover off on the other modes?·

It's only one cycle, but again the curiosity strikes me.

' ------------------------------------------------------------------------- 
' IO Pins 
' ------------------------------------------------------------------------- 
MidiOut VAR RA.1 
'..... 

MOV __PARAM1,#NN ';SEROUT MidiOut, MidiBaud, NN (sx/b) 
MOV __PARAM2,#10 '#bits 
MOV FSR,#__TRISA 'get the i/o states 
MODE $0F 'set for i/0 
CLRB IND.1 'This gets bit 1 ready to toggle to 0 (input or 0 for Open Collector) for Start Bit = 0 
MOV !RA,IND 'RA.1 to 0 (input) (but sets all 4 ports) 
[b]CLRB MidiOut 'RA.1 to 0? Why would this statement be needed here? Didn't CLRB IND.1 take care of this?[/b] 
MOV __PARAM4,#126 'baud rate loop 
DJNZ __PARAM4,@$ 
MOVB IND.1,__PARAM1.0 'this gets the next bit ready for bits 0-8 + stop bit 
MOV !RA,IND 'output the bit (but sets all 4 ports) 
STC 'set carry for stop bit 
RR __PARAM1 'rotate right to move next bit into LSB 
DJNZ __PARAM2,@$-13 
BANK $00 

Bean, after realizing what was going on, I must commend you as this a brilliant way to do the open collector simulation!· Toggling the TRIS bit to input or output related to the port for 1 or 0 - wow!

Many thanks!

Rodney

Comments

  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-08-22 00:29
    The CLRB IND.1 statement is actually clearing the associated bit in the "shadow" TRIS register for the port (SX/B saves this as you cannot read the TRIS registers in the SX28). The next line, MOV !RA, IND, writes the shadow register to the TRIS port which makes the pin an output. The CLRB MidiOut is actually manipulating your serial pin. As you've no doubt figured by now, when the port is an output you want to pull it low for OT mode. If you changed your mode to ON (open inverted) you would see SETB MidiOut so that a "1" is written to the port when it's an output.

    Post Edited (JonnyMac) : 8/22/2008 12:35:07 AM GMT
  • YendorYendor Posts: 288
    edited 2008-08-22 01:28
    Thanks for the feedback once again, Jon!·

    (Man, I don't see how you get anything done with all the detailed posts you provide!)

    I'm still not seeing something, though...

    The CLRB MidiOut only occurs on the start bit.· The other bits 9 bits freely toggle between input and output for on-1/off-0 without·performing a CLRB or SETB on the MidiOut port - just with toggling the shadow TRIS registers, as you say.· I could see if it's that way with all bits that are 0, but it·only occurs·with the start bit.

    With a 'scope, I can see the pin's state go to zero on the start bit, as soon as the MOV !RA,IND is executed, and before the CLRB MIDIOUT·is executed.· (Experimenters - be forewarned, with OC you need to have the complete circuit to see the port·change).

    Could it be, it was coded this way in case it was a bidirectional pin to 'initialize' the state, or in case there was more than two 'devices' in the current loop?

    Many thanks!

    Rodney
  • JonnyMacJonnyMac Posts: 9,215
    edited 2008-08-22 01:52
    All high level SX/B instructions set the pin as needed (input or output) without regard to the present state which would just take more code to check. So if there was a 0 in the pin driver for your midi output it that output will go low as soon as the TRIS is updated. There is no harm since the next instruction is going to take it low, anyway.

    Keep in mind that manipulating the TRIS bit does not affect the driver bit. In this case it gets initialized to zero (low when in output mode). It's easy to manipulate the TRIS bit by copying the midi data bit to it. When the midi data bit is a 0 that will cause the TRIS register to make your pin an output. Since the pin driver has been initialized to zero the output will go low. When you have a "1" data bit that will cause the TRIS to make the pin an input, and the pullup on the pin (be definition OT serial pins must have a pull-up) will bring the pin back high. Easy-peezy.

    In general, it works like this: for the open modes (OTxxxx, ONxxxx) the pin driver is initialized and the TRIS register is manipulated by the data bits; for driven modes (Txxxx, Nxxxx) the TRIS register is initialized (to make the pin an output) and the pin driver is manipulated by the data bits. Knowning this you can use a simple loop to send custom serial. I created a LanC controller for a customer that gets the start bit from the camera. I have a custom serial output loop that waits one bit period after detecting the start and then writes the byte. The LanC output is Open True as well so the controller can stomp on the first two bytes (which are $FF meaning the serial line is being pulled up) to send commands to the camera.

    ' Use: LANC_TX aByte
    ' -- asserts 'aByte' onto LANC line after start bit
    ' -- used only for bytes 0 and 1 of LANC stream
    
    SUB LANC_TX
      tmpB1 = __PARAM1                              ' get byte to send
    
    Wait_For_Start:
      \ JB LancIn, $                                ' hold for start bit
      PAUSEUS 103                                   ' delay for start bit
    
    TX_Bits:
      FOR tmpB2 = 0 TO 7                            ' send eight bits
        LancOut = tmpB1.0                           ' put bit on LANC pin
        PAUSEUS 98                                  ' trimmed for loop
        tmpB1 = tmpB1 >> 1                          ' position next bit
      NEXT
      LancOut = 0                                   ' turn off driver
      ENDSUB
    


    Keep in mind that serial devices tend to sample in the middle of the bit so a little slop one way or the other doesn't hurt anything, especially since LanC runs at the very tame baud rate of 9600.
Sign In or Register to comment.