summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c7582df)
raw | patch | inline | side by side (parent: c7582df)
author | Chitresh Gupta <chitresh.g@pathpartnertech.com> | |
Thu, 15 Sep 2016 13:15:41 +0000 (18:45 +0530) | ||
committer | Frank Livingston <frank-livingston@ti.com> | |
Wed, 5 Oct 2016 18:02:01 +0000 (13:02 -0500) |
diff --git a/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/I2C.h b/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/I2C.h
index 5f45dd333dbb0f0cd09c3912dacaf3a9c8ad2c3a..94b9ec5e43befc6f0390d8dd2bf49173311b8723 100644 (file)
I2C_3P4Mhz = 2
} I2C_BitRate;
+/*!
+ * @brief I2C Master/Slave Mode
+ *
+ * Specify one of the I2C mode of communications.
+ * The default is MASTER.
+ */
+typedef enum I2C_MS_mode_e {
+ I2C_MASTER = 0,
+ I2C_SLAVE = 1
+} I2C_MS_mode;
+
/*!
* @brief I2C Parameters
*
I2C_BitRate bitRate; /*!< I2C bus bit rate */
void *custom; /*!< Custom argument used by driver
implementation */
+ I2C_MS_mode isSlave; /* Master = 0, Slave = 1 */
} I2C_Params;
/*!
diff --git a/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/src/I2C_drv.c b/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/src/I2C_drv.c
index f5d990a0bef8c9946d6e440d35e743515894aab0..3ec3c775a3062592eb0ec5adf8e4e7876a2c67c3 100644 (file)
I2C_MODE_BLOCKING, /* transferMode */
NULL, /* transferCallbackFxn */
I2C_100kHz, /* bitRate */
- NULL
+ NULL,
+ I2C_MASTER
};
/*
diff --git a/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/src/v0/I2C_lld_v0.c b/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/src/v0/I2C_lld_v0.c
index e0aee8a6905f32d517041f8606621d0d42812c84..526e5910d673c830d199a580f97242d1e7bf8495 100644 (file)
i2cRegs->ICMDR |= CSL_I2C_ICMDR_IRS_MASK;
}
+/**
+ * \brief Enables the I2C module.This will bring the I2C module out of reset.
+ *
+ * \param baseAdd It is the Memory address of the I2C instance used.
+ *
+ * \return None.
+ *
+ **/
+void I2CSlaveEnable(uint32_t baseAdd)
+{
+ CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAdd;
+
+ /* Set Own Address */
+ i2cRegs->ICOAR = 0x11; // testI2C_OWN_ADDR;
+
+ /* Enable SLAVE mode */
+ i2cRegs->ICMDR &= ~CSL_I2C_ICMDR_MST_MASK;
+ i2cRegs->ICMDR |= CSL_I2C_ICMDR_FREE_MASK;
+
+ /* Bring I2C out of reset */
+ i2cRegs->ICMDR |= CSL_I2C_ICMDR_IRS_MASK;
+}
+
/**
* \brief Disables the I2C Module.This will put the I2C module in reset.
* Only Tx and Rx are cleared,status bits are set their default
return (I2CMasterIntStatusEx(baseAdd, errMask));
}
+uint32_t I2CSlaveErr(uint32_t baseAdd)
+{
+ uint32_t errMask;
+
+ errMask = I2C_INT_ARBITRATION_LOST |
+ I2C_INT_NO_ACK |
+ I2C_INT_STOP_CONDITION |
+ I2C_INT_ADRR_ZERO |
+ I2C_INT_RECV_OVER_RUN ;
+
+ return (I2CMasterIntStatusEx(baseAdd, errMask));
+}
+
+
/**
* \brief This API configure I2C in different modes of operation.
*
i2cRegs->ICMDR = i2cMdr;
}
+void I2CSlaveControl(uint32_t baseAdd, uint32_t ctrlMask, uint32_t ctrlCmds)
+{
+ CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAdd;
+ uint32_t i2cMdr = i2cRegs->ICMDR;
+
+ i2cMdr &= ~(ctrlMask | CSL_I2C_ICMDR_MST_MASK);
+ i2cMdr |= (ctrlCmds);
+ i2cRegs->ICMDR = i2cMdr;
+}
+
/**
* \brief This API starts a I2C transaction on the bus. This API must
* be called after all the configuration for the i2c module is
i2cRegs->ICMDR |= (CSL_I2C_ICMDR_MST_MASK | CSL_I2C_ICMDR_STT_MASK);
}
+void I2CSlaveStart(uint32_t baseAdd)
+{
+ CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAdd;
+
+ i2cRegs->ICMDR &= ~CSL_I2C_ICMDR_MST_MASK;
+ i2cRegs->ICMDR |= (CSL_I2C_ICMDR_STT_MASK);
+}
+
/**
* \brief This API stops a I2C transaction on the bus.
* This API must be used in case a deliberate STOP needs to be sent
i2cRegs->ICMDR |= (CSL_I2C_ICMDR_MST_MASK | CSL_I2C_ICMDR_STP_MASK);
}
+void I2CSlaveStop(uint32_t baseAdd)
+{
+ CSL_I2cRegsOvly i2cRegs = (CSL_I2cRegsOvly)baseAdd;
+
+ i2cRegs->ICMDR &= ~CSL_I2C_ICMDR_MST_MASK;
+ i2cRegs->ICMDR |= (CSL_I2C_ICMDR_STP_MASK);
+}
/**
* \brief This API enables only specified I2C interrupts in master mode.
*
diff --git a/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/src/v0/I2C_lld_v0.h b/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/src/v0/I2C_lld_v0.h
index 20533374c3777404674046b01b30316a71201f39..bada1c4fcf5f275d28dc9bfd940f908a7c5a232c 100644 (file)
/* I2C AM57x hardware register read/write functions */
extern void I2CMasterStop(uint32_t baseAdd);
+extern void I2CSlaveStop(uint32_t baseAdd);
extern void I2CMasterStart(uint32_t baseAdd);
+extern void I2CSlaveStart(uint32_t baseAdd);
extern void I2CMasterEnable(uint32_t baseAdd);
+extern void I2CSlaveEnable(uint32_t baseAdd);
extern void I2CMasterDisable(uint32_t baseAdd);
extern uint32_t I2CMasterErr(uint32_t baseAdd);
+extern uint32_t I2CSlaveErr(uint32_t baseAdd);
extern uint32_t I2CDataCountGet(uint32_t baseAdd);
extern uint8_t I2CMasterDataGet(uint32_t baseAdd);
extern bool I2CMasterBusBusy(uint32_t baseAdd);
extern void I2CMasterControl(uint32_t baseAdd, uint32_t ctrlMask, uint32_t ctrlCmds);
+extern void I2CSlaveControl(uint32_t baseAdd, uint32_t ctrlMask, uint32_t ctrlCmds);
extern void I2CSetDataCount(uint32_t baseAdd, uint32_t count);
extern void I2CMasterDataPut(uint32_t baseAdd, uint8_t data);
extern void I2CMasterInitExpClk(uint32_t baseAdd, uint32_t sysClk,
diff --git a/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/src/v0/I2C_v0.c b/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/src/v0/I2C_v0.c
index b9ddce8ea69327f24eec17836cf93a4625f15cf9..0d70bb221530ddfbf48eee7a372ae349c452c53a 100644 (file)
}
/* Check for I2C Errors */
- errStatus = I2CMasterErr(hwAttrs->baseAddr);
+ if (object->isSlave != 1)
+ {
+ errStatus = I2CMasterErr(hwAttrs->baseAddr);
+ }
+ else
+ {
+ errStatus = I2CSlaveErr(hwAttrs->baseAddr);
+ }
if (errStatus & I2C_INT_STOP_CONDITION)
{
if ((object->writeCountIdx == 0U) && (object->readCountIdx == 0U))
{
- /* End of transfer stop condition, not an error */
- errStatus &= ~I2C_INT_STOP_CONDITION;
+ /* End of transfer stop condition, not an error */
+ errStatus &= ~I2C_INT_STOP_CONDITION;
}
+ else if (object->isSlave == 1)
+ {
+ /* End of transfer stop condition, not an error */
+ errStatus &= ~I2C_INT_STOP_CONDITION;
+ // Change mode to exit
+ object->mode = I2C_ERROR;
+ }
+
}
- if ((errStatus == I2C_MASTER_ERR_NONE) || (object->mode == I2C_ERROR)) {
+ if ((errStatus == I2C_MASTER_ERR_NONE) || (object->mode == I2C_ERROR))
+ {
/* No errors, now check what we need to do next */
- switch (object->mode) {
+ switch (object->mode)
+ {
/*
* ERROR case is OK because if an Error is detected, a STOP bit is
* sent; which in turn will call another interrupt. This interrupt
/* Set number of bytes to receive */
I2CSetDataCount(hwAttrs->baseAddr, object->readCountIdx);
- /* Configure peripheral for I2C Receive mode with stop */
- I2CMasterControl(hwAttrs->baseAddr,
- I2C_CFG_MASK_RX | I2C_CFG_MASK_REPEAT_MODE,
- I2C_CFG_CMD_RX | I2C_CFG_CMD_REPEAT_MODE_OFF);
+ if (object->isSlave != 1)
+ {
+ /* Configure peripheral for I2C Receive mode with stop */
+ I2CMasterControl(hwAttrs->baseAddr,
+ I2C_CFG_MASK_RX | I2C_CFG_MASK_REPEAT_MODE,
+ I2C_CFG_CMD_RX | I2C_CFG_CMD_REPEAT_MODE_OFF);
+ }
+ else
+ {
+ /* Configure peripheral for I2C Receive mode with stop */
+ I2CSlaveControl(hwAttrs->baseAddr,
+ I2C_CFG_MASK_RX | I2C_CFG_MASK_REPEAT_MODE,
+ I2C_CFG_CMD_RX | I2C_CFG_CMD_REPEAT_MODE_OFF);
+ }
/* Enable RX interrupt to handle data received */
I2CMasterIntEnableEx(hwAttrs->baseAddr, I2C_INT_RECV_READY);
- /* Start I2C peripheral in RX mode */
- I2CMasterStart(hwAttrs->baseAddr);
+ if (object->isSlave != 1)
+ {
+ /* Start I2C peripheral in RX mode */
+ I2CMasterStart(hwAttrs->baseAddr);
+ }
+ else
+ {
+ /* Start I2C peripheral in RX mode */
+ I2CSlaveStart(hwAttrs->baseAddr);
+ }
}
}
break;
/* Disable RX interrupt, next interrupt will be from STOP */
I2CMasterIntDisableEx(hwAttrs->baseAddr,
I2C_INT_RECV_READY);
- /* Send stop */
- I2CMasterStop(hwAttrs->baseAddr);
+ if (object->isSlave != 1)
+ {
+ /* Send stop */
+ I2CMasterStop(hwAttrs->baseAddr);
+ }
+ else
+ {
+ I2CSlaveStop(hwAttrs->baseAddr);
+ }
}
break;
/* Some sort of error happened! */
object->mode = I2C_ERROR;
- /* Try to send a STOP bit to end all I2C communications immediately */
- I2CMasterStop(hwAttrs->baseAddr);
+ if (object->isSlave != 1)
+ {
+ /* Try to send a STOP bit to end all I2C communications immediately */
+ I2CMasterStop(hwAttrs->baseAddr);
+ }
+ else
+ {
+ I2CSlaveStop(hwAttrs->baseAddr);
+ }
}
if (hwAttrs->intcMuxNum != INVALID_INTC_MUX_NUM)
else {
/* Copy the params contents */
object->i2cParams = *params;
+ object->isSlave = params->isSlave;
}
/* extract operational mode from i2cparams and hardware attributes */
{
if (hwAttrs->intcMuxNum != INVALID_INTC_MUX_NUM)
{
- /* Setup Chip Interrupt Controller */
+ /* Setup Chip Interrupt Controller */
muxInParams.arg = (uintptr_t)handle;
muxInParams.muxNum = hwAttrs->intcMuxNum;
muxInParams.muxInEvent = hwAttrs->intcMuxInEvent;
/* Mask off all interrupts */
I2CMasterIntDisableEx(hwAttrs->baseAddr, I2C_ALL_INTS);
- /* Enable the I2C Master for operation */
- I2CMasterEnable(hwAttrs->baseAddr);
+ if (object->isSlave != 1)
+ {
+ /* Enable the I2C Master for operation */
+ I2CMasterEnable(hwAttrs->baseAddr);
+ }
+ else
+ {
+ I2CSlaveEnable(hwAttrs->baseAddr);
+ }
}
}
/* Return the address of the i2cObjectArray[i] configuration struct */
/* clear all interrupts */
I2CMasterIntClearEx(hwAttrs->baseAddr, I2C_ALL_INTS);
+
/* Enable interrupts on stop and error bits */
I2CMasterIntEnableEx(hwAttrs->baseAddr,
I2C_INT_ARBITRATION_LOST |
I2C_INT_NO_ACK |
I2C_INT_STOP_CONDITION);
+
+ if (object->isSlave == 1)
+ {
+
+ /* Start transfer in Receive mode */
+ if (object->readCountIdx)
+ {
+ object->mode = I2C_READ_MODE;
+
+ /* set number of bytes to read */
+ I2CSetDataCount(hwAttrs->baseAddr, object->readCountIdx);
+
+ /* set to Slave receiver mode */
+ I2CSlaveControl(hwAttrs->baseAddr,
+ I2C_CFG_MASK_RX | I2C_CFG_MASK_REPEAT_MODE,
+ I2C_CFG_CMD_RX | I2C_CFG_CMD_REPEAT_MODE_OFF);
+
+ /* Enable RX interrupts */
+ I2CMasterIntEnableEx(hwAttrs->baseAddr, I2C_INT_RECV_READY);
+
+ /* Send start bit */
+ I2CSlaveStart(hwAttrs->baseAddr);
+
+ I2C_drv_log1("\n I2C:(0x%x) I2C_IDLE_MODE: -> I2C_READ_MODE; Reading w/ NACK \n",
+ hwAttrs->baseAddr);
+ }
+
+ /* Start transfer in Transmit mode */
+ else /*if (object->writeCountIdx)*/ {
+ /* Set number of bytes to be transmitting */
+ I2CSetDataCount(hwAttrs->baseAddr, object->writeCountIdx);
+
+ /*
+ * Configure the I2C transfer to be in master transmitter mode,
+ * and to automatically send stop when done.
+ */
+ I2CSlaveControl(hwAttrs->baseAddr,
+ I2C_CFG_MASK_TX | I2C_CFG_MASK_REPEAT_MODE,
+ I2C_CFG_CMD_TX | I2C_CFG_CMD_REPEAT_MODE_OFF);
+
+ /* Log the transaction */
+ I2C_drv_log3("\n I2C:(0x%x) I2C_IDLE_MODE: Data to write: 0x%x; To Slave: 0x%x \n",
+ hwAttrs->baseAddr, *(object->writeBufIdx),
+ object->currentTransaction->slaveAddress);
+
+ /* Write data into transmit FIFO */
+ I2CMasterDataPut(hwAttrs->baseAddr, *(object->writeBufIdx));
+ (object->writeBufIdx)++;
+
+ /* Decrement write index */
+ object->writeCountIdx--;
+
+ if ((object->writeCountIdx != 0U) || (object->readCountIdx != 0U)) {
+ /* We will have more data to process */
+ object->mode = I2C_WRITE_MODE;
+ }
+ else {
+ /*
+ * We will be able to transmit all our data without any
+ * intervention from the ISR. Set mode = idle so when we send a
+ * stop bit, all the ISR does is post the semaphore.
+ */
+ object->mode = I2C_IDLE_MODE;
+ }
+
+ if (object->writeCountIdx) {
+ /*
+ * We were not able to transmit all the data, enable
+ * transmit interrupt to re-fill Data transmit register on
+ * under-run condition.
+ */
+ I2CMasterIntEnableEx(hwAttrs->baseAddr, I2C_INT_TRANSMIT_READY);
+ }
+
+
+ /* Start the I2C transfer in master transmit mode */
+ I2CSlaveStart(hwAttrs->baseAddr);
+
+ I2C_drv_log1("\n I2C:(0x%x) I2C_IDLE_MODE: -> I2C_WRITE_MODE; Writing w/ START \n",
+ hwAttrs->baseAddr);
+ }
+
+ }
+ else
+ {
+
/* Start transfer in Transmit mode */
if (object->writeCountIdx) {
/* Set number of bytes to be transmitting */
I2C_drv_log1("\n I2C:(0x%x) I2C_IDLE_MODE: -> I2C_READ_MODE; Reading w/ NACK \n",
hwAttrs->baseAddr);
}
+ }
}
else /* POLLING MODE */
{
diff --git a/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/src/v0/I2C_v0.h b/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/i2c/src/v0/I2C_v0.h
index 5ac9a2133424bdceed01d11dd072cf10ab929313..6af7bc57064b789b663241fc996613a2a68d7ff8 100644 (file)
I2C_Transaction *tailPtr; /* Tail ptr for queued transactions */
bool isOpen; /* flag to indicate module is open */
+ bool isSlave; /* flag to indicate module is Master or Slave */
} I2C_v0_Object;
/* Invalid Intc Mux number, intc Mux not used if assigned INVALID_INTC_MUX_NUM */
diff --git a/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/spi/src/v0/SPI_lld_v0.c b/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/spi/src/v0/SPI_lld_v0.c
index 96011e418c9c91a497dc0fb52295733a4c9216db..71c870ffdbc5610e8e03f193584d679518fe8ebb 100644 (file)
void SPITransmitData(uint32_t baseAdd, uint32_t csHold, uint32_t txData)
{
uint32_t temp_addr = baseAdd + CSL_SPI_SPIDAT1;
- uint32_t spidat1 = HWREG(temp_addr);
+ uint32_t spidat1 = HWREG(temp_addr);
- spidat1 &= ~(CSL_SPI_SPIDAT1_TXDATA_MASK | CSL_SPI_SPIDAT1_CSHOLD_MASK);
- spidat1 |= (csHold << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) | txData;
+ spidat1 &= ~(CSL_SPI_SPIDAT1_TXDATA_MASK | CSL_SPI_SPIDAT1_CSHOLD_MASK);
+ spidat1 |= (csHold << CSL_SPI_SPIDAT1_CSHOLD_SHIFT) | txData;
/* Load the SPI_TX register with the data to be transmitted */
HWREG(temp_addr) = spidat1;
uint32_t temp_addr = baseAdd + CSL_SPI_SPIGCR1;
HWREG(temp_addr) = (loopback << CSL_SPI_SPIGCR1_LOOPBACK_SHIFT) | \
(powerdown << CSL_SPI_SPIGCR1_POWERDOWN_SHIFT) | \
- (SPI_MASTER_MODE << CSL_SPI_SPIGCR1_MASTER_SHIFT);
+ (clk_master << CSL_SPI_SPIGCR1_MASTER_SHIFT);
}
/**
@@ -418,6 +418,24 @@ void SPIDataFormatSetup(uint32_t baseAdd, uint32_t df_sel, uint32_t inputClkFreq
(df_sel << CSL_SPI_SPIDAT1_DFSEL_SHIFT);
}
+
+void SPIDataFormatSetupSlave(uint32_t baseAdd, uint32_t df_sel, uint32_t inputClkFreq,
+ uint32_t spiOutClk, uint32_t clockMode, uint32_t charLen)
+{
+ uint32_t temp_addr = baseAdd + CSL_SPI_SPIFMT(df_sel);
+
+ /* Clear the DFSEL field of SPI_SPIDAT1 register. */
+ HWREG(temp_addr) = \
+ ((charLen << CSL_SPI_SPIFMT_CHARLEN_SHIFT) & CSL_SPI_SPIFMT_CHARLEN_MASK);
+
+ temp_addr = baseAdd + CSL_SPI_SPIDAT1;
+ /* Clear the DFSEL field of SPI_SPIDAT1 register. */
+ HWREG(temp_addr) &= ~CSL_SPI_SPIDAT1_DFSEL_MASK;
+
+ /* Set the DFSEL field with the user sent value. */
+ HWREG(temp_addr) |=
+ (df_sel << CSL_SPI_SPIDAT1_DFSEL_SHIFT);
+}
/**
* \brief This call will setup the chip select delays
* of the SPI peripheral.
((t2cDelay << CSL_SPI_SPIDELAY_T2CDELAY_SHIFT) & CSL_SPI_SPIDELAY_T2CDELAY_MASK);
temp_addr = baseAdd + CSL_SPI_SPIFMT(0);
- if ((c2tDelay != 0U) && (t2cDelay != 0U))
- {
+ if ((c2tDelay != 0U) && (t2cDelay != 0U))
+ {
HWREG(temp_addr) &= ~CSL_SPI_SPIFMT_DISCSTIMERS_MASK;
- }
- else
+ }
+ else
{
HWREG(temp_addr) |= CSL_SPI_SPIFMT_DISCSTIMERS_MASK;
}
void SPISetShiftDir(uint32_t baseAdd, uint32_t shift_dir)
{
uint32_t temp_addr = baseAdd + CSL_SPI_SPIFMT(0);
- if (shift_dir)
- {
+ if (shift_dir)
+ {
HWREG(temp_addr) |= CSL_SPI_SPIFMT_SHIFTDIR_MASK;
- }
- else
+ }
+ else
{
HWREG(temp_addr) &= ~CSL_SPI_SPIFMT_SHIFTDIR_MASK;
}
diff --git a/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/spi/src/v0/SPI_lld_v0.h b/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/spi/src/v0/SPI_lld_v0.h
index 7b0d678612aab4bc38b4fdd0d1adf6f7f2164464..06103e2039df923f661903d4f5a78c4e4089cd21 100644 (file)
#define SPI_POWERDOWN_ON (CSL_SPI_SPIGCR1_POWERDOWN_ENABLE)
#define SPI_POWERDOWN_OFF (CSL_SPI_SPIGCR1_POWERDOWN_DISABLE)
#define SPI_MASTER_MODE (3U) /* Master mode, SPICLK is an output */
+#define SPI_SLAVE_MODE (0U) /* Slave mode, SPICLK is an input */
/*
** Values used to configure the SPI Pin Control Register 0 (SPIPC0)
uint32_t simoFun, uint32_t clkFun);
extern void SPIDataFormatSetup(uint32_t baseAdd, uint32_t df_sel, uint32_t inputClkFreq,
uint32_t spiOutClk, uint32_t clockMode, uint32_t charLen);
+extern void SPIDataFormatSetupSlave(uint32_t baseAdd, uint32_t df_sel, uint32_t inputClkFreq,
+ uint32_t spiOutClk, uint32_t clockMode, uint32_t charLen);
extern void SPIDelaySetup(uint32_t baseAdd, uint32_t c2tDelay, uint32_t t2cDelay);
extern void SPIData1Setup(uint32_t baseAdd, uint32_t delay_enable, uint32_t cs);
extern Bool SPIRxFull(uint32_t baseAdd);
diff --git a/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/spi/src/v0/SPI_v0.c b/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/spi/src/v0/SPI_v0.c
index f27b832b1aa3d0f347fd96140e5dddf4a090cf0d..4e04e88288a55ca9d980e8b88edcef7615be8f4e 100644 (file)
/* Clear out any pending read data */
do {
- SPIReceiveData(hwAttrs->baseAddr);
+ SPIReceiveData(hwAttrs->baseAddr);
} while(SPIRxFull(hwAttrs->baseAddr));
if(object->operMode != SPI_OPER_MODE_POLLING)
csHold = SPI_CSHOLD_OFF;
}
- /* Wait until TX buffer is empty */
+ /* Wait until TX buffer is empty */
while (SPITxEmpty(hwAttrs->baseAddr) == false)
{}
- /* Write data to TX buffer, if no write data, write 0 */
+ /* Write data to TX buffer, if no write data, write 0 */
if (object->writeBufIdx)
{
SPITransmitData(hwAttrs->baseAddr, csHold, (uint32_t)(*object->writeBufIdx));
{}
rxData = SPIReceiveData(hwAttrs->baseAddr);
- if (object->readBufIdx)
+ if (object->readBufIdx)
{
*object->readBufIdx = (uint8_t)rxData;
object->readBufIdx++;
intCode = SPIIntStatusGet(hwAttrs->baseAddr);
+ /* RX FIFO is full, empty the FIFO to receive more data if necessary */
+ if (intCode & SPI_INT_RX_FULL) {
+ rxData = SPIReceiveData(hwAttrs->baseAddr);
+ if (object->readCountIdx)
+ {
+ /* Read from the SPIBUF */
+ if (object->readBufIdx)
+ {
+ *object->readBufIdx = (uint8_t)rxData;
+ object->readBufIdx++;
+ }
+
+ object->readCountIdx--;
+ }
+
+ SPIIntStatusClear(hwAttrs->baseAddr, SPI_INT_RX_FULL);
+
+ intCode = intCode & ~SPI_INT_RX_FULL;
+ }
+
/*
* Refill the TX FIFO if an TX-empty interrupt has occurred & there is more
* data to transmit.
if (object->writeCountIdx)
{
/* For the last write byte, release the hold if no data read */
- if ((object->writeCountIdx == 1U) && (terminateXfer != 0U))
+ if ((object->writeCountIdx == 1U) && (terminateXfer != 0U) && (object->isSlave == false))
{
csHold = SPI_CSHOLD_OFF;
}
- /* Write data to TX buffer, if no write data, write 0 */
+ /* Write data to TX buffer, if no write data, write 0 */
if (object->writeBufIdx)
{
SPITransmitData(hwAttrs->baseAddr, csHold, (uint32_t)(*object->writeBufIdx));
intCode = intCode & ~SPI_INT_TX_EMPTY;
}
- /* RX FIFO is full, empty the FIFO to receive more data if necessary */
- if (intCode & SPI_INT_RX_FULL) {
- rxData = SPIReceiveData(hwAttrs->baseAddr);
- if (object->readCountIdx)
- {
- /* Read from the SPIBUF */
- if (object->readBufIdx)
- {
- *object->readBufIdx = (uint8_t)rxData;
- object->readBufIdx++;
- }
-
- object->readCountIdx--;
- }
-
- SPIIntStatusClear(hwAttrs->baseAddr, SPI_INT_RX_FULL);
- intCode = intCode & ~SPI_INT_RX_FULL;
- }
/* RX overrun, read SPIBUF twice to get to the overrun buffer */
if (intCode & SPI_INT_RX_OVERRUN)
rxData = SPIReceiveData(hwAttrs->baseAddr);
if (object->readCountIdx)
{
- if (object->readBufIdx)
+ if (object->readBufIdx)
{
*(object->readBufIdx) = (uint8_t)rxData;
(object->readBufIdx)++;
SPIXferDisable(hwAttrs->baseAddr);
SPIIntInit(hwAttrs->baseAddr);
object->transferCallbackFxn((SPI_Handle)arg, object->transaction);
+ if (object->operMode == SPI_OPER_MODE_CALLBACK)
+ {
+ object->transaction = NULL;
+ }
}
- if ((object->readCountIdx == 0U) && (object->readCountIdx == 0U))
+ if ((object->readCountIdx == 0U) && (object->writeCountIdx == 0U))
{
SPIIntInit(hwAttrs->baseAddr);
object->transferCallbackFxn((SPI_Handle)arg, object->transaction);
+ if (object->operMode == SPI_OPER_MODE_CALLBACK)
+ {
+ object->transaction = NULL;
+ }
}
if (hwAttrs->intcMuxNum != INVALID_INTC_MUX_NUM)
}
- /* Extract actual mode */
- if(SPI_MASTER != params->mode)
- {
- /* Does not support slave mode */
- SPI_close_v0(handle);
- ret_flag = 1U;
- handle = NULL;
- }
+ object->isSlave = (bool)(params->mode == 1 ? true : false);
+
if(ret_flag == 0U)
{
SPIReset(hwAttrs->baseAddr);
/* Setup global control */
- SPIGlobalControlSetup(hwAttrs->baseAddr, SPI_LOOPBACK_OFF,
- SPI_POWERDOWN_OFF, SPI_MASTER_MODE);
+ if(SPI_MASTER == params->mode)
+ SPIGlobalControlSetup(hwAttrs->baseAddr, SPI_LOOPBACK_OFF,
+ SPI_POWERDOWN_OFF, SPI_MASTER_MODE);
+ else
+ SPIGlobalControlSetup(hwAttrs->baseAddr, SPI_LOOPBACK_OFF,
+ SPI_POWERDOWN_OFF, SPI_SLAVE_MODE);
+
SPIXferDisable(hwAttrs->baseAddr);
/* Initialize SPI interrupts, by default all disabled */
}
/* Configure data format */
+ if(SPI_MASTER == params->mode)
SPIDataFormatSetup(hwAttrs->baseAddr,
SPI_DFSEL_0,
hwAttrs->inputClkFreq,
params->bitRate,
object->clockMode,
params->dataSize);
+ else
+ SPIDataFormatSetupSlave(hwAttrs->baseAddr,
+ SPI_DFSEL_0,
+ hwAttrs->inputClkFreq,
+ params->bitRate,
+ object->clockMode,
+ params->dataSize);
- SPIDelaySetup(hwAttrs->baseAddr, SPI_C2TDELAY(8U), SPI_T2CDELAY(8U));
- SPIData1Setup(hwAttrs->baseAddr, SPI_DELAY_ON, hwAttrs->csNum);
+ if(SPI_MASTER == params->mode)
+ {
+ SPIDelaySetup(hwAttrs->baseAddr, SPI_C2TDELAY(8U), SPI_T2CDELAY(8U));
+ SPIData1Setup(hwAttrs->baseAddr, SPI_DELAY_ON, hwAttrs->csNum);
+ }
}
}
return (handle);
/* Release the lock for this particular I2C handle */
SPI_osalPostLock(object->mutex);
- object->transaction = NULL;
+ if (object->operMode != SPI_OPER_MODE_CALLBACK) {
+ object->transaction = NULL;
+ }
+
ret = (bool)true;
}
}
diff --git a/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/spi/src/v0/SPI_v0.h b/psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/drv/spi/src/v0/SPI_v0.h
index 37b69103531b3b4e38b0d51146cceddd9c21347e..6f26d8d81f8d7a9d5c97097c3e1ffe20ec1d7131 100644 (file)
uint32_t readCountIdx; /* Internal dec. readCounter */
bool isOpen; /* flag to indicate module is open */
+ bool isSlave; /* flag to indicate module is Master or Slave */
} SPI_v0_Object, *SPI_v0_Handle;
/* Invalid Intc Mux number, intc Mux not used if assigned INVALID_INTC_MUX_NUM */