News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_zhulien

CPC / Raspberry Pi Bridge Card

Started by zhulien, 14:14, 08 May 16

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Bryce

Quote from: zhulien on 06:24, 13 September 16
I have ordered my Xilinx programmer and a couple of GODIL's to see what I can do... will keep you posted

Did you order a real Xilinx programmer or a Chinese knockoff? If it's a Chinese one, be very careful not to click yes if it asks you to update the firmware!

Bryce.

zhulien

I ordered a real one, sadly they aren't cheap (the USB cable 2) but luckily got a good price on ebay... with luck it should be working fine as advertised.

the plan:

- put a z80 core into the GODIL and see if CPC works as per normal (this is the biggest risk of it not working before enhancing the core)

- enhance the z80 core to have a turbo mode as follows:
    - new instructions switch between normal and turbo mode and to copy RAM or perhaps just page the internal FPGA RAM at slow CPC speed for it to do normal speed memory transfers
    - normal mode, it executes code from normal CPC RAM at normal CPC speeds with normal Z80 behaviour using the external clock
    - turbo mode, it executes code inside the FPGA with RAM also inside the FPGA at fastest possible using an internal clock but pretending to satisfy the rest of the CPC's timings with nop behaviour

- connect the PI to the additional 4 I/O pins

Can anyone see any flaws in this approach?

Gryzor

Quote from: Bryce on 08:20, 13 September 16
Did you order a real Xilinx programmer or a Chinese knockoff? If it's a Chinese one, be very careful not to click yes if it asks you to update the firmware!

Bryce.


Oh, the ones that get bricked? 

Bryce

Quote from: Gryzor on 11:28, 13 September 16

Oh, the ones that get bricked?

Yup, the new Firmware bricks them.

Bryce.

TFM

Quote from: Bryce on 08:20, 13 September 16
If it's a Chinese one, be very careful not to click yes if it asks you to update the firmware!


Why?
TFM of FutureSoft
Also visit the CPC and Plus users favorite OS: FutureOS - The Revolution on CPC6128 and 6128Plus

Gryzor

If I recall correctly from what Bryce had told me many moons ago, the firmware is the original one and it can distinguish between an original device and clones, so it'll brick the clone. Hope I remember this correctly.

zhulien

#31
My xilinx programmer arrived... now awaiting the 2 GODIL fpgas...


2 GODIL's arrived :D 


First to work out which way they go in and ensure they are safe by default in a CPC6128 (I'd rather that die than the Plus)...


will keep you all posted, if an FPGA can truely clone a Z80 I can see no reason it won't work at least if the core is compatible enough.

zhulien

Here is a good article on ICE on the GODIL Home · hoglet67/AtomBusMon Wiki · GitHub

I am hoping to give this a try this week if i get the time.  It will prove if it can work or not.  Interestingly,  this page shows that it can work on a Spectrum +2 but not a Spectrum 48K (I don't know much about spectrum board revisions) - so there is still some hope that some CPC can run a GODIL.  Now apparently there is about 40kb of RAM in it which could be used as a fastRAM.  There are other possible uses for a GODIL if it works too, such as... it could be used to run things like gameboy games on a CPC - since even Minimig can run on the same FPGA core it seems maybe other CPU cores could be in there.  Anyway, first see if the things work in some form on a CPC, then we can play with the ideas.

ICE T80 · hoglet67/AtomBusMon Wiki · GitHub

zhulien

things a bit slow here, i ended up ordering 2 ZIF sockets and also a few Z80 sockets because the GODILs are quite expensive and don't want to lose pins in the Z80 socket.  The ZIFs have arrived, not yet the Z80 sockets - Seems I need to build a small breadboard circuit to program the GODIL the first time to ensure no wrong voltages get applied to the CPC.

zhulien

#34
I have put together what i think would be the GPIO mappings from a Pi to CPC.  A couple of things I am unsure of on the CPC side.  I am hoping one of you with more CPC hardware knowledge than me would be able to give some feedback.


https://docs.google.com/spreadsheets/d/1bS1CLDIN0jPP3GI2pCcTU7_VIf2otQ10bVm-NL0F2eQ/edit?usp=sharing


The Pi Zero or Pi B+ has 40 GPIO ports we can use:


- For the Pi to be able to map into the CPC address space, have I missed any CPC bus signals we need? 
- I have hijacked 2 address lines (2 lower bits of the upper byte) and set them always high, is that ok?
- Does hardware have to somehow detatch from all bus activity if it isn't the active hardware, I am guessing i have missed something here?  Is there like a latch that if this device sees an IO request for it's port, then it switches in or something?


I am hoping the Pi could map into the address space, preferably as a 16kb chunk (8kb if i have to forego another bit, or even 4kb forgoing another 2 bits)...  There are 4 Level Converters to allow the Pi GPIOs which are 3.3V to connect to the 5V CPC.


If there is an interest in a Pi Zero or such connected to CPC, then maybe this could be worked as a MX board, but this is early days...

zhulien

#35

Below is an example PI logic.  My only hardware projects have been dumb things in the past with switches light bulbs etc.


As I have never simulated hardware before, I am guessing the behaviour but trying to think in hardware terms.  I usually think in software.
Of course, with the lack of GPIOs I can't simulate a DkTronics memory expansion, but some other wonderful things are possible.
I am assuming mapping it always into #8000 - #C000.  This allows quick data transfers from normal video memory as well as 16k banked RAM within #4000 - #C000.
In my questions at the bottom, if I need BUSAK, then I will need to sacrifice another GPIO of the address space, unless I am better to replace RAMDIS with BUSAK.  Also if the clock has a use, eg: timing PI operations with the CPC?


My thoughts are as follows... Allowing the PI to have mapped I/O as well as memory, I can use the memory for quick transfers in a similar way Duke's Wifi Card does it from using ROM space of the CPC.  The I/O will tell the PI what I want to do, then, the memory will let me read and write chunks of data.


Am I on the right track so far?


[logic removed as will change until it is right]



questions:   can IORQ and MREQ be high at the same time?
         do i even need RAMRD if I don't need to know about ROM state?  I can reclaim a bit if I don't need RAMRD...
         when the PI sends data to the CPC, how long does it need to keep the databus high?  How does it know when the CPC got the data? BUSAK?  Maybe BUSAK is more important than RAMRD?


Here are the level converters I am thinking of using.   They are not expensive, and needs 4 of them per board.  http://www.ebay.com.au/itm/301893252205?_trksid=p2060353.m1438.l2649&ssPageName=STRK%3AMEBIDX%3AIT
Should I have any other hardware to protect the CPC or the PI?  Or just 4 of them wired to the buses and nothing else?


There are multiple PI boards with the 40 pin/28 GPIO interface.


PI 2b:      https://www.raspberrypi.org/products/raspberry-pi-2-model-b/
         900Mhz Quad Core CPU, 1GB RAM, 4 USB, Full HDMI, Ethernet, Audio, Micro SD, 3D Graphics
         
PI 3b:   https://www.raspberrypi.org/products/raspberry-pi-3-model-b/
         1.2Ghz Quad Core CPU, Wifi, Blutooth, 1 GB RAM, 4 USB, Full HDMI, Ethernet, Audio, MicroSD slot, 3D Graphics


Imagine... RSXs for BASIC and Z80 code libraries on CPC which produce awesome 3D graphics in Full HD resolution!!!  Then... I will see if Symbos will support this too ;)

zhulien

#36

Pi-side Logic:


PI_RAMADDR_START = #8000
PI_RAMADDR_END = #BFFF
PI_IOADDR_UNMAPPED = #0001   ; used as both the I/O address and mode status
PI_IOADDR_MEMORY = #0002   ;
PI_IOADDR_MAPPEDIO = #0003   ;
intPIMode = PI_IOADDR_UNMAPPED
blnInRead = false
blnInWrite = false
Set (ALL GPIOs) BCM0 to BCM27, GPIO0, GPIO1, GPIO5, GPIO21 to INPUT
Set GPIO_RAMDIS to OUTPUT
;Set GPIO_RAMDIS to LOW ;NOT REQUIRED?


while (1)
{
   Read (iorq) BCM25 into REG_IORQ
   Read (mreq) BCM24 into REG_MREQ
   Read (address bus) inputs BCM0-BCM15 into REG_ADDR
   Read (rd) BCM26 into REG_READ
   Read (wr) BCM27 into REG_WRITE
   
   if ((intPIMode == PI_IOADDR_MEMORY) || (intPIMode == PI_IOADDR_MAPPEDIO))
   {
      if ((REG_ADDR >= PI_RAMADDR_START) && (REG_ADDR <= PI_RAMADDR_END))
      {
         if (REG_MREQ == 0)
         {
            // PI is active and we have a memory request
            if (REG_READ == 0)   // READ REQUEST
            {
               if (!blnInRead)
               {
                  blnInRead = true   // start of read cycle
                  set GPIO_RAMDIS to HIGH
                  set (data bus) BCM16-BCM23 to OUTPUT
                  
                  // memory read requests
                  if (intPIMode == PI_IOADDR_MEMORY)
                  {
                     // read data from somewhere in PI RAMDisc memory
                     REG_DATA = readMemory(REG_ADDR);
                  }
                  else if (intPIMode == PI_IOADDR_MAPPEDIO)
                  {
                     // read data from somewhere in PI I/O memory
                     REG_DATA = readIOMemory(REG_ADDR);
                  }
                  put REG_DATA into (data bus) BCM16-BCM23
               }
            }
            else if (REG_WRITE == 0)   // WRITE REQUEST
            {
               if (!blnInWrite)
               {
                  blnInWrite = true   // start of write cycle
                  set GPIO_RAMDIS to HIGH
                  set (data bus) BCM16-BCM23 to INPUT
                  Read (data bus) inputs BCM16-BCM23 into REG_DATA
                  
                  // memory write request
                  if (intPIMode == PI_IOADDR_MEMORY)
                  {
                     // write memory to the PI RAMDisc memory
                     writeMemory(REG_ADDR, REG_DATA);
                  }
                  else if (intPIMode == PI_IOADDR_MAPPEDIO)
                  {
                     // write memory to the PI I/O memory
                     writeIOMemory(REG_ADDR, REG_DATA);
                  }
               }
               else
               {
                  blnInWrite = false      // end of write cycle, is it even a cycle?
               }
            }
         }
         else   
         {
            if (blnInRead)
            {
               if (REG_MREQ == 1)
               {
                  blnInRead = false      // end of read cycle
               }
            }
         }
      }
   }
   else if (REG_IORQ == 0)   // I/O REQUESTS
   {
      if (REG_ADDR == PI_IOADDR_UNMAPPED)
      {
         // deselect PI from address space
         ;set GPIO_RAMDIS to LOW   ; just in case it was high NOT REQUIRED?
         intPIMode = PI_MODE_UNMAPPED
      }
      else if (REG_ADDR == PI_IOADDR_MEMORY)
      {
         // select PI into CPC address space in memory mode
         intPIMode = PI_IOADDR_MEMORY
      }
      else if (REG_ADDR == PI_IOADDR_MAPPEDIO)
      {
         // select PI into CPC address space in mapped I/O mode
         intPIMode = PI_IOADDR_MAPPEDIO
      }
   }
   
   // process I/O requests based on I/O memory
   processIOMemory();
}


arnoldemu

is your pi device a co-processor/gfx card?

CPC sends commands, and then pi processes the commands?

Pi is 3v for GPIO and CPC is 5v. Are you using a voltage converter?
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

zhulien

#38
Quote from: arnoldemu on 19:32, 29 January 17
is your pi device a co-processor/gfx card?

CPC sends commands, and then pi processes the commands?

Pi is 3v for GPIO and CPC is 5v. Are you using a voltage converter?


Yes, 4 of them for 32 GPIOs.  The PI has 40 GPIOs on the Model 3 B.  I have only a Model 1 which is not enough but am waiting for a 3B to arrive.  I am plugging the PI via the Voltage Levelers directly to the CPC bus to emulate memory as well as memory mapped I/O (of the PI's hardware).

zhulien

Of all the CPC signals I've mapped to, what would be the next most 'useful' one that I haven't?  I have one more GPIO...


https://docs.google.com/spreadsheets/d/1bS1CLDIN0jPP3GI2pCcTU7_VIf2otQ10bVm-NL0F2eQ/edit#gid=0


Duke

You must drive the datalines from the falling edge of RD or WR to the rising edge ( you can see all these timings in the z80 manual ).
BUSAK is no use without BUSRQ and strictly not needed, because you know by the next cycle it will release the bus, which may turn in handy if you cannot maintain I/O mapping at all times.
The important signals for your purpose is A15-A0, D0-D7, RD, WR, IORQ, MREQ, ROMEN, RAMDIS, ROMDIS, BUSRQ. Of course if you need no rom mapping, you can discard ROMEN and ROMDIS.
BUS_RESET and RESET is nice to have if you need to delay startup time.
RAMDIS or ROMDIS will need to be driven high to not drive data lines on RD and to not write to base memory on WR. There is probably more I forgot right now :)

zhulien

#41
I've refactored the spreadsheet so it is much more clear.  I'm now debating ROMEN and ROMDIS in please of BRST & RESET - as I have exhausted all the GPIO's I reasonably have access to.  32 of them.  Thanks for the falling edge tip, I'm sure I will get lots of bugs otherwise.  If I don't need the RESETs, then the ROM support could be useful to emulate yet another ROMBoard, but there are really good ROMBoard solutions already :D


To time the rising and falling edges, do I need to monitor the clock?  investigating... http://www.piclist.com/techref/mem/dram/slide4.html


Actually that explains a lot when I was wondering... how do i know when the CPU finished reading.  now I know.

Duke

#42
Quote from: zhulien on 21:24, 29 January 17
To time the rising and falling edges, do I need to monitor the clock?  investigating... http://www.piclist.com/techref/mem/dram/slide4.html

You don't need to monitor the clock, ideally, I don't know if PI has this, what I use on the Cortex series, is edge detectors, meaning you can setup an interrupt or event for a given gpio. I am using the event in a interrupt disabled closed loop in tight assembly, because a few too many instructions will skew the timing.
Then you just issue the instruction WFE (wait for event), do your checkings and drive/read whatever lines, WFE again for the rising edge, loop.
Of course you can also just loop after driving the data lines, while ( gpio(RD/WR/ROMEN/MREQ/ETC)== 0 ) ;

zhulien

#43
I updated the logic in the previous page to cater for rising and falling clock edges.  Currently i only have the original Raspberry Pi which doesn't have enough I/Os, I am waiting for the new one to arrive so can't test much really until then.


In this version, the rising and falling, for a read, I start on the falling, then finish on the rising for which the mreq stops.  For a write, since both the start and end of the cycle on on the rising, does it really matter?  I am guessing that as soon as the WR operation starts, the data is immediately available and it's up to me to do what i want with it quickly.


With IOREQ, are timings important for that?  I would have thought as long as it's the IO port I am decoding, then it's mine. 


Actually I don't need the clock, I can detect the edges of the MREQ.

genesis8

Use the PI as a RTC for the CPC is on your feature list ?
____________
Amstrad news site at Genesis8 Amstrad Page

zhulien

Quote from: genesis8 on 23:20, 29 January 17
Use the PI as a RTC for the CPC is on your feature list ?


It is now :)

Ygdrazil


Hi Zhulien


Great news! As a big fan of the RPI and CPC, the CPC-RPI bridge is the project. Was thinking of doing something like this for a long time!


How is the bridge mounted? On the expansion bus (with additional pins) or between the CPC motherboard and the Z80? 


Keep up the good work :-)


Regards,
/Ygdrazil

Quote from: zhulien on 05:16, 30 January 17

It is now :)

zhulien

Expansion bus. With 40 gpios mapped for now

zhulien

#48
My pi 3b arrived so just waiting for the voltage levellers...


In the meantime some ideas I would like to consider...



Pi hardware exposed:‎

Hdmi FullHD
3d graphics‎
Audio
Mp3‎

Wifi
Bluetooth
Ethernet

Rtc
‎Sdcard

Simulated cpc hardware:


512mb Ram expansion‎

Memory mapped io to pi for hardware activation and control of other operations.‎

Can register jumpblocks to pi. Eg register an address with a target of a call that can be synchronous or asynchronous. Sync will basically loop to itself until pi is ready then pi will change the loop to a return. Async will just be a return immediately but it triggers a process. The process can be read later.. or ignored. Both cases registers are passed into the jumpblock.‎


Transformations. Eg... register a transformation to be triggered based on a call or mapped io. A transformation could be eg... fill memory with a sine wave xor 2 memories multiple can then be triggered by using an ldir. I wonder how much processing can be achieved in a single cpc instruction cycle?



zhulien

Although i have access to 32 gpio ports 4 are on this ugly flat camera connector plastic ribbon type thing... 3 i can forego but 1 i cannot which is ramdis. 


Are there ICs that eg... block a signal in a direction so i can connect ramdis that is output and and the rd signal that is always input to the same gpio? So that when the gpio is in it reads rd... but if it is out it write to ramdis? Ramdis needs to be kept high on out... so is such an ic a latch?

Powered by SMFPacks Menu Editor Mod