SPI problem when writing data in bulk to MAX7456

I’m working on my MAX7456 OSD interface again (temporarily replaced my fried Panda with one from another project). I’m trying to get the performance where it needs to be. In the .Net Micro Framework, that usually comes down to having the framework do as much of the work as possible, especially iterative operations.

The following code snippet, I’m writing text to the display memory. The way I have it now, I’m writing the array of byte[] charValues to SPI in a single step. For some reason, every other character is dropped when I do it this way. When I comment out that line and uncomment out the loop below, it all works fine.


           WriteSPI((byte)Registers.Write_DMM, (byte)(DMM_Values.OperationMode_16bit | DMM_Values.AutoIncrement_Enabled ));
           spi.Write(charValues);
           //for (int x = 0; x < charValues.Length; x++)
           //{
           //    WriteSPI(charValues[x]);
           //    //Debug.Print("Offset=" + this.CharOffset);
           //}
            WriteSPI((byte)0xff);
            WriteSPI((byte)Registers.Write_VM0, (byte)(VH0_Values.Sync_NextVSync | VH0_Values.OSD_On));

// declared elsewhere:

        byte[] spiWriteBuf1 = new byte[1];
        byte[] spiWriteBuf2 = new byte[2];

        private void WriteSPI(byte data)
        {
            spiWriteBuf1[0] = data;
            spi.Write(spiWriteBuf1);
        }

        private void WriteSPI(byte reg, byte data)
        {
            spiWriteBuf2[0] = reg;
            spiWriteBuf2[1] = data;
            spi.Write(spiWriteBuf2);
        }

If the performance difference wasn’t so massive, I wouldn’t worry about it. But I need the SPEED.

I’m not sure if the OSD is busy and is dropping the data, or if there’s some kind of weird timing issue going on. I tried slowing the transfer rate, tweaking the SPI parameters for HoldTime, SetupTime, etc. (But I can’t say I exhausted the options there.) I know the MF SPI interface supports a busy bit but the MAX7456 doesn’t. I have a hack going now where I write a ushort instead of a byte so I’m still dropping but just spacing out my data. But I’m wasting cycles formatting the data that way so it’s still slow.

Does anyone have any ideas on this?!?!

Here’s the SPI setup config I’m using now:


SPI.Configuration(pin, false, 0, 0, false, true, 10000,module)

Your chip expect a CS toggle on every byte?
Is your OSD chip expecting 16 bit and this is why you see every 2 bytes?

If your problem is not in delays then it is in how CS is used. First code does CS once for all bytes where the second does CS on every single byte

@ Gus – I think you’re right… I think it was a CS toggle after every byte when writing this mode. Look at figrue 21 on the data sheet (http://datasheets.maxim-ic.com/en/ds/MAX7456.pdf) and I think you can read it this way.

The first code block is SOOO much faster than the second, I really want to make it work. Is there way to toggle CS on each byte without looping in c#?

It almost seems like it’s not actually setting 16bit mode. 8bit mode would expect the extra attribute byte which would explain why every other char is printing or just spaced out with the uShort. Try creating a byte buffer with a few chars setup as 8bit mode using the 2byte attribute/char for each character and see what happens.

Maybe the single byte version works because when the CS is pulled, the chip assumes it’s a complete data pair for that address and uses it as the char byte then advances the address counter. Either way the auto-increment is working but something else is missing.

I’m pretty sure I’m in 16-bit mode (confusing name because it reads data in 8-bit sections), but I’ll experiement with it more. I’ll try going into 8-bit mode and try combinations of a few things.

What’s strange is that it seems to work if I loop through the byte array but not if the MF does it for me. I don’t have a logic analyzer so I can’t see what’s really going down on at the pin level.

I think I have my answer on why this wasn’t working: the OSD wants CS high to latch the data. For some reason, sending 16 bits latches the data too, but I have to do a <<8 shift for each character to make that work, so I still have a loop that iterates through each of my characters which slows me down. Wit this extra work, I’m topping out at 5-6 FPS with nothing but GPS and OSD functions running. That’s not fast enough and I need cycles for IMU processing, PID, etc. :frowning:

so I’m not sure where to go from here except to keep experimenting to see if I can hack up something faster.

so it works on 16-bit but you have to shift every byte up or you have to CS on every byte…hmmmmmmm

Are positive there is no command you can send to reconfigure the chip to use 8bit?

8 bit works, but only if CS is toggled high after every byte. Otherwise, sending another 8 bits forces the register to latch.

@ gus – OK, I made good–as promised, I just posted my high-performance MAX7456 driver to Fezzer: http://www.fezzer.com/project/170/max7456-high-peformance-driver/ Video is included.

I had to end up using ushorts almost everywhere. it wastes space but it’s SOOO much faster to send the array of ushort than writing to SPI in my own loop. I also moved to a buffered operation so I can write the entire screen buffer in a single SPI call which saves a ton of overhead. Managing my own display buffer also lets me reuse buffers for character conversion in a few places to avoid unnecessary visits from the GC.

Where is the video? :wink:

it’s on Fezzer and has been since it was originally posted… :wink: Gus, did you check ?

I didn’t even know we have a video feature on fezzer lol

:naughty:

You should talk more often to Josh :smiley:

Andrejk, did you directly interact with the MAX chip or use the sparkfun breakout board? Did you need to do any level conversions to use SPI with it?

I’m hoping this will work since this sounds similar to Fez: http://blog.theroyweb.com/max7456-bus-pirate

I am happy to report this code works great once the resistor combo is on the MISO line as described in the above link.