Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OutTransfer not handling >64bytes #1

Open
mjunior-fitec opened this issue Nov 29, 2018 · 2 comments
Open

OutTransfer not handling >64bytes #1

mjunior-fitec opened this issue Nov 29, 2018 · 2 comments

Comments

@mjunior-fitec
Copy link

I am running some tests here with a FTDI device and I just can't send more than 64 bytes.
Checking the Ftdi.SndData, I saw it calls the OutTransfer which is suppose to deal with the maxpktsize (64 byte) limit.
I didn't test a solution yet, but looks like this is wrong:

uint8_t buf[64];

for( i=0; i<nbytes; i++) {
	buf[i] = data[i];
}

nbytes is the number of bytes (total) to be sent, a uint32. But this implementation takes only the fist 64bytes, since buf is 64 bytes long.

This for loop, copying the data to the buffer that will be writen should be done insisde the while (bytes_left) loop. This while loop seems to be OK, treating the message in chunks of 64 bytes and updating bytes_left every iteration.

I will test the solution tomorrow.

@mjunior-fitec
Copy link
Author

mjunior-fitec commented Nov 30, 2018

I just test a simple solution, but unfortunately doesn't seem to work.
Yet...

uint32_t USBHost::OutTransfer(EpInfo *pep, uint32_t nak_limit, uint32_t nbytes, uint8_t *data) {
	uint32_t rcode = 0, retry_count;
	uint8_t *data_p = data; //local copy of the data pointer
	uint32_t bytes_tosend, nak_count;
	uint32_t bytes_left = nbytes;
	uint8_t buf[64];
	uint8_t i;

	uint32_t maxpktsize = pep->maxPktSize;
	
    if(maxpktsize < 1 || maxpktsize > 64)
		return USB_ERROR_INVALID_MAX_PKT_SIZE;

	/*mjunior - removing to fix the >64b bug
	for( i=0; i<nbytes; i++) {
		buf[i] = data[i];
	}
	*/
	//unsigned long timeout = millis() + USB_XFER_TIMEOUT;

	//set toggle value
	if(pep->bmSndToggle)
		USB->HOST.HostPipe[pep->epAddr].PSTATUSSET.reg = USB_HOST_PSTATUSSET_DTGL;
	else
		USB->HOST.HostPipe[pep->epAddr].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_DTGL;

	while(bytes_left) {		
		retry_count = 0;
		nak_count = 0;
		bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left;
		for (i = 0; i < bytes_tosend; i++){
			buf[i] = data_p[i]; //mjunior - set the buf data to be sent in this iteration (** must use data_p **)
		}
		UHD_Pipe_Write(pep->epAddr, bytes_tosend, buf); //filling output FIFO

		//set number of bytes
		//dispatch packet
		//wait for the completion IRQ
		//clear IRQ

		rcode = dispatchPkt(tokOUT, pep->epAddr, nak_limit);
		if (rcode)
		{
			switch(rcode) {
                            // --- NO CHANGES HERE --- //
			}//switch( rcode
		}

		bytes_left -= bytes_tosend;
		data_p += bytes_tosend;
    }//while( bytes_left...
breakout:
    pep->bmSndToggle = USB_HOST_DTGL(pep->epAddr);
    return (rcode); //should be 0 in all cases
}

I basically moved the for loop to inside the while(bytes_left) and adjusted the assignment to data_p and indexing with bytes_tosend.
My testing conditions here are very poor, and by now I just can't check what's going wrong.
As a workarround I am treating the 64b limitations outside the Ftdi.SndData call.

@gdsports
Copy link
Owner

gdsports commented Jul 7, 2019

I think this commit fixes the problem. ac8c323

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants