USBFS DMA behaviour

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

I've read the datasheet of USBFS and noticed that it is possible to implement it with the DMA. My situation is that I have an array with 128 samples (2 bytes each) and I want to transfer these over to the PC (python program).

The pyusb implementation limits the transfers to 64 bytes, so I use the Bulk transfer on the PSoC and, so far, I was able to transfer 64 bytes of data (actually 32 because it divides the 2 bytes samples).

So, my question, regarding the DMA is: shouldn't it send the first 64 bytes and, right after queue the next samples to be sent, doing this process until it reaches the end of the sample array?

Attached is my project called "PSoCandPYTHON"

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
cadi_1014291
Level 6
Level 6
25 likes received 10 likes received 10 likes given

I couldn't get the USB component to send more than 64bytes on one packet (this limitation when using BULK) nor being able to the DMA Automatic handle to send the next 64 bytes on the second transaction.

I modified your project to use Manual memory handing and now i can send the whole array to the pc, as the data you were trying to send is uint16_t and the USB can send uint8_t data i used a union:

union Data {

     uint16_t      u6_buffer[128], // your original buffer

     uint8_t     u8_buffer[256], // "virtual" buffer

};

And Load the data to the IN endpoint like:

union Data myData = {

     .u16_buffer = { // content of the buffer

     }

}

USB_LoadEPIn(IN_EP, &myData.u8_buffer[0], 64);

The python script:

#!/usr/bin/env python3

import time

import usb.core

import usb.util

import numpy as np

import sys

def close_device(exitVal=0):

    print("Exiting...")

    usb.util.dispose_resources

    sys.exit(exitVal)

###########USBFS Configuration (Python side)###########

VID = 0x04B4

PID = 0xF232

dev = usb.core.find(idVendor = VID, idProduct = PID)

if not dev:

    print('PSoC not found')

    close_device(1)

print('PSoC found')

#set the active configuration (basically, start the device)

dev.set_configuration()

#get interface 0, alternate setting 0

cfg = dev.get_active_configuration()

intf = cfg[(0, 0)]

epOut = usb.util.find_descriptor(

    intf,

    # match the first OUT endpoint

    custom_match= \

    lambda e: \

        usb.util.endpoint_direction(e.bEndpointAddress) == \

        usb.util.ENDPOINT_OUT)

#make sure our endpoints were found

if epOut is None:

    close_device(1)

# find the first (and in this case only) IN endpoint in our interface

epIn = usb.util.find_descriptor(

    intf,

    custom_match= \

    lambda e: \

        usb.util.endpoint_direction(e.bEndpointAddress) == \

        usb.util.ENDPOINT_IN)

#make sure our endpoints were found

if epIn is None:

   close_device(1)

###########USBFS Configuration (Python side)###########

#print("Message: ")

# obtenemos la entrada del usuario

#t = input()

# escribimos la entrada del usuario al OUT endpoint

#dataWriten = epOut.write(t)

# if using BULK transfers we are stuck at 64 bytes

bytes_to_read = 64

for i in range(10):

    time.sleep(0.25)

    # "trigger" the data transfer

    try:

        print("Triggering the data transfer")

        epOut.write('2')

    except usb.core.USBError:

        print("Can't send data to the PSoC")

        close_device()

    data = epIn.read(bytes_to_read)

    # print data in decimal

    # we get the data in u8 format so to transform it into u16

    # we need to shift the high_byte 8 positions to the left

    # and OR it with the lower_byte

    # Repeat it depending of the number of bytes to read

    for i in range(0, bytes_to_read, 2):

        print('Received: {0:d}'.format(data[i+1] << 8 | data))

close_device()

The project is attached.

View solution in original post

4 Replies
AnkitaS_51
Employee
Employee
100 likes received 50 likes received 25 likes received

You can check into this project in which circular buffer -

PSoC 4 Pioneer Kit Community Project#102 – USB ... | element14 | Cypress Kits

Its an old project, it may not build in latest version of creator.

You can make use of DMA with Manual Buffer Management option, but the here the transfers may be slow as all will be handled by CPU.

0 Likes
lock attach
Attachments are accessible only for community members.
cadi_1014291
Level 6
Level 6
25 likes received 10 likes received 10 likes given

I couldn't get the USB component to send more than 64bytes on one packet (this limitation when using BULK) nor being able to the DMA Automatic handle to send the next 64 bytes on the second transaction.

I modified your project to use Manual memory handing and now i can send the whole array to the pc, as the data you were trying to send is uint16_t and the USB can send uint8_t data i used a union:

union Data {

     uint16_t      u6_buffer[128], // your original buffer

     uint8_t     u8_buffer[256], // "virtual" buffer

};

And Load the data to the IN endpoint like:

union Data myData = {

     .u16_buffer = { // content of the buffer

     }

}

USB_LoadEPIn(IN_EP, &myData.u8_buffer[0], 64);

The python script:

#!/usr/bin/env python3

import time

import usb.core

import usb.util

import numpy as np

import sys

def close_device(exitVal=0):

    print("Exiting...")

    usb.util.dispose_resources

    sys.exit(exitVal)

###########USBFS Configuration (Python side)###########

VID = 0x04B4

PID = 0xF232

dev = usb.core.find(idVendor = VID, idProduct = PID)

if not dev:

    print('PSoC not found')

    close_device(1)

print('PSoC found')

#set the active configuration (basically, start the device)

dev.set_configuration()

#get interface 0, alternate setting 0

cfg = dev.get_active_configuration()

intf = cfg[(0, 0)]

epOut = usb.util.find_descriptor(

    intf,

    # match the first OUT endpoint

    custom_match= \

    lambda e: \

        usb.util.endpoint_direction(e.bEndpointAddress) == \

        usb.util.ENDPOINT_OUT)

#make sure our endpoints were found

if epOut is None:

    close_device(1)

# find the first (and in this case only) IN endpoint in our interface

epIn = usb.util.find_descriptor(

    intf,

    custom_match= \

    lambda e: \

        usb.util.endpoint_direction(e.bEndpointAddress) == \

        usb.util.ENDPOINT_IN)

#make sure our endpoints were found

if epIn is None:

   close_device(1)

###########USBFS Configuration (Python side)###########

#print("Message: ")

# obtenemos la entrada del usuario

#t = input()

# escribimos la entrada del usuario al OUT endpoint

#dataWriten = epOut.write(t)

# if using BULK transfers we are stuck at 64 bytes

bytes_to_read = 64

for i in range(10):

    time.sleep(0.25)

    # "trigger" the data transfer

    try:

        print("Triggering the data transfer")

        epOut.write('2')

    except usb.core.USBError:

        print("Can't send data to the PSoC")

        close_device()

    data = epIn.read(bytes_to_read)

    # print data in decimal

    # we get the data in u8 format so to transform it into u16

    # we need to shift the high_byte 8 positions to the left

    # and OR it with the lower_byte

    # Repeat it depending of the number of bytes to read

    for i in range(0, bytes_to_read, 2):

        print('Received: {0:d}'.format(data[i+1] << 8 | data))

close_device()

The project is attached.

Anonymous
Not applicable

Gracias por la ayuda!

0 Likes

Hope it helps to solve your project.