Add missing HSCMI configuration options; Make HSMCI configuration naming more compatible; Fix HSCMI clocking to use the CLKODD bit

This commit is contained in:
Gregory Nutt 2014-03-24 14:25:40 -06:00
parent ff7c62574a
commit fa3f78c821
2 changed files with 89 additions and 50 deletions

View File

@ -1131,6 +1131,52 @@ config SAM34_EMAC_ISETH0
endmenu # EMAC device driver options
endif # SAM34_EMAC
if SAM34_HSMCI
menu "AT91SAM3/4 HSMCI device driver options"
config SAM34_HSMCI_RDPROOF
bool "Read Proof Enable"
default n
---help---
Enabling Read Proof allows to stop the HSMCI Clock during read
access if the internal FIFO is full. This will guarantee data
integrity, not bandwidth.
config SAM34_HSMCI_WRPROOF
bool "Write Proof Enable"
default n
---help---
Enabling Write Proof allows to stop the HSMCI Clock during write
access if the internal FIFO is full. This will guarantee data
integrity, not bandwidth.
config SAM34_HSMCI_XFRDEBUG
bool "HSMCI transfer debug"
depends on DEBUG_FS && DEBUG_VERBOSE
default n
---help---
Enable special debug instrumentation analyze HSMCI data transfers.
This logic is as non-invasive as possible: It samples HSMCI
registers at key points in the data transfer and then dumps all of
the registers at the end of the transfer. If DEBUG_DMA is also
enabled, then DMA register will be collected as well. Requires also
DEBUG_FS and DEBUG_VERBOSE.
config SAM34_HSMCI_CMDDEBUG
bool "HSMCI command debug"
depends on DEBUG_FS && DEBUG_VERBOSE
default n
---help---
Enable special debug instrumentation analyze HSMCI commands. This
logic is as non-invasive as possible: It samples HSMCI registers at
key points in the data transfer and then dumps all of the registers
at the end of the transfer. If DEBUG_DMA is also enabled, then DMA
register will be collected as well. Requires also DEBUG_FS and
DEBUG_VERBOSE.
endmenu # HSMCI device driver options
endif # SAM34_HSMCI
if SAM34_UDP
menu "AT91SAM3/4 USB Full Speed Device Controller driver (DCD) options"

View File

@ -1216,52 +1216,46 @@ static void sam_req_wrsetup(struct sam_usbdev_s *priv,
/* Get the number of bytes remaining to be sent. */
DEBUGASSERT(privreq->req.xfrd < privreq->req.len);
nbytes = privreq->req.len - privreq->req.xfrd;
/* If we are not sending a zero length packet, then clip the size to
* maxpacket and check if we need to send a following zero length packet.
/* Either send the maxpacketsize or all of the remaining data in
* the request.
*/
if (nbytes > 0)
if (nbytes >= privep->ep.maxpacket)
{
/* Either send the maxpacketsize or all of the remaining data in
* the request.
*/
if (nbytes >= privep->ep.maxpacket)
{
nbytes = privep->ep.maxpacket;
}
/* This is the new number of bytes "in-flight" */
privreq->inflight = nbytes;
usbtrace(TRACE_WRITE(USB_EPNO(privep->ep.eplog)), nbytes);
/* The new buffer pointer is the started of the buffer plus the number
* of bytes successfully transfered plus the number of bytes previously
* "in-flight".
*/
buf = privreq->req.buf + privreq->req.xfrd;
/* Write packet in the FIFO buffer */
fifo = (uint8_t *)
((uint32_t *)SAM_UDPHSRAM_VSECTION + (EPT_VIRTUAL_SIZE * epno));
for (; nbytes; nbytes--)
{
*fifo++ = *buf++;
}
/* Indicate that there is data in the TX packet memory. This will
* be cleared when the next data out interrupt is received.
*/
privep->epstate = UDPHS_EPSTATE_SENDING;
nbytes = privep->ep.maxpacket;
}
/* This is the new number of bytes "in-flight" */
privreq->inflight = nbytes;
usbtrace(TRACE_WRITE(USB_EPNO(privep->ep.eplog)), nbytes);
/* The new buffer pointer is the started of the buffer plus the number
* of bytes successfully transfered plus the number of bytes previously
* "in-flight".
*/
buf = privreq->req.buf + privreq->req.xfrd;
/* Write packet in the FIFO buffer */
fifo = (uint8_t *)
((uint32_t *)SAM_UDPHSRAM_VSECTION + (EPT_VIRTUAL_SIZE * epno));
for (; nbytes; nbytes--)
{
*fifo++ = *buf++;
}
/* Indicate that there is data in the TX packet memory. This will
* be cleared when the next data out interrupt is received.
*/
privep->epstate = UDPHS_EPSTATE_SENDING;
/* Initiate the transfer and configure to receive the transfer complete
* interrupt.
*/
@ -1379,7 +1373,8 @@ static int sam_req_write(struct sam_usbdev_s *priv, struct sam_ep_s *privep)
}
/* The way that we handle the transfer is going to depend on
* whether or not this endpoint supports DMA.
* whether or not this endpoint supports DMA. In either case
* the endpoint state will transition to SENDING.
*/
if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0)
@ -1424,21 +1419,22 @@ static int sam_req_write(struct sam_usbdev_s *priv, struct sam_ep_s *privep)
}
/* If all of the bytes were sent (including any final zero length
* packet) then we are finished with the request buffer), then we can
* return the request buffer to the class driver. The transfer is not
* finished yet, however. There are still bytes in flight. The
* transfer is truly finished when we are called again and the
* request buffer is empty.
* packet) then we are finished with the request buffer and we can
* return the request buffer to the class driver. The state will
* remain IDLE only if nothing else was put in flight.
*
* Note that we will then loop to check to check the next queued
* write request.
*/
if (privreq->req.len >= privreq->req.xfrd &&
privep->epstate == UDPHS_EPSTATE_IDLE)
if (privep->epstate == UDPHS_EPSTATE_IDLE)
{
/* Return the write request to the class driver */
usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)),
privreq->req.xfrd);
DEBUGASSERT(privreq->req.len == privreq->req.xfrd);
sam_req_complete(privep, OK);
}
}
@ -3577,9 +3573,6 @@ static int sam_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
epno = USB_EPNO(ep->eplog);
req->result = -EINPROGRESS;
req->xfrd = 0;
privreq->inflight = 0;
privep->zlpneeded = false;
privep->zlpsent = false;
flags = irqsave();
/* Handle IN (device-to-host) requests. NOTE: If the class device is