Hello,
I would like to ask for some help finding out how to switch SPI mode during runtime on the LPC4370. I have considered this post made on a similar issue to what I am experiencing but this does not line up with my possibilities using the LPC. This might be very simple but I appear to be rather stuck in this.
I am using SSP1, and have three slaves connected to it. Each slave functions on a different SPI mode. During initialization, I successfully communicate with all three:
1. Slave 0 --> SPI mode 1
2. Slave 1 --> SPI mode 0
3. Slave 2 --> SPI mode 3
But after the initialization of slave 2, I need the following functionality inside of an infinite loop:
1. Communicate with Slave 1 (SPI mode 0)
2. Communicate with slave 2 (SPI mode 3)
3. Return to step 1 and repeat
(Slave 0 is not communicated with anymore).
What I am seeing is that after the initiation of Slave 2, if I want to communicate with slave 1, the SPI mode is stuck to SPI mode 3 (which is expected as I am using a pointer to the SSP base, see code). But when using a Logic Analyser, I am seeing behaviour that is more akin to a different SPI mode (I'd expect to see slave 1 communicate in SPI mode 3):
Setting | Slave 2 | Slave 1 | Result comm. Slave 1 after init. Slave 2 |
Mode | Mode 3 | Mode 0 | Mode 2 |
CPOL | 1 | 0 | 1 |
CPHA | 1 | 0 | 0 |
Setting | Slave 2 | Slave 1 | Result comm. Slave 1 after init. Slave 2 |
Mode | Mode 1 | Mode 0 | Mode 1 |
CPOL | 0 | 0 | 0 |
CPHA | 1 | 0 | 1 |
I need to switch the SPI mode rapidly during runtime to interface with two of the slaves:
Setup:
Infinite loop:
#define LPC_SSP LPC_SSP1
/* Slave 1 initialization */
void SL1_init()
{
(var 'ports' init)
Chip_SSP_Disable(LPC_SSP);
SL1_Init(LPC_SSP, ports, TDC_clock_freq);
}
void SL1_Init(LPC_SSP_T* SPI_BUS, SL_ports config, float Clock_frequency)
{
Slave1_SPI = SPI_BUS; //global var inside of this file
SL1_Init_SPI();
// init ports
Clock_Frequency = Clock_frequency;
}
void SL1_Init_SPI()
{
Chip_SSP_Init(Slave1_SPI);
SSP_ConfigFormat ssp_format;
ssp_format.frameFormat = SSP_FRAMEFORMAT_SPI;
ssp_format.bits = SSP_DATA_BITS;
ssp_format.clockMode = SSP_CLOCK_MODE0;
Chip_SSP_SetFormat(Slave1_SPI, ssp_format.bits, ssp_format.frameFormat, ssp_format.clockMode);
Chip_SSP_SetMaster(Slave1_SPI, 1);
Chip_SSP_SetBitRate(Slave1_SPI, 10000000);
Chip_SSP_Enable(Slave1_SPI);
}
For slave 2:
void Init_Slave2(LPC_SSP_T* spi_bus, Slave2_con config)
{
Slave2_SPI = spi_bus;
Slave2_Init_SPI();
//pin init
}
void Slave2_Init_SPI()
{
// Chip_SSP_Disable(Slave2_SPI);//new
Chip_SSP_Init(Slave2_SPI);
SSP_ConfigFormat ssp_format;
ssp_format.frameFormat = SSP_FRAMEFORMAT_SPI;
ssp_format.bits = SSP_DATA_BITS;
ssp_format.clockMode = SSP_CLOCK_MODE3; //can be 1 or 3
Chip_SSP_SetFormat(Slave2_SPI, ssp_format.bits, ssp_format.frameFormat, ssp_format.clockMode);
Chip_SSP_SetMaster(Slave2_SPI, 1);
Chip_SSP_SetBitRate(Slave2_SPI, 1000000);
Chip_SSP_Enable(Slave2_SPI);
}
Both slaves are changing the pointer directly to LPC_SSP. Which I think is needed? I thought I could 'just' recall the slavex_init_spi() function during runtime, but this resulted in the LPC_SSP C0 register being completely messed up:
Initiation | Measurement loop | |
Slave 1 as defined before Slave 2 | Slave 2 defined | Slave 1 communication (firstly calling the slave1_init_SPI function) |
Hex:0xa07 Binary:101000000111 | Hex:0x65c7 Binary:110010111000111 | Hex:0xfe87 Binary:1111111010000111 |
Do I need to add a forced delay between the re-initiation of the SPI before or after I'm trying to communicate?
I cannot plainly use different SSP ports as the controller is connected to a custom PCB (which has worked before but I do not possess that code).
Thank you for your consideration and take care!
解決済! 解決策の投稿を見る。
The issue was that the
Chip_SSP_Disable(LPC_SSP);
Was not inside of init SPI function. So the SPI was never turned off. Adding this inside of the function made everything work fine.
The issue was that the
Chip_SSP_Disable(LPC_SSP);
Was not inside of init SPI function. So the SPI was never turned off. Adding this inside of the function made everything work fine.