You are here

Very inconsistent read behavior | Cypress Semiconductor

Very inconsistent read behavior

Summary: 3 Replies, Latest post by paul.chambre_1977636 on 30 Oct 2016 07:32 PM PDT
Verified Answers: 1
Last post
Log in to post new comments.
paul.chambre_1977636's picture
User
45 posts

I feel like there must be something simple I'm overlooking, but I'm having a ton of problems reading data with this project.

This is (supposed to be, some day) a helper module for an old pocket computer. CS enables the MCU when low (from address and chip select decoding off of the PC bus). This fires an interrupt handler. That works perfectly.

From there, I need to read other input pins, like the Address set, and the R/W pin. Right now I'm mainly focusing on the R/W pin. I've tried changing it to software controlled and added a register for the OE. I've tried changing its sync. I've tried disabling its buffer. Nothing seems to make it work correctly. Basically, most of the time it reads RW at 1 (high) regardless of whether it is or not. Occasionally it will go through periods of reading it as 0, again, regardless of the actual value. At one point, while it was reading 0, I disconnected the PC and attached a pull up to VDD. I could read 4.54V on the solder join on the eval board, but a debug breakpoint was still showing the value as 0. That had me thinking that I had blown the MCU or something, but, that was when I tried switching to software and a register... and that changed it to reading 1 all the time. Later, changing back still left it as 1.

It's frustrating, because writing data onto the bus is working pretty well. However, not being able to read anything has me completely blocked.

I may try retargeting for one of the other eval modules, just to rule out a blown MCU...

Edit/update:

I did try putting the 214009 back on the Pioneer board and programming a simple LED flash app to test reading P0.4 and P0.5. Both of them read correctly when being used as software pins in that setup. I then switched the input pins to P3.3 and P3.2, and they read fine as well. So, apparently, it's something in my project and not a blown MCU. Is there something about interrupt handling that interferes with pin reads?

user_242978793's picture
User
1030 posts

Increase your heap in both programs to 0x200.

paul.chambre_1977636's picture
User
45 posts

Thanks. I think that helped. It seemed to make a difference anyway, and allowed me to make progress to the point that I can read an address under strict conditions.

The conditions seem to have to do with timing and performance.

I call this function as soon as my interrupt handler starts:

void ReadAddress()
{
    //for now, we'll just make a single-pass address read and dummy the wait
    //address = 128;
    laddress = Pin_Address_Read();
    //CyDelayCycles(2); //Pretend we're reading the upper 8-bits...
    //address = address * 256;
    address = 0x8000 | laddress;
    //address = address | Status_Address_Read();
}

As the project is now, if I'm running the debug branch, I can successfully read the currently connected (4 lsb) address bits. However, if I add even 1 to the CyDelayCycles, I don't get my processing done in time, and I basically get zeros or intermittent address reads.

I tried switching to the release branch and adding exhaustive speed optimizations, and, there, I do seem to be able to add delays and still get a good read. The delays are because I only have 8 GPIO pins to read the 16 address bits on this device (which I would like to use because of its compact and simple implementation on the board), and I'm going to need to switch the 8 pins from the low to the high half of the address with external bus switchers to get the whole thing.

I'd appreciate any advice or pointers to articles anyone has on performance optimization and timing synchronization for such bus interaction.

Thanks,
Paul

 

P.S. I just found one interesting thing. In trying to enable the write section of my code, I was breaking read... again because of timing. Reading the R/W bit and making decisions based on its state was delaying things. However, I was able to get it working (though it's not doing much yet). The difference was between:

    mode = CyPins_ReadPin(Pin_RW_0);
    //mode = Pin_RW_Read();

Looks like CyPins_ReadPin is a lot faster than calling the logical pin read function... at least for a single pin.

P.P.S. It would probably be helpful to know that the pocket PC in question is a Sharp PC-1500. The CPU is an 8-bit CMOS device running at 1.3MHz. Access time for system SRAM is 200ns.

One other update: I got suspicious that the speed optimizations might be ignoring the CyDelayCycles call... and that does seem to be the case. I cranked it up to 1024 or so, and it made no difference; but, by adding a second call to Pin_Address_Read() and one pin write to an output (to include the actual timing that would be involved in bus switching to read the whole address), I once again broke my test code.

Is there really much performance gain to be had by creating custom UDBs to handle the address and data busses, or am I better off switching to a device that has more GPIOs, so I can at least have contiguous blocks for these busses and avoid the bus switching?

paul.chambre_1977636's picture
User
45 posts

Over the weekend I retargeted my project to the CY8C4247LQI-BL483 that came with the Pioneer board. that allowed me to map Address Low, Address High, and Data each to their own port and use the direct read and write functions on the full bytes of the ports instead of through registers. I would think/hope that there are some speed advantages to working with a port at a time instead of pins scattered across ports. In any case, it's looking like this might be fast enough, at least to read the full address. It was failing my Hello World test until I recompiled with full optimizations... but I am using the data from Address High, so I don't think the optimizer is hiding anything from me.

If (and this is the big if) I can also read the data bus and R/W bit in time, then this will work for my needs, as everything else the MCU would need to do could be done asynchronously from the PC's CPU. I can't tell yet whether the data read is working... as I have not yet gotten a POKE to work in any recognizable fashion. I am not sure yet whether this is because there's still a problem with my code or design, or if there might be some safety checks in the POKE command that prevent the user from POKEing non-RAM addresses. OTOH, even though I'm clearing my buffer before writing HELLO WORLD into it, space after the test message does contain non 00 data. I'm not sure how that would get there other than through PC activities that are attempting to write into that space (my write function only accepts writes to buffer bytes after the HELLO WORLD characters.) On the third hand, of course, I have no way of knowing if these garbage bytes have the values that the PC CPU intended to write. :-)

Next step is probably to hack up some LH5801 machine language to try writing into the buffer, and see what happens... 

Log in to post new comments.