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
Tool/software: Code Composer Studio
I'm using MSP432P401R with TI-RTOS(CCS).
My system has 3 tasks(adc, ethernet, encoder).
The encoder is connected to a GPIO interrupt.
The ADC task runs on a 12,500Hz timer and reads it as SPI within the timer callback function.
Since the SPI function consumes about 80us, it can be said that it consumes most of the time here.
The problem is that encoder interrupts are not read correctly.
The encoder generates 2000 pulse/r. As I move the encoder quickly, only 10 pulses are generated. I need to move very very slowly to generate 2000 pulses.
So I've tested it and it seems that there is a conflict with the timer of the ADC task.
When the ADC task runs on a 10Hz timer, the encoder works perfectly.
Can Interrupt and Timer conflict?
How can I solve it?(Interrupt Priority? Multi-interrupt?)
Thank you.
Hi Joonbum,
How are you setting up your SPI transfer mode? It defaults to SPI_MODE_BLOCKING, which will block task execution until the transaction is complete or until a timeout has occurred. Since you say your SPI transactions are taking up most of the time, this may be why you are missing your gpio interrupts.
If this is the case, perhaps try SPI_CALLBACK_MODE instead, as it does not block task execution and is therefore safe to use within a task or interrupt context.
Thanks,
Alexis
Hi Alexis,
Very good idea!
So I'm trying that out right now.
But it doesn't read normally.
And it doesn't fire call back function.
Do you have any examples of using Callback mode?
I tried like this:
void UserCallback1Fxn(SPI_Handle spi, SPI_Transaction* transaction) { printf("callback1\n"); } static void ADS1158_spiInit(void) { SPI_Params_init(&adc1SpiParams); adc1SpiParams.transferMode = SPI_MODE_CALLBACK;/// adc1SpiParams.transferCallbackFxn = UserCallback1Fxn; adc1SpiParams.frameFormat = SPI_POL0_PHA0; adc1SpiParams.bitRate = 12000000; adc1Spi = SPI_open(Board_SPI0, &adc1SpiParams); if(adc1Spi == NULL) { printf("Error initializing spi 1\n"); } } static unsigned char ADS1158_spiReadID(int deviceID) { uint8_t gpioIndex; SPI_Transaction spiTransaction; SPI_Handle spiHandle; unsigned char rxBuffer[2]; unsigned char txBuffer[2]; bool transferOK; txBuffer[0] = OPCODE_RREG | (REG_ADDR_ID & OPCODE_A_MASK); spiTransaction.count = 2; spiTransaction.txBuf = (void *)txBuffer; spiTransaction.rxBuf = (void *)rxBuffer; if(deviceID == 1) { gpioIndex = Board_GPIO_ADC_CS_1; spiHandle = adc1Spi; } else if(deviceID == 2) { gpioIndex = Board_GPIO_ADC_CS_2; spiHandle = adc2Spi; } GPIO_write(gpioIndex, Board_GPIO_LOW); transferOK = SPI_transfer(spiHandle, &spiTransaction); if(!transferOK) { printf("transfer fail\n"); } GPIO_write(gpioIndex, Board_GPIO_HIGH); return rxBuffer[1]; }
Thank you.
Hi Joonbum,
I think you may find this related thread useful: https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/611917?RTOS-MSP432P401R-Clarification-about-SPI-transfer-from-a-HWI-context-
Thanks,
Alexis
Hi Alexis,
The thread seems to be a similar problem to mine.
But I can't find a solution. Is it something I didn't understand?
Thanks
Hi Joonbum,
Here was the verified suggested solution from the post I linked previously:
"you could use a semaphore post based on the generated interrupt from the ADC1298 first from the HWI context. And since you are the master on the SPI, you could then use a thread to call SPI_transfer() with the callback function version so that you are not blocking your other threads. The key thing is that you don't want to starve your other threads just to be polling to be receiving SPI data."
Thanks,
Alexis
Hi Alexis,
OK.
I know what you mean.
The problem has not been resolved in time, and now it has been abandoned. I will try again next time.
Thank you.
**Attention** This is a public forum