9 Replies Latest reply on Oct 28, 2016 7:56 PM by pach_1977636

    Tristate data bus drive best approach?

      Hi folks,


      I'm looking at using a PSoC MCU (current candidate is CYBLE-214009), to add modern connectivity and capabilities to a vintage hand-held computer.


      To interface, I'm attempting to make the MCU emulate RAM/ROM (original RAM has 200ns access time), and read/write data, instructions, and status into/out of it over a range of addresses.


      I think I'll be able to read the address bus with a status register and using an external pair of bus switchers to read the 16 bits in two 8-bit reads.


      For the 8-bit data bus, I need a tristate interface so I can read or drive the data bus, depending on the value of the R/W signal from the handheld. It looks like older PSoC devices supported an EMIF device that would have been a ready-made solution for this, but, for some reason, this is not supported for PSoC 5.


      What am currently thinking are 8-bit control and status registers, connected together through a bufoe per bit, and then to a bidirectional pin per bit. The bufoes will have their OEs connected together and to the R/W signal from its input pin.


      First of all, will this work? Are there any special configuration settings required in the registers or in the bidirectional pins to make all this act like tristate?


      Secondly, is there a way to make hooking these devices together easier and cleaner? Already with just one bit connected it looks pretty messy on the TopDesign view.






      After reading through the Using GPIO pins document, I'm wondering whether I actually need the bufoes. It seems like I should be able to hook both registers directly to the I/O pins, and set their behavior through the BIE registers (1 = OE, 0 = Hi-Z). Is that correct? 


      EDIT 2----------------------------------------


      I tried a couple of tests:


      First one with a Bufoe, a bidirectional pin, and three registers (one to set OE of the Bufoe, one for Control output, and one for Status input). This worked fine to alternate between driving a strong drive output and reading a strong drive input. I guess there's some magic that hooks the Bufoe OE to the drive mode of the bidirectional pin.


      Second was without the Bufoe and just connecting both of the registers to the bidirectional pin. In this case, I was trying to directly set the drive mode of the pin at runtime (Hi-Z to read, and Strong to write). However, this code fails to program due to "Multiple drivers" on the line connecting the bidirectional pin to the two registers.


      So, at this point, the setup with a bank of Bufoes seems like the better bet. Code-wise it will probably be easier, though it will certainly be messier on the layout. Any other thoughts? Is there some reasonable way I can define my own component with 1 to n bits of Staus register, Control register, and Bufoe?

        • 1. Re: Tristate data bus drive best approach?

          You do not need control and status registers, set pin's property "Number of pins" to 8 and read all pis with a single API Pins_Read().


          Same for writing all 8 pins. Set only oe externally or using a status register. Wire all oe's on topdesign sheet, so there is no impact on the PCB.





          • 2. Re: Tristate data bus drive best approach?

            Thanks. I'll give that a try.


            So, when I do Read() or Write(), with a UINT8, that will automatically map to the bit values for each pin? 


            Sorry, one other NOOB question: how do I make the bidirectional pin OE show as a connection on the design sheet? You mention wiring them, but so far I've only seen how to set them through BIE in code. 

            • 3. Re: Tristate data bus drive best approach?

              "BIE" What's that??


              When the pin is defined as output, you can select OE. Search in pins datasheet for "output enable"





              • 4. Re: Tristate data bus drive best approach?

                // Set P0[0] to bidirectional mode


                CY_SET_REG8(CYDEV_IO_PRT_PRT0_BIE, 0x01); 




                OK, I got it working sort-of the way you describe. I was adding bidirectional pins, I didn't realize I needed to edit the pins and set them to input AND output, instead of bidirectional. Then I was also able to check the box to make the OE pin available.


                I got an error with the pins not connected to registers, but I think that's because I had left them HW controlled. So right now they are connected to status and control registers. Is there any advantage or disadvantage to using the registers? 

                • 5. Re: Tristate data bus drive best approach?

                  I looked at running just with a set of software controlled pins, but that adds a lot of work in that I have to set and read each bit individually... I guess that's what registers are for. :-)


                  So, at this point, I think I'm good to go with the Input/Output HW pins and associated registers. Thanks for the help.

                  • 6. Re: Tristate data bus drive best approach?

                    When you use MyPort_Read() for a pins component that has got the number of pins set to > 1(max is 8), you get a binary pattern that reflects the actual pin's states. Give it a try...





                    • 7. Re: Tristate data bus drive best approach?

                      I see. Not an option, though, as, while the eval module is on the Pioneer board, I don't have 8 pins available from a single port. 


                      When I start doing my less limited testing, with the eval board off of the Pioneer, I may be able to allocate the 8 pins of port 3 together (looks like the only 8-pin port on this device). Are operations on contiguous sets of port pins faster than those on a register of mixed pins? If so, I'll definitely try to keep them together for the address bus, to make the two reads happen as fast as possible.




                      I saw in the Using Pins document the comment that the 8-pins grouped should have been accessible as a logical port. Mine is called Pin_Data. But, when I was editing the code, I did not see Pin_Data_Read() in the function list... only Pin_Data_0_Read(), Pin_Data_1_Read(), etc...

                      • 8. Re: Tristate data bus drive best approach?

                        When you get stuck, please post your complete project, so that we all can have a look at all of your settings. To do so, use
                        Creator->File->Create Workspace Bundle (minimal)
                        and attach the resulting file.





                        • 9. Re: Tristate data bus drive best approach?

                          The documentation would seem to be inaccurate, or I am missing something. Today I rearranged my project to allow it to run removed from the Pioneer board. This freed up enough pins that I could map AD0-AD7 to P3.0-P3.7 (the only set of 8 pins on one port on the CYBLE-214009.) After I did that, I still had no Pin_Address_Read() function. I then went into the designer and checked Contiguous. This consolidated the 8 pins in my pin assignment view, and, after a build I now do have Pin_Address_Read as an option.


                          The using pins document for PSoC says this: "In PSoC Creator, you can organize a group of as many as 36 pins into a logical port, which can then be referenced in code by the port’s defined name. All the pins may be part of the same physical port, or they may form separate physical port."


                          It would seem, that to get all the functionality, they must be on the same physical port.... or, at least be contiguous across adjacent ports (I didn't try that.) I can confirm that this doesn't work if they're scattered.