Unconventional baud rates in USBizi and Fez

Hi,

I’m interfacting with an RFID reader that uses 15625 baud. When I use this to open COM2 I get data but also framing errors.

Will the board actually implement that baud rate or default to a standard one like 14400 or 19200?

Rudie

We calculate and set any baud rate but you may end up with divide fraction.

You can set the baud manually by writing directly to the uart registers.

Hey, realiser, good to see you here. Had to go back to the Spark forums to make sure that was you.
Blue Hair Bob

Hi BHB! Nice to see you here too. Hope you’re working hard on your Spark project (www.embeddedspark.com) :slight_smile:

This thing is driving me nuts. Maybe someone can help?

I’m using the following datasheet as reference:

I’ve got it working to the point where I get data back from the module. I’ve figured out that it uses 7 data bits - not 8. The problem is it has no stop bit - so that explains why I get framing errors. It’s not standard Async.

I gave up using the Serial port for this - so on to plan B.

What I’m doing now is to capture the transitions using an InterruptPort and a buffer. It works pretty well (with a catch).

    _SCIOInt = new InterruptPort(this.SCIOPin, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
    _SCIOInt.OnInterrupt += new NativeEventHandler(_SCIOInt_OnInterrupt);


    void _SCIOInt_OnInterrupt(uint data1, uint data2, DateTime time)
    {
        if (data2 != 0)
        {
            _EdgeLog[_Index] = (int)(time.Ticks - _StartTicks);
        }
        else
        {
            _EdgeLog[_Index] = (int)(time.Ticks - _StartTicks) * -1;
        }

        _Index++;

        _SCIOInt.ClearInterrupt(); // According to documentation this is supposed to give exception on both edges but it doesn't.
    }

Look at the attached trace from the logic analyzer - and my captured data. I use a -minus sign to indicate the pin was low when the interrupt happened.

Tick Delta
25223 25223.00
-28432 3209.00
29342 910.00
30321 979.00
-31232 911.00

So it almost works out… It says:

  • It started low and went high after about 2.5ms (delta from start = 25223)
  • It stayed high and went low after 3ms (delta 3209)
  • It stayed low then went high after 1ms (delta 910)
  • It stayed high then went high after 1ms
  • It stayed high then went low after 1ms

So you can see there’s something wrong there.

What I don’t understand is how it can have high to high transitions. The only explanation is that somewhere it gets busy with something and misses one of the transition interrupts. You can see on the trace there are 4 transitions but I’m only catching 3.

The tick resolution seems fine enough to use this method to capture and decode the pattern, but how do I force it not to miss one of the interrupts?

Is there perhaps a better way to capture such a signal? Maybe the reverse of OutputCompare? There’s no InputCompare in NetMF.

I promise to contribute a driver for this RFID reader if the forum will help me get it to work :slight_smile:

Rudie

@ realizer

ClearInterrupt(), according to the documentation, is to be used with level interrupts, not edge interrupts.

You are using edge interrupts. Take out the ClearInterrupt and see if that helps.

BTW, the current SDK does not support level interrupts.

Thanks Mike, but that’s not it. I tried it before with and without the ClearInterrupt - no difference. I also noticed that even if I use NoInterrupt, it still fires the interrupt.

I’m using 4.0 if that makes a difference.

Plan C is to go straight to the metal… Can I do inline assembly with NetMF?

Plan D is use a PIC or AVR to interface to the RFID chip and translate. With all the power of the Fez board that would be a disappointment.

Using inputport is a bad idea. You can tweak the uart to any baudrate and make it 7 bit. Search the wiki for ax12 servo motor project for exame

Thanks Gus.

The problem is the data stream has a start bit but no stop bit, so the UART rejects the data at the hardware level.

There’s really no other way than sampling the data and decoding it myself - like they do with RC pulses.

Is there a better way to do it than with InterruptPort?

I have one more option because the module supports a synchronous mode for reading. I’ll try this because it is not timing sensitive. What’s ridiculous about this is that you must first send a command byte asynchronously to put it into synchronous mode - so back to square one with that. At least I can do that pretty accurately in “bit bang” mode using OutputCompare.

I’ll let you know how it goes.

[quote]
There’s really no other way than sampling the data and decoding it myself - like they do with RC pulses.[/quote]

Have you looked at the LPC23xx user manual and verified that you can’t change it to 7 bit?

The problem isn’t setting it to 7 bits - that actually works. What happens is that there is no stop bit - so it can’t find the end of the byte. There’s also no way that I can see to say “ignore the stop bit”.

Am I missing something obvious?

I see, maybe with assync. you can use SPI?

Thanks for all the help so far everybody. Slowly but surely I’ll get there :slight_smile:

What I tried now is to use the Synchronous mode - so I can control the timing by clocking in the data myself. Or so I thought.

If you look at the trace you’ll see that the module is waiting for me to clock the data out, but it is impatient. I just can’t clock it fast enough until it wants to go to the next byte.

The code for clocking the data in goes like this:


            while (_ReceivingData)
            {
                _TXCTout.Set(true);
                state = _SCIOIn.Read();
                _TXCTout.Set(false);
                i++;

                if (i > 640)
                {
                    _ReceivingData = false;
                }
            }

I used the OutputCompare before to generate the byte to put it into Sync mode - which worked great. That’s why I use _TXCTout.Set to toggle the pin.

Trouble with this is it is too slow. It looks like one cycle of the loop is about 180 us. It needs to be about 60 - 100 us max.

So where to from here?

I’ll try SPI next - so I’ll clock the data in using hardware. The catch with this is the following… I must start clocking in the data within 128 us after the module pulls the data line high. I’m struggling to get anything to respond that fast. Even using an interrupt, it responds too late. I’ll keep on trying.

The next option is to try and write a native routine. Can anyone point me to how to do this? How is it compiled so it can be called from C#?

Rudie

Tried the SPI - but there’s a catch (again!).

The minimum frequency I can use via the built-in SPI object is just under 150kHz before the framework gives an exception. I need it to be much slower than that - around 16 kHz.

I went low level and started playing with the registers directly. By the way, it uses the SSP module - not SPI on the Fez Domino.

The rest of this post is long and technical, but it explains where I’m stuck at the moment, so bear with me please…

What’s happening is that 150 kHz is getting close to the limit for the clock timer before it overflows - and generates the exception.


            SPI.Configuration spiConfig = new SPI.Configuration((Cpu.Pin)GHIElectronics.NETMF.FEZ.FEZ_Pin.Digital.Di0, false, 0, 0, false, true, 1000, SPI.SPI_module.SPI2);
            SPI spi = new SPI(spiConfig);

            Register regClockRate = new Register(0xE0030000);
            Register regPrescaler = new Register(0xE0030010);
            Register regPCLK = new Register(0xE01FC1A8);

The 1000 kHz in the config translates to a value of 8967 for regClockRate. 150 kHz translates to 61191 - so it is approaching overflow for the counter.

Looking at the value of regPrescaler.Read() I get 2 - the minimum value for the prescaler - so the simple solution is to set the Prescaler to a higher number.

This changes the value:

regPrescaler.Write(10)

BUT when I execute this line…


spi.WriteRead(writeBuffer, readBuffer);

the prescaler register jumps back to 2.

So basically the framework sets the prescaler somewhere inside and I can’t override it.

I changed the master peripheral clock PCLK which had some effect, but I’m not so keen on doing that because it messes up the timing of all the peripherals and I have no idea if the framework will be affected in some way.

The question now is how to override WriteRead to not overwrite the prescaler or how to send the data to SSP myself.

Can anyone help?

The internal SPI driver sets everything in every loop. Do not use the built in drivers. You are very close, do not give up

I’m getting close. I can now send data at my own rate over SSP with control over the registers. I’m yet to see if I’ll be able to control the data coming in with the desired timings. It needs a short delay between bytes in the clock stream - like this…

---------------------

Is it difficult to use DMA? Is there an example somewhere? With all this I’m thinking I might as well create a little library to do high speed data capture. With 2 SSP ports and DMA it shouldn’t be too hard to make a simple 2 channel logic analyzer with decent performance.

NXP ships a zip file that have all kind of example code for their processors

This is where I throw in the towel.

I got very close to cracking this by sampling using SSP. It turns out that the RFID module is super sensitive to timing down to the microsecond. Using managed code it is just not possible to control that kind of timing. I need to wait for the SCIO line to go high and then respond with a clock signal on TxCT about 32 uS later. Managed code just can’t do that.

An alternative approach that almost worked was to use the SSP module as a “logic analyzer” and sample the asynchronous data at a known clock rate. This got so close… but for some reason the hardware seems to introduce a short delay between transmissions and this messes up the capture of the 128 bits in the stream.

I’m going to have to use a PIC to create a helper that will communicate with the module and send the data to Fez using a regular serial port. It feels so wrong, but this is the end of the road for me on this particular challenge - at least until RLP comes to the Fez Domino.

What about a $0.20 PIC10?

Indeed - but do you see my frustration here? There’s 72MHz of ARM processor running with dozens of free IO’s, heaps of free program space - and no (simple) way to get to it at the low level. This was more a matter of principle… I wanted to prove to myself that NETMF can give me a complete solution. I can easily implement the entire solution on PIC, but I don’t want to… I want to use NETMF.

Anyway - at least I’ve learnt the current boundaries of the platform and my abilities. As time goes by and NETMF matures (with GHI libraries), I’m sure this is going to be a simple problem to solve in future.

Now where did I put that PIC programmer… :slight_smile:

You have a very specialized case. That chip requires some very tight timing to work. Even if you were to program it natively you will run into problems…unless you disable interrupts on the entire system.

Most chips I have seen follow a standard… SPI, I2C, UART, OneWire, CAN … we support them all!

I still want to learn more as you move forwards