Hi, does anyone know how to program SPI using LPC54018 as the master and MCP795 as the slave?
I tried with the demo codes from SDK but I dont understand well.
Thank you in advanced.
Solved! Go to Solution.
Hi, Syamil,
This is the mechanism of the spi code, the SPI_MasterInit() initializes the SPI module, and enable interrupt, after the initialization, the SPI transmit register is empty, which trigger an SPI interrupt, the void SPI_MASTER_IRQHandler(void) is the ISR of SPI.
As you can see that the SPI_WriteData() is called in the ISR SPI_MASTER_IRQHandler(void). That is why I suggest you modify the void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags).
Hope it can help you
BR
XiangJun Rong
void SPI_MASTER_IRQHandler(void)
{
/* read data to avoid rxOverflow */
while (SPI_GetStatusFlags(EXAMPLE_SPI_MASTER) & kSPI_RxNotEmptyFlag)
{
SPI_ReadData(EXAMPLE_SPI_MASTER);
}
/* send data if buffer is not full */
if (SPI_GetStatusFlags(EXAMPLE_SPI_MASTER) & kSPI_TxNotFullFlag)
{
if (masterIndex == 1)
{
/* need to disable interrupts before write last data */
SPI_DisableInterrupts(EXAMPLE_SPI_MASTER, kSPI_TxLvlIrq);
SPI_WriteData(EXAMPLE_SPI_MASTER, (uint16_t)(srcBuff[BUFFER_SIZE - masterIndex]), kSPI_FrameAssert);
}
else
{
SPI_WriteData(EXAMPLE_SPI_MASTER, (uint16_t)(srcBuff[BUFFER_SIZE - masterIndex]), 0);
}
masterIndex--;
}
if (masterIndex == 0U)
{
masterFinished = true;
}
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags)
{
uint32_t control = 0U;
uint32_t instance;
/* check params */
assert(NULL != base);
/* get and check instance */
instance = SPI_GetInstance(base);
/* set data width */
control |= (uint32_t)SPI_FIFOWR_LEN((g_configs[instance].dataWidth));
/* set sssel */
control |= (SPI_DEASSERT_ALL & (~SPI_DEASSERTNUM_SSEL((uint32_t)(g_configs[instance].sselNum))));
/* mask configFlags */
control |= (configFlags & (uint32_t)SPI_FIFOWR_FLAGS_MASK);
/* control should not affect lower 16 bits */
assert(0U == (control & 0xFFFFU));
base->FIFOWR = data | control;
}
///////
Hi, Syamil,
This is the mechanism of the spi code, the SPI_MasterInit() initializes the SPI module, and enable interrupt, after the initialization, the SPI transmit register is empty, which trigger an SPI interrupt, the void SPI_MASTER_IRQHandler(void) is the ISR of SPI.
As you can see that the SPI_WriteData() is called in the ISR SPI_MASTER_IRQHandler(void). That is why I suggest you modify the void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags).
Hope it can help you
BR
XiangJun Rong
void SPI_MASTER_IRQHandler(void)
{
/* read data to avoid rxOverflow */
while (SPI_GetStatusFlags(EXAMPLE_SPI_MASTER) & kSPI_RxNotEmptyFlag)
{
SPI_ReadData(EXAMPLE_SPI_MASTER);
}
/* send data if buffer is not full */
if (SPI_GetStatusFlags(EXAMPLE_SPI_MASTER) & kSPI_TxNotFullFlag)
{
if (masterIndex == 1)
{
/* need to disable interrupts before write last data */
SPI_DisableInterrupts(EXAMPLE_SPI_MASTER, kSPI_TxLvlIrq);
SPI_WriteData(EXAMPLE_SPI_MASTER, (uint16_t)(srcBuff[BUFFER_SIZE - masterIndex]), kSPI_FrameAssert);
}
else
{
SPI_WriteData(EXAMPLE_SPI_MASTER, (uint16_t)(srcBuff[BUFFER_SIZE - masterIndex]), 0);
}
masterIndex--;
}
if (masterIndex == 0U)
{
masterFinished = true;
}
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags)
{
uint32_t control = 0U;
uint32_t instance;
/* check params */
assert(NULL != base);
/* get and check instance */
instance = SPI_GetInstance(base);
/* set data width */
control |= (uint32_t)SPI_FIFOWR_LEN((g_configs[instance].dataWidth));
/* set sssel */
control |= (SPI_DEASSERT_ALL & (~SPI_DEASSERTNUM_SSEL((uint32_t)(g_configs[instance].sselNum))));
/* mask configFlags */
control |= (configFlags & (uint32_t)SPI_FIFOWR_FLAGS_MASK);
/* control should not affect lower 16 bits */
assert(0U == (control & 0xFFFFU));
base->FIFOWR = data | control;
}
//////
///////
Hi, Ahmad,
First of all, I think it is okay to use SPI module as master to read/write the MCP795xx.
This is connection:
LPC54018 MCP795xx:
SSELx CS
SCK SCK
MOSI SI
MISO SO
Regarding the SPI configuration:
configure the CPOL=0 and CPHA=0.
As you have seen that the SPI transfers 24 bits for each transmission. I suggest you refer to the spi_interrupt example code, but you have to rewrite the code especially the function:
void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags)
{
uint32_t control = 0U;
uint32_t instance;
/* check params */
assert(NULL != base);
/* get and check instance */
instance = SPI_GetInstance(base);
/* set data width */
control |= (uint32_t)SPI_FIFOWR_LEN((g_configs[instance].dataWidth));
/* set sssel */
control |= (SPI_DEASSERT_ALL & (~SPI_DEASSERTNUM_SSEL((uint32_t)(g_configs[instance].sselNum))));
/* mask configFlags */
control |= (configFlags & (uint32_t)SPI_FIFOWR_FLAGS_MASK);
/* control should not affect lower 16 bits */
assert(0U == (control & 0xFFFFU));
base->FIFOWR = data | control;
}
so that you can use Byte transfer, keep the /CS is low during the first 2 byte transfer, then write the third byte by setting the EOT bit in the control half word.
Hope it can help you
BR
XiangJun rong