SAMV7 QSPI: Back out part of last change; byte access are necessary. Correct write to the IAR register

This commit is contained in:
Gregory Nutt 2015-09-06 11:24:43 -06:00
parent 26eada3446
commit f3af146d44

View File

@ -279,8 +279,8 @@ static int qspi_memory_dma(struct sam_qspidev_s *priv,
static int qspi_memory_nodma(struct sam_qspidev_s *priv,
struct qspi_meminfo_s *meminfo);
static void qspi_memcpy(uint32_t *dest, const uint32_t *src,
size_t wordlen);
static void qspi_memcpy(uint8_t *dest, const uint8_t *src,
size_t buflen);
/* Interrupts */
@ -988,11 +988,11 @@ static int qspi_memory_nodma(struct sam_qspidev_s *priv,
struct qspi_meminfo_s *meminfo)
{
uintptr_t qspimem = SAM_QSPIMEM_BASE + meminfo->addr;
uint16_t wordlen;
size_t buflen;
/* Get the length as an even multiple of 32-bit words. */
wordlen = ALIGN_WORDS(meminfo->buflen);
buflen = ALIGN_UP(meminfo->buflen);
/* Enable the memory transfer */
@ -1002,13 +1002,13 @@ static int qspi_memory_nodma(struct sam_qspidev_s *priv,
if (QSPIMEM_ISWRITE(meminfo->flags))
{
qspi_memcpy((uint32_t *)qspimem,
(const uint32_t *)meminfo->buffer, wordlen);
qspi_memcpy((uint8_t *)qspimem,
(const uint8_t *)meminfo->buffer, buflen);
}
else
{
qspi_memcpy((uint32_t *)meminfo->buffer,
(const uint32_t *)qspimem, wordlen);
qspi_memcpy((uint8_t *)meminfo->buffer,
(const uint8_t *)qspimem, buflen);
}
MEMORY_SYNC();
@ -1038,18 +1038,22 @@ static int qspi_memory_nodma(struct sam_qspidev_s *priv,
* 32-bit version of memcpy.
*
* Input Parameters:
* dest - Destination address of the copy
* src - Source address of the copy
* wordlen - The number of 32-bit words to copy.
* dest - Destination address of the copy
* src - Source address of the copy
* buflen - The number of 32-bit words to copy.
*
* Returned Value:
* None
*
****************************************************************************/
static void qspi_memcpy(uint32_t *dest, const uint32_t *src, size_t wordlen)
static void qspi_memcpy(uint8_t *dest, const uint8_t *src, size_t buflen)
{
for (; wordlen > 0; wordlen--)
/* The size of the SPI transfer is equal to the bus access width.
* 8-bit transfers should result in in 8-bit SPI accesses.
*/
for (; buflen > 0; buflen--)
{
*dest++ = *src++;
}
@ -1391,7 +1395,16 @@ static int qspi_command(struct qspi_dev_s *dev,
{
DEBUGASSERT(cmdinfo->addrlen == 3 || cmdinfo->addrlen == 4);
qspi_putreg(priv, cmdinfo->addr, SAM_QSPI_IFR_OFFSET);
/* Set the addressin the IAR. This is required only if the
* instruction frame includes an address, but no data. When data is
* preset, the address of the instruction is determined by the address
* of QSPI memory accesses, and not by the content of the IAR.
*/
qspi_putreg(priv, cmdinfo->addr, SAM_QSPI_IAR_OFFSET);
/* Set/clear the address enable bit and the address size in the IFR */
ifr |= QSPI_IFR_ADDREN;
if (cmdinfo->addrlen == 3)
@ -1421,14 +1434,14 @@ static int qspi_command(struct qspi_dev_s *dev,
if (QSPICMD_ISDATA(cmdinfo->flags))
{
uint16_t wordlen;
uint16_t buflen;
DEBUGASSERT(cmdinfo->buffer != NULL && cmdinfo->buflen > 0);
DEBUGASSERT(IS_ALIGNED(cmdinfo->buffer));
/* Get the length as an even multiple of 32-bit words. */
wordlen = ALIGN_WORDS(cmdinfo->buflen);
buflen = ALIGN_UP(cmdinfo->buflen);
/* Write Instruction Frame Register:
*
@ -1450,27 +1463,43 @@ static int qspi_command(struct qspi_dev_s *dev,
if (QSPICMD_ISWRITE(cmdinfo->flags))
{
/* Set write data operation */
ifr |= QSPI_IFR_TFRTYP_WRITE;
qspi_putreg(priv, ifr, SAM_QSPI_IFR_OFFSET);
/* Write the IFR to the hardware. If the instructrion frame
* includes data, writing to the IFR does not trigger the
* instruction frame transfer. Rather, the instruction frame
* is triggered by the first access to QSPI memory.
*/
(void)qspi_getreg(priv, SAM_QSPI_IFR_OFFSET);
/* Copy the data to write to QSPI_RAM */
qspi_memcpy((uint32_t *)SAM_QSPIMEM_BASE,
(const uint32_t *)cmdinfo->buffer, wordlen);
qspi_memcpy((uint8_t *)SAM_QSPIMEM_BASE,
(const uint8_t *)cmdinfo->buffer, buflen);
}
else
{
/* Set read data operation */
ifr |= QSPI_IFR_TFRTYP_READ;
qspi_putreg(priv, ifr, SAM_QSPI_IFR_OFFSET);
/* Write the IFR to the hardware. If the instructrion frame
* includes data, writing to the IFR does not trigger the
* instruction frame transfer. Rather, the instruction frame
* is triggered by the first access to QSPI memory.
*/
(void)qspi_getreg(priv, SAM_QSPI_IFR_OFFSET);
/* Copy the data from QSPI memory into the user buffer */
qspi_memcpy((uint32_t *)cmdinfo->buffer,
(const uint32_t *)SAM_QSPIMEM_BASE, wordlen);
qspi_memcpy((uint8_t *)cmdinfo->buffer,
(const uint8_t *)SAM_QSPIMEM_BASE, buflen);
}
MEMORY_SYNC();
@ -1501,13 +1530,16 @@ static int qspi_command(struct qspi_dev_s *dev,
* QSPI_IFR_NBDUM(0) No dummy cycles
*/
ifr = QSPI_IFR_WIDTH_SINGLE | QSPI_IFR_INSTEN | QSPI_IFR_TFRTYP_READ |
QSPI_IFR_NBDUM(0);
ifr |= QSPI_IFR_WIDTH_SINGLE | QSPI_IFR_INSTEN | QSPI_IFR_TFRTYP_READ |
QSPI_IFR_NBDUM(0);
qspi_putreg(priv, ifr, SAM_QSPI_IFR_OFFSET);
MEMORY_SYNC();
/* Fall through to INSTRE wait */
/* If the insruction frame does not include data, writing to the IFR
* tiggers sending of the instruction frame. Fall through to INSTRE
* wait.
*/
}
/* When the command has been sent, Instruction End Status (INTRE) will be