GPIO Interrupt service routine based task handling in MSP432

basugouda wrote on Thursday, May 30, 2019:

Hi
I am trying to use a simple task from a gpio interrupt handler using MSP432
I am using the semaphore for executing

The problem is once the interrupt occurs it is jumping to the idle state by dissabling the interrupts by itself

May I know what could be the problem I am litrally stuck here.

Thanks in advance

rtel wrote on Thursday, May 30, 2019:

I think I understand the first part of this, but am unsure of the second
part:

I am trying to use a simple task from a gpio interrupt handler using MSP432
I am using the semaphore for executing

So you are using a semaphore to unblock a task from an interrupt service
routine? If so, please show the code.

The problem is once the interrupt occurs it is jumping to the idle state
by dissabling the interrupts by itself

This is the bit I’m not sure about. By idle state, do you mean the
interrupt service routine is not returning to the task you unblocked
with the semaphore, but returning to the idle task instead? If so, does
it then run the task you unblocked with the semaphore after the next
tick interrupt? If that is the case then it is probably a result of the
way the interrupt is using the API - and showing the code (as requested
above) will let me see that.

I’m not sure what you mean when you say ‘by disabling the interrupts by
itself’.

basugouda wrote on Friday, May 31, 2019:

Thank you for your reply

I was trying to unblock two tasks which are using one semaphore,
Both the tasks are ISR based. I am not sure whether this is right way to do using a single semaphore for two ISR based tasks.


void uart_data(void *p){

	while(1){
			xSemaphoreTake( xBinarySemaphore,portMAX_DELAY );
		  MAP_UART_transmitData(EUSCI_A0_BASE, MAP_UART_receiveData(EUSCI_A0_BASE));
			
		}

}

void led_t(void *p){

	while(1){
		 xSemaphoreTake( xBinarySemaphore,portMAX_DELAY );
		 MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P2,GPIO_PIN1);
		 
		}

}

void EUSCIA0_IRQHandler(void)
{
BaseType_t checkIfYieldRequired = pdFALSE;
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE);
MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status);

if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
{
	xSemaphoreGiveFromISR( xBinarySemaphore, &checkIfYieldRequired );
	portYIELD_FROM_ISR(checkIfYieldRequired);
		}

}

void PORT1_IRQHandler(void)
{
BaseType_t checkIfYieldRequired1 = pdFALSE;
uint32_t status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);

if(status & GPIO_PIN1)
{
	xSemaphoreGiveFromISR( xBinarySemaphore, &checkIfYieldRequired1 );
	portYIELD_FROM_ISR(checkIfYieldRequired1);
		}

}
int main(void){
//xBinarySemaphore=xSemaphoreCreateBinary();
xBinarySemaphore=xSemaphoreCreateCounting;
hw_init();
xTaskCreate(toggle_led_red,“toggle_led”,20,(void *)0,tskIDLE_PRIORITY,&led_red);
if(xBinarySemaphore!=NULL){
xTaskCreate(uart_data,“UART”,200,(void *)0,tskIDLE_PRIORITY,&UART);
xTaskCreate(led_t,“LED”,200,(void *)0,tskIDLE_PRIORITY,&led);
vTaskStartScheduler();
}

while(1){}

}

richarddamon wrote on Friday, May 31, 2019:

One comment, by having two tasks wait on the same semaphore, only one of them will get it when the ISR gives it (If they have different priorities, it will be the one with the higher priority, with the same priority as you have in your test, it isn’t specified which one).

You also have two ISRs set the same semaphore, so the task that is woken isn’t based on which interrupt occured. My first guess is that you want to create two different semaphores, one for the GPIO, and one for the UART.

basugouda wrote on Monday, June 03, 2019:

Thank you for your response I was trying the exact thing which you are telling using a single semaphore to two ISR and found that we got to use two semaphores.

Thanks you for your response