GPIOs seem to be linked

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hi folks,

I have this PSoC 5LP project that's acting a bit weird. Basically, when I read data from port 3 (8-bit bus with 3.0 - 3.7), things work fine as long as 3.7 is low. When 3.7 goes high, it seems like 15.4, or my Pin_RW logical connection, is always being pulled high as well.

The PSoC in this case is on a CY8CKIT-059. I have removed the LED, CMOD cap, and SAR caps. The device is emulating RAM to interface with an old CPU (LH5801). I see the issue when I try to POKE values > 127 into the MCU. Value below 128 work fine, and I no problem reading any data value from the MCU. Addresses also don't have problems with the upper bit. When I try to write data > 127, though, the MCU acts as if R/W never went low. No write occurs.

I did also check resistance between 3.7 and 15.4. It's about 3 MOhms.

It's a bit tricky to troubleshoot, because the system needs all its clock cycles to work properly. Debug makes it too slow.

Any ideas on what might be happening here?

Thanks,
Paul

0 Likes
1 Solution
Anonymous
Not applicable

OK. A bit more experimentation... it's definitely a timing issue. I played around a bit with switching between PS and Read() and reordering the reads, and I managed to make it worse and sporadic in reliability, but never any better.

I guess that the timing is a bit different for some reason on either when the data bits are stable or when the R/W line goes low when the data starts with 1000.

This seems to be the most reliable way to get the data out of the iterations I've tried:

    for(;;)

    {       

        if (Status_CS_Read())

        {

            laddress = Pin_Address_Low_Read();

            haddress = Pin_Address_High_Read();

            data_read = Pin_Data_Read();

            rwpin = Pin_RW_Read();

I tried adding a 1us delay before reading the data, but that was definitely worse.

Is there a way I can quickly and cleanly latch these input values one microsecond after Status_CS_Read goes true?

View solution in original post

0 Likes
5 Replies
Anonymous
Not applicable

I did a bit more experimentation and have narrowed things down a bit.

The issue occurs when trying to poke values that have 1000 for their upper four bits. Values below 128 work fine, as do those above 143.

I also tried using Pin_Data_Write instead of Pin_Data_DR, and I tried switching the pins from Transparent to Double-Synched. The first made no difference, and the second blocked the computer this is connected to from even turning on.

BTW, I have two of the PocketPCs that this module is supposed to work with. I have tried it on both and seen the same behavior.

0 Likes
Anonymous
Not applicable

OK. A bit more experimentation... it's definitely a timing issue. I played around a bit with switching between PS and Read() and reordering the reads, and I managed to make it worse and sporadic in reliability, but never any better.

I guess that the timing is a bit different for some reason on either when the data bits are stable or when the R/W line goes low when the data starts with 1000.

This seems to be the most reliable way to get the data out of the iterations I've tried:

    for(;;)

    {       

        if (Status_CS_Read())

        {

            laddress = Pin_Address_Low_Read();

            haddress = Pin_Address_High_Read();

            data_read = Pin_Data_Read();

            rwpin = Pin_RW_Read();

I tried adding a 1us delay before reading the data, but that was definitely worse.

Is there a way I can quickly and cleanly latch these input values one microsecond after Status_CS_Read goes true?

0 Likes
Anonymous
Not applicable

Seems like there are probably better ways for me to capture these 8-bit writes.

I would think that I could create a UDB-based 8-bit latch and clock it from the falling edge of the R/W signal, then read from that in my code.

Or, maybe I could use DMA to directly handle such writes (and reads?) without the CPU at all...?

Any advice here? Thanks.

0 Likes
Anonymous
Not applicable

Banged my head against the wall for a while today. I tried adding DMA, and nothing worked anymore. The MCU was killing my PocketPC. Long story short, the issue was fanout. One UDB AND gate was an OK load for the R/W signal. One AND plus one inverter was too much. Changed to feed just the one inverter, and then a second inverter before the AND gate, and it's working again.

Now have DMA just writing to one byte, and that seems to work. Need to get my array address deferencing and offsets straight to hook up a wider range of addresses... looks like DMA will work. (fingers crossed that it will be fast enough under all circumstances).

I switched to PSOC 5 because PSOC 4 wasn't fast enough to process reads and writes in a loop, but DMA might allow me to move back to PSOC 4, which would be great because I'd really like to use the onboard BLE.

0 Likes
Anonymous
Not applicable

OK. Next question: is it possible to have a dynamic destination address for DMA? In my project, I have a 16-bit address bus that I'm reading in two 8-bit chunks. I'd like to use this address to define an offset into an array for the destination of the byte received during a DMA operation.

This is what I have now::

CyDmaTdSetAddress(DMA_1_TD[0], LO16((uint32)&Pin_Data_PS), LO16(((uint32)buffer+(((uint32)Pin_Address_High_PS & 15) << 😎 + (uint32)Pin_Address_Low_PS)));

In the above case, buffer is the base address of a [16][256] uint8 array. This doesn't work.

This (going to a single uint8) does work:

CyDmaTdSetAddress(DMA_1_TD[0], LO16((uint32)&Pin_Data_PS), LO16((uint32)buffer));

Worst case, I could use an interrupt to transfer each read byte somewhere else, but, again, I think that might be too slow. Is this what Indexed DMA is for? Is there a code example of that?


BTW. Could someone maybe change the title of this thread to: options for sharing PSoC memory with external devices or somesuch?

Thanks.

0 Likes