how to make a synchronous FIFO interface with 15 pins

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
jeeyoo
Posts: 6
Joined: Thu Sep 17, 2015 3:32 am
Contact:

how to make a synchronous FIFO interface with 15 pins

Post by jeeyoo » Thu Sep 17, 2015 6:07 am

SORRY, I am the beginner.

my plan is get a synchronous FIFO interface with 15 pins, pin[0] will be the benchmark. I name it clock.
all others pin will follow pin[0]'s rising(or falling) edge to output. all 15 pins have the synchronized cycles.
if I write as :

Code: Select all

pin0.high()
...
pin13.high()
pin14.high()
I think they will not have the same edges.
so, how can I do to ?
thanks to reply me .

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: how to make a synchronous FIFO interface with 15 pins

Post by dhylands » Thu Sep 17, 2015 11:04 pm

No they won't have the same edges, although generally speaking, this doesn't matter.

What matters is that the pins all have the correct value when the clock signal changes.

If there are multiple pins on the same CPU port. If you look at: http://docs.micropython.org/en/latest/p ... ckref.html then we can see that A0 through A7 (in the white boxes) are on pins X1 through X8.

You can use the stm module and do something like:

Code: Select all

import stm
odr = stm.mem16[stm.GPIOA + stm.GPIO_ODR]
odr &= 0xff00
odr |= (val & 0xff)
stm.mem16[stm.GPIOA + stm.GPIO_ODR] = odr
and that will write all 8 bits at once (and preserve A9 thru A15).

The above assume that you've already configured X1 thru X8 as output.

jeeyoo
Posts: 6
Joined: Thu Sep 17, 2015 3:32 am
Contact:

Re: how to make a synchronous FIFO interface with 15 pins

Post by jeeyoo » Fri Sep 18, 2015 1:39 am

thank you for your help.
I guess I can use A0-A7,A13-A15, total 11pins ,I CAN write 11 bits at once , yeah?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: how to make a synchronous FIFO interface with 15 pins

Post by dhylands » Fri Sep 18, 2015 4:54 am

Yep - just adjust the mask appropriately.

jeeyoo
Posts: 6
Joined: Thu Sep 17, 2015 3:32 am
Contact:

Re: how to make a synchronous FIFO interface with 15 pins

Post by jeeyoo » Fri Sep 18, 2015 6:14 am

thank you for your answer patiently!thank you.

jeeyoo
Posts: 6
Joined: Thu Sep 17, 2015 3:32 am
Contact:

Re: how to make a synchronous FIFO interface with 15 pins

Post by jeeyoo » Mon Oct 19, 2015 8:59 am

Code: Select all

import pyb
import stm
import select
import binascii



def program(usb):

    pyb.Pin(pyb.Pin.cpu.A0, pyb.Pin.OUT_PP)  
    pyb.Pin(pyb.Pin.cpu.A1, pyb.Pin.OUT_PP)     
    pyb.Pin(pyb.Pin.cpu.A2, pyb.Pin.OUT_PP)     
    pyb.Pin(pyb.Pin.cpu.A3, pyb.Pin.OUT_PP)        
    pyb.Pin(pyb.Pin.cpu.A4, pyb.Pin.OUT_PP)     
    pyb.Pin(pyb.Pin.cpu.A5, pyb.Pin.OUT_PP)     
    pyb.Pin(pyb.Pin.cpu.A6, pyb.Pin.OUT_PP) 
    pyb.Pin(pyb.Pin.cpu.A7, pyb.Pin.OUT_PP) 
    pyb.Pin(pyb.Pin.cpu.A13, pyb.Pin.OUT_PP)     
    pyb.Pin(pyb.Pin.cpu.A14, pyb.Pin.OUT_PP)     
    pyb.Pin(pyb.Pin.cpu.A15, pyb.Pin.OUT_PP)  
    value = 0x0000
    odr = stm.mem16[stm.GPIOA + stm.GPIO_ODR]
    odr &= 0x0000
    odr |= (value & 0xff)
    stm.mem16[stm.GPIOA + stm.GPIO_ODR] = odr
    stm.mem16[stm.GPIOA + stm.GPIO_ODR] = 0x20A5

    usb.setinterrupt(-1)
    while True:
        select.select([usb], [], [])
        if usb.any():
            revByte = usb.read(64)
            
            usb.send(0xF0, timeout=1)
            for index in range(64):
                stm.mem16[stm.GPIOA + stm.GPIO_ODR] = (0x2000 | revByte[index])
                stm.mem16[stm.GPIOA + stm.GPIO_ODR] = (0x0000 | revByte[index])
            usb.send(0xF1, timeout=1)
            
            #with open("usb.log", "a") as f:
                #for i in range(6):
                    #f.write("\r\n")
                    #f.write(str(len(revByte)))
    
@micropython.native
def main():
    program(pyb.USB_VCP())  
    
main()    
Boot.py is blank.

My purpose is to modify 11 pin's value at the same time. it speed than 200s to modify 128 times, how can I increase the speed .

thanks,

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: how to make a synchronous FIFO interface with 15 pins

Post by Damien » Mon Oct 19, 2015 6:07 pm

Can you please clarify the current speed that you are getting: is it 128 changes in 200ms?

What frequency are you aiming for?

Note that it will ultimately depend on the speed of the USB serial comms.

jeeyoo
Posts: 6
Joined: Thu Sep 17, 2015 3:32 am
Contact:

Re: how to make a synchronous FIFO interface with 15 pins

Post by jeeyoo » Tue Oct 20, 2015 2:58 am

THANK YOU ,
I found that 128 changes spent 200 seconds not "200 microseconds".

when pyboard has received all 64 bytes, it will send "0xF0" to PC, and when finish 128 changes will send "0xF1" to PC,
I compute time of the interval is more than 200s.
so, I think the speed of the USB serial is not the bottlenecks.


Code: Select all

            revByte = usb.read(64)
            
            usb.send(0xF0)  
            for index in range(64):
                stm.mem16[stm.GPIOA + stm.GPIO_ODR] = (0x2000 | revByte[index])
                stm.mem16[stm.GPIOA + stm.GPIO_ODR] = (0x0000 | revByte[index])
                
            usb.send(0xF1)
I have not changed the default clock.
I want the frequency sooner than sooner ,o(∩_∩)o ,
how can I do?
thank you.

Code: Select all

>>> import pyb
>>> pyb.freq()
(168000000, 168000000, 42000000, 84000000)

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: how to make a synchronous FIFO interface with 15 pins

Post by Damien » Tue Oct 20, 2015 9:44 pm

I tried your code above (the full program) and it worked for me. I put that code in main.py and then ran the following code on my PC:

Code: Select all

import serial
import time
ser = serial.Serial('/dev/ttyACM0', baudrate=115200, interCharTimeout=1)
buf = bytearray(64)
start = time.time()
for i in range(128):
    ser.write(buf)
    ret = ser.read(2)
    print(ret[0], ret[1])
    buf[0] += 1
    buf[1] += 1
end = time.time()
print(end - start, 128 * len(buf) / (end - start))
This will send 64 byte blocks, 128 times, and tell you the data rate at the end. I also modify the buffer that's being sent so it's not always all 0's.

I get 1.28s, which is 6400 bytes/sec.

That's rather slow (but not 200s long). To make it faster change the 64-byte buffer to 128 bytes (and also change the receiver to read in 128 bytes at a time). Then I get 0.37s, which is 43000 bytes/sec.

USB sends data in 64 byte packets, so probably reading 64 byte chunks means you hit some strange edge case where it has to wait for the next USB packet (which is empty to indicate that there was only 64 bytes to read) before returning the 64 bytes.

Also, doing usb.read(64) won't always give you 64 bytes. It might give you less. Use usb.recv(64, timeout) and adjust the timeout to try and get a full 64-byte buffer returned.

jeeyoo
Posts: 6
Joined: Thu Sep 17, 2015 3:32 am
Contact:

Re: how to make a synchronous FIFO interface with 15 pins

Post by jeeyoo » Thu Oct 22, 2015 6:04 am

thank you Damien.
because of your guidance, I found why I spent 200s .
and my have almost finished my task.
thanks you , thanks dhylands.

Post Reply