This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Part Number: MSP432P401R
I will give down below the code I use for sending over the SPI.
I need to send very quickly bytes to the CC1200 chip. And because of that, I work without interrupts and I only watch the flag. As soon as it goes up, I send the next byte over the SPI.
First I pull STE low, then I wait for the CC1200 to be ready(wait for the SOMI to go high) and then I send bytes over the SPI. At the end, I wait for the sending to be finished and I pull STE high.
There are two problems:
1. Using the SPI is Busy function doesn't seem to work so I look at the Busy bit manually.
2. Sometimes the SPI doesn't want to set the Interrupt flag for the transmit buffer. After some transmit the flag goes down and doesn't come back up.
This error occurs rarely and I can't find why it happens.
#define CC1200 EUSCI_B0_BASE uint8_t CC1200_Burst_Write(uint8_t* inputBuffer, uint8_t startingAddress, uint8_t length) { int32_t i; uint8_t statusByte; CC1200_Select_Module(); /* Command byte that says burst write from starting address */ CC1200_Transmit_Byte(startingAddress | CC1200_WRITE_BURST); statusByte = CC1200_Receive_Byte(); for(i = 0; i<length; i++) { CC1200_Transmit_Byte(inputBuffer[i]); } CC1200_Deselect_Module(); return statusByte; } static void CC1200_Select_Module() { /* Clear receive interrupt status */ EUSCI_B_SPI_clearInterruptFlag(CC1200_SPI, CC1200_SPI_RECEIVE_INTERRUPT); /* Pull chip select down and wait until SOMI goes down */ MAP_GPIO_setOutputLowOnPin(CC1200_SPI_PORT, CC1200_SPI_STE); while (MAP_GPIO_getInputPinValue(CC1200_SPI_PORT, CC1200_SPI_MISO)); } static void CC1200_Deselect_Module() { /* Wait for the SPI to finish transfer to deselect the module */ while (UCB0STATW & 1); /* After ending transfer, pull chip select up */ MAP_GPIO_setOutputHighOnPin(CC1200_SPI_PORT, CC1200_SPI_STE); } static void CC1200_Transmit_Byte(uint8_t byte) { /* Wait for transmit buffer to be empty and transmit byte */ while (!(EUSCI_B_SPI_getInterruptStatus(CC1200_SPI, CC1200_SPI_TRANSMIT_INTERRUPT))); EUSCI_B_SPI_transmitData(CC1200_SPI, byte); } static uint8_t CC1200_Receive_Byte() { /* Wait for receive flag to read receive register */ while (!(EUSCI_B_SPI_getInterruptStatus(CC1200_SPI, CC1200_SPI_RECEIVE_INTERRUPT))); return EUSCI_B_SPI_receiveData(CC1200_SPI); }
Well,
We are using REV C, and SMCLK 6 MHz. It is synchronous.
I don't know how much you are able to look into this, but here is some info. I looked at the errata but I am currently home, so I will look into it tomorrow.
Currently the only way to achieve this is to manually clear the interrupt bit. If it is cleared this way it won't reassert itself. We are never clearing this bit so it can't be it.
The worst thing is I can't recreate it. It happened to me like 2-3 times in the last six months. Now I gave my code to me partner who is testing my code together with his, and it occurs a few times a day.
We checked, and he doesn't even have any interaction with EUSCIB0.
The only workaround now we can think of is watchdog timer because our systems can recover quickly with it.
Here is the part of the code that has to do with the SPI.
/* SPI Master Configuration Parameter for CC1200 */ static const eUSCI_SPI_MasterConfig spiCC1200Config = { EUSCI_B_SPI_CLOCKSOURCE_SMCLK, // SMCLK Clock Source 6000000, // SMCLK = HFXT/8 = 6MHz 6000000, // SPICLK = 6MHz EUSCI_B_SPI_MSB_FIRST, // MSB First EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT, // Phase EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW, // Low polarity EUSCI_B_SPI_3PIN // 3Wire SPI Mode }; void CC1200_Init() { /* Initialize all SPI related GPIOs and start the SPI module */ MAP_GPIO_setAsOutputPin(CC1200_SPI_PORT, CC1200_SPI_STE); MAP_GPIO_setOutputHighOnPin(CC1200_SPI_PORT, CC1200_SPI_STE); MAP_GPIO_setAsPeripheralModuleFunctionInputPin(CC1200_SPI_PORT, CC1200_SPI_CLK | CC1200_SPI_MOSI | CC1200_SPI_MISO, GPIO_PRIMARY_MODULE_FUNCTION); /* Configure SPI in 3 wire master mode for CC1200 */ SPI_initMaster(CC1200_SPI, &spiCC1200Config); SPI_enableModule(CC1200_SPI); EUSCI_B_SPI_disableInterrupt(CC1200_SPI, CC1200_SPI_TRANSMIT_INTERRUPT); EUSCI_B_SPI_disableInterrupt(CC1200_SPI, CC1200_SPI_RECEIVE_INTERRUPT); }
Hi Evan,
Thank you very much for the answer. It was very helpful. In the mean time, the error kept occurring and we solved it with a simple trick.
After a lot of testing we found a problem in the application. We used the eUSCIB0 SPI in our main and sometimes we used it with DMA at the same time.
This caused the error to occur more frequently but we very quick and solved the problem. Now the problem still occurred from time to time and with additional testing we managed to narrow it down to a problem in the hardware.
To not bother what I was thinking I solved the problem with a little trick. After polling for CC1200_SPI_TRANSMIT_INTERRUPT in this function:
static void CC1200_Transmit_Byte(uint8_t byte) { /* Wait for transmit buffer to be empty and transmit byte */ while (!(EUSCI_B_SPI_getInterruptStatus(CC1200_SPI, CC1200_SPI_TRANSMIT_INTERRUPT))); EUSCI_B_SPI_transmitData(CC1200_SPI, byte); }
I added one line of code:
static void CC1200_Transmit_Byte(uint8_t byte) { /* Wait for transmit buffer to be empty and transmit byte */ while (!(EUSCI_B_SPI_getInterruptStatus(CC1200_SPI, CC1200_SPI_TRANSMIT_INTERRUPT))); EUSCI_B_SPI_clearInterruptFlag(CC1200_SPI, CC1200_SPI_TRANSMIT_INTERRUPT); EUSCI_B_SPI_transmitData(CC1200_SPI, byte); }
Now the error never occurs.
Thanks for the help, and thanks for adding it to the errata.
**Attention** This is a public forum