SPI on LPC54018

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI on LPC54018

Jump to solution
2,606 Views
mohd_
Contributor III

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.

 

 

Tags (1)
0 Kudos
Reply
1 Solution
2,551 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

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;
}

 

View solution in original post

5 Replies
2,571 Views
mohd_
Contributor III

///////

 

0 Kudos
Reply
2,552 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

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;
}

 

2,501 Views
mohd_
Contributor III

//////

0 Kudos
Reply
2,547 Views
mohd_
Contributor III

///////

0 Kudos
Reply
2,587 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

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

 

0 Kudos
Reply