USB speed 2mb/sec USB (MCU <-->PC) realisation? stm32 - arm

I have the plans to create an emmc reader project where the mcu will read the data chunks (per 8kb) and send it to UI in PC (i guess i will use Visual Studio with serial port implmentation), the problem is that the fast usb speed is required because of emmc mcu has 32gb on board, therefore i need 2mb/sec speed at least. I have stm32h7, VCP is very slow , i can get 450 kb/sec this is the limit due to the package size of 64byte per ms. What other varients? i was thinking about USART (FTDI CHIP) with maximum baud rate, but i doubt i can reach 2mb with it. Also it has to be 2.0 USB , therefore i cant use HighSpeed, right? becase its only for usb 3.0.
i'm not tied to arm architecture, can use any other chip, any suggestions?
UPD for Codo
#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
When i change CDC_DATA_FS_MAX_PACKET_SIZE to value more then 64, usb stops working on USB 2.0 HUB, but working on USB 3.0.

Related

STM32 USB CDC did not work

I'm using stm32l151 and I want to use usb peripheral in cdc mode. I used stm32 cubeMx to generate the project. however the function CDC_Transmit_FS() always return USBD_BUSY. can anyone help me?
Here is my code:
while (1)
{
CDC_Transmit_FS(Buffer, 6);
HAL_Delay(2000);
}
I only added the above code to the project created by STM32cubeMX but it didn't work.
STM library is buggy and it stalls when you for example try to send many larger packets of data.
There is a problem with the windows drivers and there are quite long delays between packets. So 12MB is quite difficult to archive - using CubeMx I could only have about 3-4Mb (12MB when packet is sent).
Another problem I had - I needed to send some data to the device bofore I could transmit next packet (max 8kB in my case), otherwise it stalled randomly.
Fortunately, the problem is solved and I can receive data in the PC from the STM32. There was a problem in my terminal software. I used serial port manitor to monitor the received data from the serial port, however this serial monitor software do not open the serial port by itself and if any other software opens the serial port and receives the data, it monitors data receptions. I didn't know that.
Thanks

How do I write to an SD Card using SPI for the PSoC 5LP chip?

How do I write to an SD Card using SPI with DMA available for the PSoC 5LP (32-bit Cortex-M3) chip?
I currently have a DMA and SPI tx/rx pair working, but for a different purpose so if the actual transmission is not an issue, I just don't know how to interact with the SDcard.
The datasheet for the PSoC 5LP is here.
Basic Info:
I am using the DMA in simple mode and the DMA TD chain is setup for:
8 bit width, 4 Byte bursts
auto complete the full TD (only needs initial HW request)
Loop back to beginning of initial TD when done and wait for HW request
The SPI Master is initialized in a gui, I have it set using a 16Mhz clock, 8 bit tx/rx transfers with a 4 Byte tx/rx buffer. interrupts are set on rx FIFO full, connected to them is an rx DMA.
The pointers for the SDcard SPI rx/tx are SPIM_RX_PTR and SPIM_TX_PTR respectively. The DMA transfers to and from them. The Arrays that I am transferring from and to are SDcardout and SDcardin.
Having SPI communication will only get you the lowest command/block level access to the card; you will need a file system. SD cards come pre-formatted as FAT32, so a FAT file-system will provide the greatest comparability, is not the greatest reliability (corruption is likely if write is interrupted by power loss or reset for example). It also has the advantage of being relatively simple to implement and requires few resources.
There are several commercial and open-source FAT filesystems libraries available. I suggest that you look at ELM FatFs or ELM Petit FatFs both have permissive licences and are well documented. In each case you simply need to implement the disk I/O stubs to map them to your SPI driver. There are plenty of examples, documentation and application notes on the site to help you. You can start with an SPI SD implementation example for another target and adapt it to your driver (or adapt your driver perhaps). Other FAT filesystem libraries are broadly similar to this and require I/O layer implementation.
The diskio layer of ELM FatFs is not media specific, so you in fact need an additional MMC/SD layer between that and the SPI driver. It is unlikely that you will find an example for your specific target, but it is possible to work from examples for other targets since MMC/SD over SPI itself is not target specific, the hardware dependencies come only at the SPI level and the GPIO implementation for the card-detect and write-protect (optional) signals. There are several examples for various ARM targets here, a project for PSoC support here (apparently a work-in-progress at time of writing).
I have done work on exactly this problem.
I found that the existing SPI module provided with the PSoC 5 components library is not ideally suited to bulk transfers to / from an SD card. As far as I could tell, it was necessary to clear SPI module flags in software on each byte transfer, rendering DMA much less useful. I think one solution is to use two TDs (Transfer descriptors) - one to perform the data transfer and a second to clear the RX flag after the first TD has completed - anyway, that's off topic.
I also found that the emFile component supplied in the components library is limited in its capabilities. I couldn't see any way to attach DMA, and even if I could, its clock speed appeared to be very poor. On top of this, emFile requires compile-time selection of FAT16 or FAT32, limiting your design to one or another filesystem only.
As I didn't like the idea of a more complicated DMA setup, I decided to design my own SPI component hardware in the UDB editor. The project containing the component can be found at: https://github.com/PolyVinalDistillate/NSDSPI
This incorporates the excellent FatFS library mentioned above (thanks ChaN), which takes care of FAT12, FAT16 and FAT32 formatted cards. As stated, without the filesystem layer, you will only be accessing raw data blocks of 512 bytes each. With FatFS, you get analogues of fopen(), fclose(), etc.
If you look at my component in PSoC Creator, you'll see it's actually composed of 2 components: One is the specialised UDB component implementing the main SPI logic, the other is a schematic connecting my UDB component to DMA and some control logic. This second component also has the API files containing my hardware-specific code and is the component to drop into your TopDesign schematic.
FatFS is included as a precompiled library, and LowLevelFilesys.h in the API folder provides access to all the file functions.
This component was designed with bulk-reads in mind and the API does the following for read:
Sets up a DMA TD of the required data length and tells my SPI component how many bytes will be transferred.
Triggers the transfer, causing my SPI component to send 0xFF automatically (no need to write 0xFF to the SPI for every byte received), while copying each received byte into the receive buffer via DMA.
Writing the card is performed in a more typical fashion, with the DMA simply sending data to the SPI module after preparing the SD card for it.
If you run my project on your PSoC system, it will perform a read / write test on the SD card, depositing a file reporting the specs:
Testing Speed
Writing 16000 bytes to file, non-DMA
Took 94 ms
Rate 1361 kbps
Reading 16000 bytes to file, non-DMA
Took 50 ms
Verifying... All Good! :D
Rate 2560 kbps
Writing 16000 bytes to file, DMA
Took 17 ms
Rate 7529 kbps
Reading 16000 bytes to file, DMA
Took 12 ms
Verifying... All Good! :D
Rate 10666 kbps
Some SD cards give better results, some give worse. I believe this is down to the SD card itself (e.g. class, usage, age of tech, etc).

Controlling voltage supply on usb port using c or any programming language

I don't have much konwledge in electronics. i wanted to turn on/off led connected to usb port using program. usb port consists 4 line (data+,data-,voltage ,ground) if i connect voltage and ground lines to led , it will glow. i've been searching on internet this issue and i find that it is not possible to control led connected to usb using program because supply over datapin is too low which can not be used to tun on off led.
but what if i connect my led to vol and ground pin and control the entire power supply of usb port , i guess it is possible to control led using program. there is a way to disable and enable power supply over usb port.
i also want to know is it bad to follow this approach. does it damage usb controller to frequently enable/disable power supply.
Algo :
a = Get_input_from_user() ;
if(a=="ON")
turn power supply of usb port ON.
else
turn power supply of usb port OFF.
this thing is certainly possible using extra hardwares, i don't want to use any extra hardware.
The power for a computer's USB ports is generally not software controllable. In most cases, the power pins of your USB ports are wired directly to the 5V rail of your power supply (usually through a polyfuse), so there is no way to switch them on and off.
Some powered USB hubs do support switching power to their ports, but you said that you didn't want to use any extra hardware, so you're out of luck.
you can use any basic Arduino board to do this there is a complete IDE free and a LOT of sample code that will do what you want out of the box
you can also use a COOL board.
Arduino Compatible code is available for the Teensy
Software Development Tools HERE
You can use an external power supply (the Vcc and GND pins of the USB port in this case) with a resistor to power the diode and connect a transistor in the middle working as interruptor. Then, yo connect the base and emisor to de data+ and data- of the USB port.
this page doesnt let me upload images.
Sorry for the quality of the drawing but all I have on the computer is paint.
For a more stable performance make sure to make R1 low enough so that transistor is on saturation mode when data pins are ON but not so low that transistor gets burnt (I dont really know what is the voltage level of the data pins on the USB port, sorry).
To choose a proper value of R2, you need to know the current you need to power your diode. It's calculated acording to Ohm law:
Idiode = (Vcc - Vce,sat - Vd) / R2.
Where Vce,sat is potencial diference between colector and emisor when transistor is on saturation mode (it is found on the transistor datasheet on the manufacturer webpage, usually around 0.2V) and Vd is the normalized potencial difference of the diode (the same, but this time around 0.6V).
Note that data- and GND pins are connected. I am 99% sure that this won't harm your USB port, but use it at your own risk.
I would test it out using another external power source first anyways, just to make sure you connected everything properly.

PCI Express validation using driver

I'm using Windriver Jungo for testing PCI express device connected to my PC. I can able to read/write memory in 8/16/32/64 bit modes and the board responding very well. But my doubt is that, according to PCI express specification we can send a TLP packet from 128 bytes to 4096 bytes. How can i achieve this transfer using driver. Now its transfer only 8 byte(64 bit mode) data. If i give more data to sent then it split the data to 8byte packets and then sent. Please clear my doubt and suggest any other driver options for PCI express in windows or Linux ?
You are trying PIO read write, not DMA. PIO read/write TLPs will have only a doubleword length data in a packet. For burst data transfers(which have data up to 4096 bytes but it will be probably limited to 128 byte by your motherboard chipset), you have to initate read/write from your PCIE device to PC, not from PC to PCIE.
I used a windriver to communicate with a PCIE FPGA kit before, it works fine for me at any payload the program specify (128-4K). It might be the way you write to the BAR location. check if you are sending the data to the same BAR address location or different BAR address location.

DMA transfer to a slave PCI device in Linux

I am a bit confused regarding DMA transfers with a PCIe device.
Say, for example, I have a slave PCIe device, and I want to transfer a block of data from the device to the RAM, using a DMA transaction. Note that the device is slave, and does not have a DMA "machine" on it.
I know I need to obtain a DMA-able buffer in RAM (either by allocating a coherent one, or by mapping a page) first.
But what's next? what's the API to start a DMA transfer of N bytes from address S to address D?
Can modern systems issue a DMA transfer to/from a slave pci device? if so, what is the Linux API for that?
As explained here:
[ISA]
In the original IBM PC, there was only one Intel 8237 DMA controller [...]
A PCI architecture has no central DMA controller, unlike ISA. Instead, any PCI component can request control of the bus ("become the bus master") and request to read from and write to system memory
The PCI bus does not have a "central" DMA controller - instead, each device can be a DMA "controller".
First of all, there are no slaves and slave holders inside modern PC. There is south bridge (in PCI) or Root Complex (root of PCI-express device tree) and there are some other PCI/PCIe actors, like bridges, soldered chips, plugged cards, hardware debuggers etc. I'll assume that you are asking about plugged card or some other peripheral device, like soldered Sound Card or Ethernet chip.
According to this detailed description of "Transaction Layer Packet" (TLP, "PCIe’s uppermost layer"), there is "Bus Mastership (DMA)":
On PCIe, it’s significantly less exotic. ... anyone on the bus can send read and write TLPs on the bus, exactly like the Root Complex. This allows the peripheral to access the CPU’s memory directly (DMA) or exchange TLPs with peer peripherals (to the extent that the switching entities support that).
Also, there is some benefits of DMA capability from plugged devices: DMA attack. And PCIe is listed as capable of initiating DMA transfer:
Systems may be vulnerable to a DMA attack by an external device if they have a FireWire, ExpressCard, Thunderbolt, or other expansion port that, like PCI and PCI-Express in general, hooks up attached devices directly to the physical address space.
I think, there is no universal API for programming DMA transfers that are initiated from the peripheral device itself. This depends on the what the device is, when the DMA should be started and what will be sent.

Resources