Main Site Documentation

Using Register class for parallel IO


#1

I was experimenting with using the Register class to implement a parallel I/O port.
Chose the FEZ MINI because it has 13 contiguous bits (P0.16 � P0.28) brought out to the headers.
I attached a picture of the timing waveform from my logic analyzer and the code file.
NOTE: The first 2 lines in the Main (disabling the SPI?) were not in the original test�something I added this morning and plan to try out this evening.
The signals (top-to-bottom) are:
CS-Chip Select-ADC1
RS-Register Select-ADC2
WE-Write Enable-ADC3
D0-Data Bit 0-P0.16
D1-Data Bit 1-MISO0 (never changes)
D2-Data Bit 2-MOSI0 (never changes)
D3-Data Bit 3-SD_CLK
D4-Data Bit 4-SD_CMD
D5-Data Bit 5-SD_PEN
D6-Data Bit 6-SD_DAT0
D7-Data Bit 7-ADC0
You�ll notice D1 and D2 don�t change�these are MISO0 and MOSI0 pins�which is my dilemma…all other signals are �as expected�
According to my logic analyzer, the time between CS rise (8 writes) is around 2.15ms so that should result in 3720 single byte writes per second ((1/0.00215)*8)�writing to a 40x24 character display would take around 0.25 seconds(?)
My initial question:
Will clearing the PCSPI bit of the PCONP register disable the SPI and thus cause my D1 and D2 signals to output?

Can’t attach files so pasted code:

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.IO;

using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.Hardware.LowLevel;
using GHIElectronics.NETMF.FEZ;

namespace RegisterTest1
{
public class Program
{
private static uint CS = 0x01000000; // nCS 0xFEFFFFFF Use &
private static uint RS = 0x02000000;
private static uint WE = 0x04000000; // nWE 0xFBFFFFFF Use &
private static uint OE = 0x08000000; // nOE 0xF7FFFFFF Use &
private static uint TR = 0x10000000;

    private static Register FIO0DIR = new Register(0x3FFFC000);
    private static Register FIO0MASK = new Register(0x3FFFC010);
    private static Register FIO0PIN = new Register(0x3FFFC014);

    private static Register PCONP = new Register(0xE01FC0C4);

    public static uint mCurrentDir;
    public static uint mCurrentMask;

// static Register FIO0SET = new Register(0x3FFFC018);
// static Register FIO0CLR = new Register(0x3FFFC01C);
// static Register SCS = new Register(0xE01FC1A0);

    public static void Main()
    {
    // NOTE: These 2 lines were NOT part of the initial test !!!!!!!
        uint lCurrentSPI = PCONP.Read();
        PCONP.Write(lCurrentSPI & 0xFFFFFEFF);

        while (true)
        {
            uint lCurrentDir = FIO0DIR.Read();
            uint lCurrentMask = FIO0MASK.Read();

            FIO0DIR.Write(lCurrentDir | 0x1FFF0000);
            FIO0MASK.Write(0xE000FFFF);

            bool lCont = true;
            while (lCont)
            {
                uint y;
                uint z;
                FIO0PIN.Write(CS);          // CS=1
                y = CS | RS;
                for (uint x = 0x00010000; x < 0x01000000; )
                {
                    FIO0PIN.Write(y);       // CS=1 RS=1
                    z = y | x;
                    FIO0PIN.Write(z);       // CS=1 RS=1 DATA (Setup Time)
                    z = z | WE;
                    FIO0PIN.Write(z);       // CS=1 RS=1 DATA WE=1 (Data Write)
                    z = y | x;
                    FIO0PIN.Write(z);       // CS=1 RS=1 DATA (Hold Time)
                    x = x << 1;
                }
                FIO0PIN.Write(0x00000000);  // Clear all bits
            }

            FIO0DIR.Write(lCurrentDir);
            FIO0MASK.Write(lCurrentMask);
            PCONP.Write(lCurrentSPI);
        }
    }
}

}


#2

I uploaded to projects site…

(link removed)


#3

What you are doing is probably too advanced for most users here. I need to note that before beginners try to use register access.

Even if you are using a register access, you still want to use the built in libraries.
For example, use OutputPort class to make pins outputs and verify that they are all outputs and high for example. Once that is done, you can cheat and add in your register access code that make the port high or low.


#4

I think I got it…

  1. Need another Register for PINSEL1 (pin function select):
    private static Register PINSEL1 = new Register(0xE002C004);
  2. Get the current mode and force GPIO mode for MISO0 and MOSI0 ports:
    uint lCurrentPinSel1 = PINSEL1.Read();
    PINSEL1.Write(lCurrentPinSel1 & 0xFFFFFFC3);

Waveforms are as expected…