Hardware Serial input problem with a 20X2

BillBWann

Member
I’m having a problem with the hardware serial input to a 20X2. I’ve used this feature before with a GPS and other inputs and found it to work very simply and reliably in the past but not today. I’ve narrowed my current problem down to the following simple program.

The program receives 3 short lines of characters, each line being about 35 characters long. The lines consist of a date/time stamp and a couple of other numbers. The program simply has to extract the single character following the 3rd comma in each line of characters sent. A typical line of characters would be:

6/1/20, 15:57:14, 10,2 (82,82) and the character to be extracted in this case would be "2".

It is my understanding that the hardware serial should occur in the background and be completely unaffected by what the program is doing but that doesn’t appear to be the case here.

The program that follows consists of 2 basic parts. The first part between the dotted lines allows the program to perform as expected by delaying any parsing of a line of characters until the complete line has arrived into the hardware buffer. It does this by waiting for there to be a 100mS delay in the arrival of a new character. The rest of the program simply extracts the required character by looking for the 3rd comma and copying the next character into the variable “Char”. Both parts of the program have a number of sertxd statements so I can see what’s happening.

Code:
#picaxe 20x2
#no_data
#no_table
#terminal 9600

symbol char=b1
symbol commacnt=b2    'count of number of commas encountered
symbol temp=b3
symbol temp1=b4

HSerSetup B9600_8,%111    'Switch on background RS232

ptr=hserptr    'Synchronise pointers
commacnt=0    'initialize comma count

do

'----------------------------------------------   
    do
        temp=hserptr
        pause 100
    loop while hserptr<>temp or ptr=hserptr
    sertxd ("Buffer end ",#temp,cr,lf)
    
    temp1=ptr    'save ptr temporarily
    for ptr=temp1 to temp    'Display what's in the hardware buffer
        sertxd (@ptr)
    next ptr
    ptr=temp1    'restore ptr
    sertxd ("Buffer start & end after sertxd ",#ptr,", ",#hSerPtr,cr,lf)
'----------------------------------------------   

    if hSerPtr <> ptr then
        do
            do:loop until hSerPtr <> ptr    'delay until the next character has actually arrived
            sertxd (#hserptr,", ",#ptr,", ",@ptr," (")    'display hSerPtr & ptr values and the character being processed
            temp=@ptrinc                        'save the character into temp and increment ptr
            sertxd (#temp,")",cr,lf)        'display the ascii value of the character being processed
            if temp="," then
                inc commacnt
                if commacnt=3 then
                    do:loop until hSerPtr <> ptr    'delay until the next character after this one has actually arrived
                    char=@ptr
                    inc commacnt    'increment comma count to prevent coming here again for this line of caharacters
                    sertxd (cr,lf,"Char=",Char,cr,lf)
                endif
            endif
        loop while temp<>lf
        commacnt=0    'reset comma count
        sertxd ("Finished line",cr,lf)       
    endif
loop
The following shows the results of running the full program and demonstrate that it’s performing as expected.

Code:
Buffer end 36
6/1/20,  15:57:14,   10,2  (82,82)
Buffer start & end after sertxd 0, 36
36, 0, 6 (54)
36, 1, / (47)
36, 2, 1 (49)
36, 3, / (47)
36, 4, 2 (50)
36, 5, 0 (48)
36, 6, , (44)
36, 7,   (32)
36, 8,   (32)
36, 9, 1 (49)
36, 10, 5 (53)
36, 11, : (58)
36, 12, 5 (53)
36, 13, 7 (55)
36, 14, : (58)
36, 15, 1 (49)
36, 16, 4 (52)
36, 17, , (44)
36, 18,   (32)
36, 19,   (32)
36, 20,   (32)
36, 21, 1 (49)
36, 22, 0 (48)
36, 23, , (44)

Char=2
36, 24, 2 (50)
36, 25,   (32)
36, 26,   (32)
36, 27, ( (40)
36, 28, 8 (56)
36, 29, 2 (50)
36, 30, , (44)
36, 31, 8 (56)
36, 32, 2 (50)
36, 33, ) (41)
36, 34,   (13)
36, 35,
 (10)
Finished line
Buffer end 105
6/1/20,  15:57:16,   10,0  (80,80)
6/1/20,  15:57:16,   0,0  (0,0)
Buffer start & end after sertxd 36, 105
105, 36, 6 (54)
105, 37, / (47)
105, 38, 1 (49)
105, 39, / (47)
105, 40, 2 (50)
105, 41, 0 (48)
105, 42, , (44)
105, 43,   (32)
105, 44,   (32)
105, 45, 1 (49)
105, 46, 5 (53)
105, 47, : (58)
105, 48, 5 (53)
105, 49, 7 (55)
105, 50, : (58)
105, 51, 1 (49)
105, 52, 6 (54)
105, 53, , (44)
105, 54,   (32)
105, 55,   (32)
105, 56,   (32)
105, 57, 1 (49)
105, 58, 0 (48)
105, 59, , (44)

Char=0
105, 60, 0 (48)
105, 61,   (32)
105, 62,   (32)
105, 63, ( (40)
105, 64, 8 (56)
105, 65, 0 (48)
105, 66, , (44)
105, 67, 8 (56)
105, 68, 0 (48)
105, 69, ) (41)
105, 70,   (13)
105, 71,
 (10)
Finished line
Buffer end 105
6/1/20,  15:57:16,   0,0  (0,0)
Buffer start & end after sertxd 72, 105
105, 72, 6 (54)
105, 73, / (47)
105, 74, 1 (49)
105, 75, / (47)
105, 76, 2 (50)
105, 77, 0 (48)
105, 78, , (44)
105, 79,   (32)
105, 80,   (32)
105, 81, 1 (49)
105, 82, 5 (53)
105, 83, : (58)
105, 84, 5 (53)
105, 85, 7 (55)
105, 86, : (58)
105, 87, 1 (49)
105, 88, 6 (54)
105, 89, , (44)
105, 90,   (32)
105, 91,   (32)
105, 92,   (32)
105, 93, 0 (48)
105, 94, , (44)

Char=0
105, 95, 0 (48)
105, 96,   (32)
105, 97,   (32)
105, 98, ( (40)
105, 99, 0 (48)
105, 100, , (44)
105, 101, 0 (48)
105, 102, ) (41)
105, 103,   (13)
105, 104,
 (10)
Finished line
However, the whole purpose of using the 20X2 for this project is to be able to process this data as it arrives while doing other things. Therefore, I would expect that the program should operate without delaying until the full line has been read into the buffer. In this example, I’ve simply remmed out the first part of the program and run it again but you can see from the following that it’s a disaster.

Code:
2, 0, 6 (54)
7, 1, / (47)
12, 2, 1 (49)
14, 3, / (47)
14, 4, ç (231)
14, 5, 3 (51)
14, 6,   (30)
14, 7, y (121)
14, 8,   (30)
14, 9, 8 (56)
14, 10, 2 (50)
14, 11, ) (41)
14, 12,   (13)
14, 13,
 (10)
Finished line
16, 14, 6 (54)
21, 15, / (47)
25, 16, 1 (49)
25, 17, / (47)
25, 18, 
 (14)
25, 19, ž (158)
25, 20,   (30)
25, 21,   (30)
30, 22, þ (254)
35, 23, 8 (56)
35, 24, 0 (48)
35, 25, 6 (54)
35, 26, / (47)
35, 27, 1 (49)
35, 28, 6 (54)
35, 29, : (58)
35, 30, 2 (50)
35, 31, 9 (57)
35, 32, ù (249)
35, 33, 0 (48)
35, 34, ø (248)
The first thing to note is that the hSerPtr isn’t steadily rising as I would have expected and appears to stall after about 15 characters. Only the first 4 characters are correct and from there on its a mixture of garbage and the odd possibly correct character. When the 2 lines are sent a couple of seconds later, it seems to get a few more characters into the buffer but they are obviously corrupted.

When this first happened, I assumed that I was somehow over-running the buffer but the debug data confirms that ptr is never greater than hSerPtr . The other possibility that I thought of was that somehow this 20X2 was affecting the data being sent but a check on that showed a normal transmission. The first part of that actual transmission is shown below.


23459


I also checked that the voltage supplying the 20X2 and that appeared to be stable at 5 volts and for completeness I ran it again using 4 fully charged batteries. Finally, I set up another 20X2 on a breadboard with only the download resistors and the connection to pin b.6 (the hardware serial in pin) and it performed the same.

I’ve spent a considerable amount of time working on this and have run out of ideas so I’m looking for suggestions. I’m sure it has to be something simple and will probably be quite obvious when it’s pointed out – at least, I’m hoping that will be the case.
 

hippy

Senior Member
It is possible that the received data is over-running the buffer or things are getting out of kilter. It may be better to rewrite the code in the form of a Finite State Machine (FSM) which will allow things to be progressed as data is received which reduces the possibility of overrun.

State Machines are also useful for allowing complicated sequencing to be simplified and more easily followed.

The code below runs in simulation and should also work on a real chip. When simulated it fakes data having been received as background serial and then lets the main loop loose on that data.

Code:
#Picaxe 20X2
#Terminal 9600
#No_Data

Symbol WAIT_FOR_SLASH     = 0
Symbol WAIT_FOR_1ST_COMMA = 1
Symbol WAIT_FOR_2ND_COMMA = 2
Symbol WAIT_FOR_3RD_COMMA = 3
Symbol READ_VALUE         = 4

Symbol value  = w1 ; b3:b2
Symbol state  = b4
Symbol rxChar = b5

#Macro When( char, nextState )
  Select Case rxChar
    Case char : state = nextState
    Case "/"  : state = WAIT_FOR_SLASH
    Case ":"  : state = WAIT_FOR_2ND_COMMA
  End Select
#EndMacro

Init:
  HSerSetup B9600_8,%111

  #IfDef SIMULATING
    b0 = 0
    Do
      LookUp b0,( _
        "6/1/20, 15:57:14, 10,2 (82,82)", _
        "6/1/20, 15:57:15, 10,  1234  (82,82)", _
      0), @ptr
      b0 = b0 + 1
    Loop Until @ptrInc = 0
    hSerPtr = ptr
    ptr = 0
  #EndIf

MainLoop:
  state = WAIT_FOR_SLASH
  Do
    Gosub CheckForReceivedData
    ; ... other things ...
  Loop

CheckForReceivedData:
  Do While ptr <> hSerPtr
    Gosub HandleCharacter
  Loop
  Return

HandleCharacter:
  rxChar = @ptrInc
  Select Case state
    Case WAIT_FOR_SLASH     When( "/", WAIT_FOR_1ST_COMMA )
    Case WAIT_FOR_1ST_COMMA When( ",", WAIT_FOR_2ND_COMMA )
    Case WAIT_FOR_2ND_COMMA When( ",", WAIT_FOR_3RD_COMMA )
    Case WAIT_FOR_3RD_COMMA When( ",", READ_VALUE )
    Case READ_VALUE
      If rxChar <> " " Then
        If rxChar >= "0" And RxChar <= "9" Then
          value = value * 10 + rxChar - "0"
        Else
          SerTxd( "Got value ", #value, CR, LF )
          value = 0
          state = WAIT_FOR_SLASH
        End If
      End If
   End Select
  Return
That relies on polling for received data in the main loop but it should be possible to make it interrupt driven. And simplified, because this reads the value after the third comma when you only need the single character.

It currently just reports values extracted from the serial stream as they are found and there may be more work needed to use those how you want to in your actual program.

It's probably worth giving it a whirl to see if it at least pulls out the values you are interested in.
 

inglewoodpete

Senior Member
One thing I learned early on when using background async serial data receive: using SerTxd during serial data reception will corrupt the incoming data. This is because SerTxd is bit-banged serial output. Being bit-banged, timing of each bit and byte is critical, so internal interrupts are disables. This results in the Rx UART not being read/cleared on reception of a character, and successive bytes overwriting the UART's Rx data buffer.
 

hippy

Senior Member
Good point. This is better for reporting data received while there may be more data incoming ...
Code:
    Case READ_VALUE
      For b0 = 0 To 11
        ;            012345678   9       10  11
        Lookup b0,( "Got char ", rxChar, CR, LF ), b1
        SerTxd( b1 )
      Next
      state = WAIT_FOR_SLASH
   End Select
 

BillBWann

Member
One thing I learned early on when using background async serial data receive: using SerTxd during serial data reception will corrupt the incoming data. This is because SerTxd is bit-banged serial output. Being bit-banged, timing of each bit and byte is critical, so internal interrupts are disables. This results in the Rx UART not being read/cleared on reception of a character, and successive bytes overwriting the UART's Rx data buffer.
Yes, thanks Inglewoodpete. Removing the sertxd statements solved the problem. It’s ironic really because the original code that wasn’t working didn’t have any sertxd statements in it and I only put them in there to debug that error – which sent me off on this wild goose chase.

The one good thing to come out of it though is that I now won't forget this limitation on the hardware serial which I didn’t know about before this. I had assumed that the hardware serial worked completely independently of the processor on an X2.

This also means that the 20X2 will now probably not be a good candidate for this monitoring project which needs to monitor 2 independent serial sources simultaneously in addition to a couple of digital inputs. While the traffic on the serial inputs isn’t high, they aren’t coordinated in any way so their transmissions could easily overlap. Using a couple of M2’s with their limited hardware serial will probably turn out to be easier to implement (especially using AllyCat's method discussed here).

Thanks Hippy for your contribution although I don't fully understand your code and can’t see its advantage in this case where I want to progressively parse the data strings as they arrive.

Thanks to the both of you.
 

inglewoodpete

Senior Member
This also means that the 20X2 will now probably not be a good candidate for this monitoring project which needs to monitor 2 independent serial sources simultaneously in addition to a couple of digital inputs. While the traffic on the serial inputs isn’t high, they aren’t coordinated in any way so their transmissions could easily overlap.
I had a project that had two independent serial sources too. Since I'm fairly well versed in PIC C programming, I used a PIC18F25K22 (the hardware in a 28X2), which actually has two hardware UARTs. Compared to a PICAXE, it took a whole lot more time to write and debug my program, though!
 

hippy

Senior Member
Removing the sertxd statements solved the problem. It’s ironic really because the original code that wasn’t working didn’t have any sertxd statements in it and I only put them in there to debug that error – which sent me off on this wild goose chase.
Unless you found any bugs in your code which you have corrected, then the code will be as it was. It may be working now but it seems it could easily revert back to the not working state.

This also means that the 20X2 will now probably not be a good candidate for this monitoring project which needs to monitor 2 independent serial sources simultaneously ... Using a couple of M2’s with their limited hardware serial will probably turn out to be easier to implement
I would not expect M2 HSERIN to work better than 20X2 background receive. The SERTXD issue is that, when executing, it can block reception of serial. On an X2 it will only block while executing commands, will update the background serial between commands. On an M2 it will block reception except when explicitly executing the HSERIN command, which will have a far higher likelihood of losing data.

On both M2 and X2 there is a hardware double-buffer which means no data will be lost so long as the PICAXE program doesn't take the firmware's attention away from handling serial for more than 2ms for 9600 baud. That's more likely to happen with an M2 than an X2, will require careful coding to ensure that does not happen.

Thanks Hippy for your contribution although I don't fully understand your code and can’t see its advantage in this case where I want to progressively parse the data strings as they arrive.
It's hard to explain its advantage other than it's designed to be efficient and robust.

But if what you have is now working and does what you want then it doesn't really matter which you use.
 

BillBWann

Member
Hippy, the original code was attempting to monitor two serial inputs at the same time so was more complicated than the code I sent to the forum in #1. When attempting to debug problems in that code, I inadvertently generated a new bug which I condensed down to the code I sent in #1 to demonstrate my problem. It’s only this condensed program which is now operating as expected and I’m abandoning that original code as it relied of using Serin while data from the other serial source was being received into the hardware buffer.

The reason why I think two M2s are better than one X2 is that each M2 can be dedicated to receiving its serial data and only the processed data needs to be sent from one M2 to the other. As the other serial input is only 1200 baud and I have total control over the communication between the two M2s, I think that it’s quite doable. While the two serial data streams are sent at random times, there is a period following each transmission when it can be guaranteed that no new data will be sent. In one case that period is only a couple of seconds but in the other case it’s over a minute.

Thanks again Hippy for your interest and advice.
 

hippy

Senior Member
There is one issue with using an M2; and that that's not being able to invert the HSERIN pin, have direct RS232-style idle low serial input. You would have to invert the serial stream outside the PICAXE or use the internal Data Signal Modulator to do that inversion. This code should do that but not tested on actual hardware ...
Code:
;            PICAXE-20M2
;       .---| C.4   B.3 |
; RX >--|-->| C.3   B.4 |
;       |   | C.2   B.5 |
;       |   | C.1   B.6 |<--.
;       |   | C.0   B.7 |   |
;       |   `-----------'   |
;       `-------------------'

Init:

  PokeSfr $FC, %11000000 ; SFR $39C MDCON
  PokeSfr $FD, %00000001 ; SFR $39D MDSRC
  PokeSfr $FE, %01000000 ; SFR $39E MDCARL
  PokeSfr $FF, %00000000 ; SFR $39F MDCARH

  HSerSetup B9600_4,%010
 

BillBWann

Member
Thanks Hippy for this suggestion. I've not looked at the Data Signal Modulator before. Could you briefly summarize how this works?

Also, is it possible to do this on an 08M2?
 

hippy

Senior Member
I've not looked at the Data Signal Modulator before. Could you briefly summarize how this works?
It's basically a purely hardware two-input multiplexor which chooses one or the other depending on a software bit, external input, or other internal signal. The two inputs can either be low or high, or come from PWM or other internal peripherals.

Full details are in the Microchip datasheets which are linked to from -

http://www.picaxe.com/What-is-PICAXE/PICAXE-Chip-Labels

DSM.jpg
Click to enlarge

Also, is it possible to do this on an 08M2?
Yes, the DSM is supported on all PICAXE M2 chips. However, on the 08M2, the DSM output shares a pin with HSEROUT so you lose the ability to use HSEROUT if using the DSM.
 

BillBWann

Member
Yes, the DSM is supported on all PICAXE M2 chips. However, on the 08M2, the DSM output shares a pin with HSEROUT so you lose the ability to use HSEROUT if using the DSM.
It also looks like the input to the "inverter" shares a pin with HSERIN so it's probably not really practical on an 08M2. Maybe moving HSERIN is a possibility but installing a simple transistor inverter seems a lot easier and leaves more pins available for future additions.

Great to know about this possibility though as it may well be useful in another situation so thanks Hippy.
 

AllyCat

Senior Member
Hi,

I think any one of Legs 3, 5 and 6 (of an 08M2) could be used as an "input" for simple inversion by the DSM, but yes, only Leg 7 can be the "output". Also, the DSM method is rather greedy of pins because (at least with a PICaxe) it's necessary to link the output externally back to the HSERIN input pin (either Leg 6 or Leg 2), in addition to the non-inverted serial input itself.

At the foot of the code listing in #1 of my original "Problems with HSERIN" post, I showed an "ASCII Art" schematic for a "configurable" external inverter using only an NPN and one resistor (in addition to the normal "programming" input resistor configuration). I've now refined that arrangement by adding a 3-pin-header, with its pin 1 to a PICaxe output (e.g. Leg 3 or 5), pin 2 to the emitter, and pin 3 to ground. Then, the "idle high / idle low" can be controlled automatically by the output pin state (i.e. when bridging 1-2), or the output pin freed up for another purpse and manually selecting idle low (inversion) by bridging 2-3, or idle high by not fitting a link.

Occasionally,, I'm still tinkering with my "SFR HSERIN" code and am confident that by using an external inverter and the Alternate Pin Fuction (APFCON) register, it should be possible to receive programming and fully concatonated serial bytes of either polarity at up to 19200_32 baud on Leg 2 of an 08M2, leaving most other pins (in particular SerOut, SCL and SDA) available for other purposes.

Cheers, Alan.
 

BillBWann

Member
Yes Alan, I’ve looked at your earlier pin inversion options before. So far I’ve not actually implemented it because I’ve not needed the flexibility it would provide and it would take me too long to come to grips with how it all worked again. However, I have used your trick of using a single transistor and resister along with a weak pullup to invert a single input.

I think any one of Legs 3, 5 and 6 (of an 08M2) could be used as an "input" for simple inversion by the DSM
I don’t fully understand how the DSM works and while I tried to change the input to Hippy’s inverter, I wasn’t successful. Do you have any code examples for using legs 3 or 5 as inputs to his inverter?
 

AllyCat

Senior Member
Hi,
.... it would take me too long to come to grips with how it all worked again. However, I have used your trick of using a single transistor and resister along with a weak pullup to invert a single input.
The operation is mainly determined by how the emitter is connected: If it is taken to ground (either directly or via a "Low" PICaxe output pin), then the collector can pull down when the base (current) goes up (i.e. signal inversion). Incidentally, you could just disconnect the normal 22k programming resistor from the PICaxe input pin and connect it to the NPN base. It's an unnecessarily low resistance, but easy and familiar.

As a brief diversion here; in some ways an NPN transistor looks like two diodes inside a single package, with cathodes to emitter and collector and both anodes to the base (the emitter arrow shows the equivalent diode/current flow direction). Most modern multimeters now have a transistor (gain) test facility, but "in the old days" we used to test if we'd "blown up" a transistor by measuring the resistance across all (six) permutations of E, B and C with our trusty "AVO" (Amps, Volts and Ohms - neat brandname eh?). E-B and C-B should be low resistance in one direction and high in the other (i.e. a diode) and E-C high in both directions (alternate polarity diodes in series). So.......


It doesn't matter if you leave the emitter "floating" (no link or PICaxe output pin set as an input) or allow a PICaxe pin to pull it High (where the emitter diode will be reverse-biassed); in either case the NPN can't pull the serial input Low (i.e. no inversion). In principle, the base (22k) resistor in series with the B-C diode can pull the serial input high, but the (reversed) B-C diode can't pull this input low again. So we need another resistor from the collector (PICaxe input) to either the base or the external input (or even to ground).

Generally a PICaxe input will always see a "1" (High) if it is greater than Vcc / 2, so we need to ensure that the ("Weak") internal pullup resistance is lower than any external pull-down resistance. Nominally, the Weak Pullups are about 30k - 35k , but they might be much higher (according to the data sheet) so it's wise to make the "inversion bypass" resistor about 100k or more. And a "reminder" that the PICaxe PULLUP command won't pull the Programming Input pin high, so for that you need a POKESFR WPUA , 32 (for an 08M2).

I don’t fully understand how the DSM works and while I tried to change the input to Hippy’s inverter, I wasn’t successful. Do you have any code examples for using legs 3 or 5 as inputs to his inverter?
I must admit that I've never actually used the DSM. As said, it's rather greedy of pins, particularly as it can't use the Leg 4 "Input Only" pin (which so often is of limited value). However, what I may do in the next day or two (no promises) is to mark up the "Simplified Block Diagram" (as shown by hippy above) with the Pin, Register, Logic functions and expected internal signal levels, etc.. That should make it fairly easy to determine the required pin connections and the (four) SF Register contents.

Cheers, Alan.
 

hippy

Senior Member
I think any one of Legs 3, 5 and 6 (of an 08M2) could be used as an "input" for simple inversion by the DSM
I don’t fully understand how the DSM works and while I tried to change the input to Hippy’s inverter, I wasn’t successful.
I was wondering about that. Though the DSM can use a number of sources ( middle multiplexor in the diagram ) which it uses to select what to output, only MDMIN comes from an input pin. The rests come directly from the output of other peripherals. Even if those go to pins which can be used as input, the selector goes to the on-board peripherals, not the pins.

However, the comparator output can be used, and that will have an input which can drive that, which can be considered an additional input, or two inputs for 14M2, 18M2 and 20M2 - I haven't checked what combinations are actually available on each chip, whether providing additional inputs or not.

But, using a comparator is another option I'd forgotten about for creating an inverter on-chip. Again I haven't checked which can support what.
 

AllyCat

Senior Member
Hi,

Input pins are also allocated to MDCIN1 and MDCIN2. ;) I find the "Pin Allocation Table" quite near to the beginning of the relevant base PIC data sheet to be most helpful for this type of evaluation. Also, "Leg" numbers can be more useful to specify, with the remapping of port.pin numbers of 14 and 20 pin M2s.

The 08M2 does have one comparator. ;) Also, the "SR-Latch" of any M2 might be usable as an inverter? Normally, I've found the SR Latch rather "useless" in the PICaxe environment (because its maximum timing delays are shorter than a single instruction execution time), but here the complementary input/outputs might be of value ?

Cheers, Alan.
 

AllyCat

Senior Member
Hi,

Here's my attempt to annotate the DSM block diagram for all M2 chips. My intention is that the "active" signal will take the top path (CARH) from an input pin through to the output. Then the middle (MOD) and lower (CARL) paths are passive (i.e. fixed). To allow the active signal to pass through each AND gate, its second input must be High, to allow it to pass through an OR gate its second input must be Low. The signal can always pass through an XOR, with the second input determining whether the output is inverted or not. To avoid any complications, I've tried to bypass (i.e. avoid) any paths through the flip-flops.

I've marked the "expected" (i.e. intended) signal levels in yellow, but haven't time at the moment to set up the values for the four SFR registers (at addresses $FC to $FF), let alone test them (which can of course be done only on a "real" PICaxe, not in the simulator). It's probably better to test with actual I/O voltage signals, but it may be possible to verify the operation by just changing the input flags and reading the MDOUT flag (MDCON.3).

DSMmodule3.png

Cheers, Alan.
 

hippy

Senior Member
My intention is that the "active" signal will take the top path (CARH) from an input pin through to the output.
Good point, and something I hadn't spotted or appreciated. No need to select between one and the other carriers, just select one or the other and let it pass through the polarity inverter to the output.

That should work. And, with both carriers being the same input, it doesn't matter if the selector does switch between one or the other.

So, using that, one can invert whatever goes into MDMIN, MDCIN1, MDCIN2, and any pins which can pass through a comparator.

There is some overlap with pin functions but it looks like one could invert any of 4 inputs on an 08M2, 5 for 14M2, 6 for 18M2, 5 for 20M2.
 

AllyCat

Senior Member
Hi,

As the title of this thread contains "X2", I thought I'd probably never, in the future, find the discussion on the DSM (which isn't included in X2 chips). :( So I've posted a new Code Snippet based on the ideas above.

In particular for the 08M2, I still think that a single external NPN inverter (for Idle-Low HSERIN) generally gives the most versatility. But I have shown a program there which, by setting the DSM and APFCOM SFRs, can use both HSERIN and HSEROUT communications with either polarity (software-selectable), without adding any external hardware, and still leaving c.2 and c.3 (Legs 5 and 4) available for other uses by the program.

Cheers, Alan.
 
Top