Hi, I have a system where the a PMC card with C6415 act as a daughter board. Currently, I'm using the method describe in the "C6000 Peripheral Guide" when i need to transfer data from SDRAM of the PMC Card to the memory the host system. i.e. I will use the master read and Master Write method describe in Chapter 9. For a MasterRead, I will write the source address (host's memory address) to the PCIMA register. Then, I write the destination address (DSP's memory address) to the DSPMA. Then, I write the total byte I wish to transfer and the read method accordingly to PCIMC. The above method works fine. However, it's not really "convenient" compare to the DAT module of DSP/BIOS. For example, if I wish to transfer (read/write) large amount of data through PCI interface to/from host, I have to use for/while-loop to transfer the data. The maximum amount can be trasfer at a time is limited to 65535 (i think so) as the totol bytes to transfer field (CNT) in PCIMC is only a 16-bit field. So, i need to seperate the large data to small transfers. Futher more, i need to pool (or can use Interrupt) the MASTEROK (in PCI Interrupt Source Register), to monitor the status of previous transfer before making new trasnfer request. Thus, my problem is this method of transfer appears to me as "blocking I/O" as my program will be "blocked" until the transfer end. Is there any other better method to transfer data between the memory visible to DSP to memory of Host ? I'm hoping that the transfer can be "handled in backgroud" .. something like that provided by the DSP/BIOS's DAT module.. Can i use the QuickDMA / EDMA to do so ? How ? Sorry if the message looks a bit messy :-p.. Please advise.. Thanks in advance. -- Beh, Chiun-Siang |
|
PCI data transfer
Started by ●May 22, 2003
Reply by ●May 27, 20032003-05-27
Hello, I agree completely with you : the 16bit limit for the count register is very low. However, even with this, you may achieve honorable transfer rates for a 33MHz PCI interface. What I do is breaking the transfer in chunks of 64KB-4Bytes (0xFFFC). The main transfer function stores the transfer params in some global variables. Then, it calls a function that actually starts the transfer of one chunk. After each transfer, the PCI interrupt is trigged. It checks the MASTEROK bit, programs the next chunk, and go on. When the whole transfer is finished, it posts a semaphore. I have quickly written here below how my functions look like (may be several errors in it -> no much time to write it now... sorry) I hope it helps J-F unsigned int PCI_Tfer_Async(...) { // Store tfer params (to be used by PCI_TferNextChunk) // Start First chunk (must be protected against reentrancy) PCI_TferNextChunk(); } void PCI_handler(void) { // Check last tfer status // Is there another chunk to tfer ? // If yes : PCI_TferNextChunk(); // If no : transfer finished SEM_ipost(&SEM_PCITFER); } unsigned int PCI_Tfer_poll_end(void) { return SEM_pend(&SEM_PCITFER, SYS_POLL); } unsigned int PCI_Tfer_wait_end(void) { return SEM_pend(&SEM_PCITFER, SYS_FOREVER); } unsigned int PCI_Tfer_Sync(...) { PCI_Tfer_Async(...); PCI_Tfer_wait_end(); } void PCI_TferNextChunk(void) { // Check if total count has been transferred // If no, prepare next chunk (0xFFFC or remaining cnt), // program & start tfer } |