Hi, everyone~
I don't live in an English-speaking country.
So, please understand even if the grammar is not correct:)
To begin with, I have difficulty developing SPI slave mode + I2C Master communication code.
My hardware infomation is as follows.
SPI_Master SPI_Slave / I2C_Master I2C_Slave
(SPC5748G) (MSP430FR2355) (IS31FL3xxxx)
----------------------- ------------------------ ------------------------
SIMO | -----------> | SIMO (P1.2) | | |
SCK | -----------> | SCK (P1.1) | | |
GND | -----------> | GND | -----------> | GND |
VCC | -----------> | VCC | -----------> | VCC |
(4.7K Pull-up)
----------------------- | SDA | -----------> | SDA |
(4.7K Pull-up)
| SCL | -----------> | SCL |
------------------------ ------------------------
MSP430 operates in 3Pin-SPI Slave Mode (A1 Channel) and I2C Master Mode (B0 Channel) with no external crystals
I want to keep sending I2C Data to I2C_Slave(IS31FL3xxxx) while stacking SPI_Master's SPI Data into an array buffer called receiveData.
Currently, it has been confirmed that the operation is normal if only the SPI function and the I2C function are operated separately.
However, when the source code is combined to use both functions, I2C Communication normally, but SPI Communication fail.
When I check with the debugger, several SPI data sent by the SPI_Master are continuously lost.
By the way, if I erase the CS_initFLLSettle() function in the 135th line of the source code, SPI communication works normally again this time, and I2C communication fail.
I would appreciate it if you could give me advice on how to fix the source code
I'll leave my source code below for your check.
-----------------------------------------------------------------------------------------------
#include <msp430.h>
#include "driverlib.h"
#include "Board.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
//*****************************************************************************
//
// Slave LED Driver Address
//
//*****************************************************************************
#define LED_DRIVER_1 0xD8
#define LED_DRIVER_2 0xDA
#define LED_DRIVER_3 0xDC
//*****************************************************************************
//
//Target frequency for SMCLK in kHz
//
//*****************************************************************************
#define CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ 1000
//*****************************************************************************
//
//SMCLK/FLLRef Ratio
//
//*****************************************************************************
#define CS_SMCLK_FLLREF_RATIO 30
//
//*****************************************************************************
void CLOCK_Init(void); // MSP430FR2355(No X-tal) clock initializing
void GPIO_Init(void); // GPIO initializing
void SPI_Init(void); // SPI initializing
void I2C_Init(void); // I2C initializing
void I2C_WRITE_DRIVER(uint8_t address, uint8_t Reg, uint8_t Data); // Command to LED Driver via I2C
void LED_ALL_Breathing(void); // ALL LED Breathing Test Code
uint8_t receiveData[200] = {0, };
uint8_t i2cdata_tx[2] = {0, };
uint8_t index = 0;
uint8_t TXByteCtr;
//*****************************************************************************
void CLOCK_Init(void)
{
//Stop watchdog timer
WDT_A_hold(WDT_A_BASE);
FRCTL0 = FRCTLPW | NWAITS_2;
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source
CSCTL0 = 0; // clear DCO and MOD registers
CSCTL1 |= DCORSEL_7; // Set DCO = 24MHz
CSCTL2 = FLLD_0 + 731; // DCOCLKDIV = 24MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // FLL locked
CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK;
PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode
// to activate previously configured port settings
}
void GPIO_Init(void)
{
// Set P1.0 to output direction
GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN0);
// Configure Pins for 3pin-SPI
/*
* Select Port 1
* Set Pin 1, Pin 2 and Pin 3 to input with function.
*/
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_P4,
GPIO_PIN1 + GPIO_PIN2 + GPIO_PIN3,
GPIO_PRIMARY_MODULE_FUNCTION
);
// Configure Pins for I2C
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_UCB0SCL,
GPIO_PIN_UCB0SCL,
GPIO_FUNCTION_UCB0SCL
);
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_UCB0SDA,
GPIO_PIN_UCB0SDA,
GPIO_FUNCTION_UCB0SDA
);
}
void SPI_Init(void)
{
//Initialize slave to MSB first, inactive high clock polarity and 3 wire SPI
EUSCI_A_SPI_initSlaveParam param = {0};
param.msbFirst = EUSCI_A_SPI_MSB_FIRST;
param.clockPhase = EUSCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT;
param.clockPolarity = EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW;
param.spiMode = EUSCI_A_SPI_3PIN;
EUSCI_A_SPI_initSlave(EUSCI_A1_BASE, ¶m);
//Enable SPI Module
EUSCI_A_SPI_enable(EUSCI_A1_BASE);
EUSCI_A_SPI_clearInterrupt(EUSCI_A1_BASE,
EUSCI_A_SPI_RECEIVE_INTERRUPT
);
//Enable Receive interrupt
EUSCI_A_SPI_enableInterrupt(EUSCI_A1_BASE,
EUSCI_A_SPI_RECEIVE_INTERRUPT
);
__bis_SR_register(GIE); // enable interrupts
}
void I2C_Init(void)
{
CS_initFLLSettle(
CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ,
CS_SMCLK_FLLREF_RATIO
);
//Initialize Master
EUSCI_B_I2C_initMasterParam param = {0};
param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
param.i2cClk = CS_getSMCLK();
param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
param.byteCounterThreshold = 0;
param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, ¶m);
//Set in transmit mode
EUSCI_B_I2C_setMode(EUSCI_B0_BASE,
EUSCI_B_I2C_TRANSMIT_MODE
);
//Enable I2C Module to start operations
EUSCI_B_I2C_enable(EUSCI_B0_BASE);
EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
//Enable master Receive interrupt
EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);
}
void I2C_WRITE_DRIVER(uint8_t address, uint8_t Reg, uint8_t Data)
{
TXByteCtr = 1; // Load TX byte counter
i2cdata_tx[0] = Reg; // Select Register
i2cdata_tx[1] = Data; // Command data
EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, address/2);
while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE));
EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, i2cdata_tx[0]);
}
void LED_ALL_Breathing(void)
{
int i, j, k, l;
I2C_WRITE_DRIVER(LED_DRIVER_1,0x2F,0x00);//reset IC
I2C_WRITE_DRIVER(LED_DRIVER_2,0x2F,0x00);//reset IC
I2C_WRITE_DRIVER(LED_DRIVER_3,0x2F,0x00);//reset IC
I2C_WRITE_DRIVER(LED_DRIVER_1,0x00,0x01);//Enable SSD
I2C_WRITE_DRIVER(LED_DRIVER_2,0x00,0x01);//Enable SSD
I2C_WRITE_DRIVER(LED_DRIVER_3,0x00,0x01);//Enable SSD
for(i=0x14;i<=0x25;i++)
{
I2C_WRITE_DRIVER(LED_DRIVER_1,i,0x10);//enable all LED channel
I2C_WRITE_DRIVER(LED_DRIVER_2,i,0x10);//enable all LED channel
I2C_WRITE_DRIVER(LED_DRIVER_3,i,0x10);//enable all LED channel
}
I2C_WRITE_DRIVER(LED_DRIVER_1,0x26,0x00);//GCC
I2C_WRITE_DRIVER(LED_DRIVER_2,0x26,0x00);//GCC
I2C_WRITE_DRIVER(LED_DRIVER_3,0x26,0x00);//GCC
I2C_WRITE_DRIVER(LED_DRIVER_1,0x27,0x00);//frequency
I2C_WRITE_DRIVER(LED_DRIVER_2,0x27,0x00);//frequency
I2C_WRITE_DRIVER(LED_DRIVER_3,0x27,0x00);//frequency
for(j=0;j<=0xFF;j=j+8)
{
for(i=0x01;i<=0x12;i=i+1)
{
I2C_WRITE_DRIVER(LED_DRIVER_1,i,j);//write all channel PWM with 0x10
I2C_WRITE_DRIVER(LED_DRIVER_2,i,j);//write all channel PWM with 0x10
I2C_WRITE_DRIVER(LED_DRIVER_3,i,j);//write all channel PWM with 0x10
}
I2C_WRITE_DRIVER(LED_DRIVER_1,0x13,0x00);//update PWM and ON/OFF
I2C_WRITE_DRIVER(LED_DRIVER_2,0x13,0x00);//update PWM and ON/OFF
I2C_WRITE_DRIVER(LED_DRIVER_3,0x13,0x00);//update PWM and ON/OFF
}
for(l=0xFF;l>=0;l=l-8)
{
for(k=0x01;k<=0x12;k=k+1)
{
I2C_WRITE_DRIVER(LED_DRIVER_1,k,l);//write all channel PWM with 0x10
I2C_WRITE_DRIVER(LED_DRIVER_2,k,l);//write all channel PWM with 0x10
I2C_WRITE_DRIVER(LED_DRIVER_3,k,l);//write all channel PWM with 0x10
}
I2C_WRITE_DRIVER(LED_DRIVER_1,0x13,0x00);//update PWM and ON/OFF
I2C_WRITE_DRIVER(LED_DRIVER_2,0x13,0x00);//update PWM and ON/OFF
I2C_WRITE_DRIVER(LED_DRIVER_3,0x13,0x00);//update PWM and ON/OFF
}
}
//*****************************************************************************
void main(void)
{
CLOCK_Init();
GPIO_Init();
I2C_Init();
SPI_Init();
while(1)
{
LED_ALL_Breathing(); // infinite Breathing (fade in fade out)
}
}
//******************************************************************************
//
//This is the USCI_B0 interrupt vector service routine.
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A1_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B0_VECTOR)))
#endif
void USCI_A1_ISR (void)
{
switch(__even_in_range(UCA1IV, USCI_SPI_UCTXIFG))
{
case USCI_SPI_UCRXIFG: // UCRXIFG
//USCI_A1 TX buffer ready?
while (!EUSCI_A_SPI_getInterruptStatus(EUSCI_A1_BASE,
EUSCI_A_SPI_TRANSMIT_INTERRUPT
));
//Receive data from master
receiveData[index] = EUSCI_A_SPI_receiveData(EUSCI_A1_BASE);
index++;
if(index >= 116)
{
index = 0;
}
break;
default:
break;
}
}
//------------------------------------------------------------------------------
// The USCIAB0TX_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData
// points to the next byte to transmit.
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B0_VECTOR)))
#endif
void USCIB0_ISR(void)
{
switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
{
case USCI_NONE: // No interrupts break;
break;
case USCI_I2C_UCALIFG: // Arbitration lost
break;
case USCI_I2C_UCNACKIFG: // NAK received (master only)
//resend start if NACK
//EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);
break;
case USCI_I2C_UCTXIFG0: // TXIFG0
// Check TX byte counter
if (TXByteCtr)
{
EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, i2cdata_tx[1]);
// Decrement TX byte counter
TXByteCtr--;
}
else
{
EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
}
break;
default:
break;
}
}
-----------------------------------------------------------------------------------------------
I’d be glad if you could help me.
Thanks.


