Hi,
I am trying to make use of the Colibri iMX7 SOM’s SODIMM pin 22 as a rising edge interrupt signal. My application runs on your WINCE700 BSP.
I have used interrupts before on toradex boards on some other gpios and have been able to get them working. I am unable to understand why it does not seem this time.
Another issue that I noticed is that even though I am configuration the gpio pin to be rising edge triggered when using the Imx7Gpio_SetConfigString() interface, the configuration that I retrieve by calling the Imx7Gpio_GetConfigString() suggests that the gpio is configured for low level interrupt triggering.
Below is the code that I am using to initialize the gpio and the interrupt irqs
/* Inititalize the GPIO interupt for the interrupt from FPGA for data request
*/
int printTestingInterruptInit( void )
{
BOOL fSuccess = TRUE;
DWORD irqNum = 0;
TCHAR configString[200];
/// Initialize the interrupt input gpio as a rising edge triggered interrupt input
if(!Imx7Gpio_SetConfigString( hGpio, ioPrintingTestDataRequest, NULL, L"AltFn=-1,dir=in,pull=up47k,inmode=std,irqtrig=rising", StoreVolatile)) {
LOG_ERROR("\nERROR, [%s, %d], Failed to initialize the print test interrupt gpio", __FUNCTION__, __LINE__ );
return ERROR_FPGA_INIT_FPGA_INTERRUPT;
}
LOG_ERROR("\nOK, [%s, %d], Print testing gpio set config string ok", __FUNCTION__, __LINE__ );
/// Initialize the interrupt input gpio as a rising edge triggered interrupt input
if(!Imx7Gpio_GetConfigString( hGpio, ioPrintingTestDataRequest, NULL, configString, sizeof(configString))) {
LOG_ERROR("\nERROR, [%s, %d], Failed to gett gpio config string", __FUNCTION__, __LINE__ );
}
printf("\nCHECK, [%s, %d], Config string retrieved %S", __FUNCTION__, __LINE__, configString);
// Get Irq number from GPIO number
if( !Imx7Gpio_GetConfigInt( hGpio, ioPrintingTestDataRequest, L"irq", &irqNum) ){
LOG_ERROR("\nERROR, [%s, %d], Failed to initialize the print test interrupt gpio", __FUNCTION__, __LINE__ );
return ERROR_FPGA_INIT_FPGA_INTERRUPT;
}
printf("\nCHECK, [%s, %d], Irq number %u", __FUNCTION__, __LINE__, irqNum);
/*IST init for Data request from FPGA*/
// Create an Event
hPrintingTestDataRequest = CreateEvent(NULL, FALSE, FALSE, PRINTING_TEST_DATA_REQUEST_EVENT );
if( hPrintingTestDataRequest == NULL ){
LOG_ERROR("\nERROR, [%s, %d], Create printing test data request event failed number %d", __FUNCTION__, __LINE__, GetLastError());
return ERROR_FPGA_INIT_FPGA_INTERRUPT;
}
// Get the system interrupt for the corresponding Irq number
printingTestSysIrq = Int_RequestSysInterrupt( hIntr, irqNum );
if( !printingTestSysIrq ){
LOG_ERROR("\nERROR, [%s, %d], Failed to get the sys irq(%u) mapped to irqNum(%u)", __FUNCTION__, __LINE__, printingTestSysIrq, irqNum );
return ERROR_FPGA_INIT_FPGA_INTERRUPT;
}
printf("\nCHECK, [%s, %d], Sys irq number %u", __FUNCTION__, __LINE__, printingTestSysIrq);
// Initialize interrupt
fSuccess = Int_InterruptInitialize( hIntr, printingTestSysIrq, hPrintingTestDataRequest, NULL, 0 );
if( !fSuccess ) {
LOG_ERROR("\nERROR, [%s, %d], Interrupt initialize failed", __FUNCTION__, __LINE__ );
return ERROR_FPGA_INIT_FPGA_INTERRUPT;
}
printf("\nCHECK, [%s, %d], Interrupt initialize ok", __FUNCTION__, __LINE__);
// If it is required to ignore any interrupt that was triggered before this
// point in time, we need to confirm it, before calling WaitForsingleObject().
// This is only an issue for level-triggered interrupts.
Int_InterruptDone( hIntr, printingTestSysIrq);
// Create thread to handle Interrupt event
hPrintingTest_IST = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)printTest_IST, NULL, CREATE_SUSPENDED, NULL);
//Set this thread to highest priority
fSuccess = CeSetThreadPriority( hPrintingTest_IST, 10 );
if( fSuccess != 0 ){
LOG_MSG("\nOK, [%s, %d], Thread priority set successfully", __FUNCTION__, __LINE__);
}
else{
LOG_ERROR("\nERROR, [%s, %d], Failed to set swathe print thread priority", __FUNCTION__, __LINE__);
return ERROR_FPGA_INIT_FPGA_INTERRUPT;
}
//Start the thread
ResumeThread( hPrintingTest_IST );
return NO_ERROR;
}
Below is the output log from the init code. Notice the irq trigger configuration returned:
OK, [printTestingInterruptInit, 2247], Print testing gpio set config string ok
CHECK, [printTestingInterruptInit, 2253], Config string retrieved dir=in,lvl=1,altfn=0,pull=up47k,strength=0,slew=slow,irqtrig=low,sion=normal
CHECK, [printTestingInterruptInit, 2260], Irq number 196
CHECK, [printTestingInterruptInit, 2277], Sys irq number 30
CHECK, [printTestingInterruptInit, 2285], Interrupt initialize ok
OK, [fpga_initInterface, 461], Data Request interrupt init OK
and this is my thread waiting for the interrupt, it continues to timeout on the event that is supposed to be signaled when the interrupt is received.
DWORD WINAPI printTest_IST( LPVOID lpParam )
{
DWORD waitResult = WAIT_OBJECT_0;
HANDLE waitHandles[2] = { INVALID_HANDLE_VALUE };
INT32 carriagePos = 0;
//Create an event to signal application exit
waitHandles[0] = CreateEvent( NULL, TRUE, FALSE, _T("ExitApp") );
if( waitHandles[0] == NULL ){
DWORD error = GetLastError();
LOG_ERROR("\nERROR, [%s, %d], Failed to create ExitApp Event error(%d]", __FUNCTION__, __LINE__, error);
}
waitHandles[1] = hPrintingTest;
while ( 1 )
{
/// Wait until swathe printing is ON or exit app is signalled
waitResult = WaitForMultipleObjects( 2, waitHandles, FALSE, INFINITE );
if( waitResult == WAIT_FAILED ){
LOG_ERROR("\nERROR, [%s, %d], Wait failed, error %u", __FUNCTION__, __LINE__, GetLastError());
goto EXIT_PRINTING_TEST_IST;
}
else if( waitResult == WAIT_OBJECT_0 ){
LOG_ERROR("\nCHECK, [%s, %d], Exit app event found set, exiting thread", __FUNCTION__, __LINE__ );
goto EXIT_PRINTING_TEST_IST;
}
//LOG_ERROR("\nCHECK, [%s, %d], Printing test event found set", __FUNCTION__, __LINE__);
/// Timed wait checking for interrupts from the FPGA.
/// in case of time out recheck in case swathe printing has ended, this is to take care
/// in case the FPGA did not send any interrupts while the swathe printing was on
/// didn't send any interrupt
waitResult = WaitForSingleObject( hPrintingTestDataRequest, 2000 );
if( waitResult == WAIT_TIMEOUT ){
LOG_ERROR("\nCHECK, [%s, %d], Waiting for interrupt signal", __FUNCTION__, __LINE__);
continue;
/// This let's us check whether the swathe printing is still ON
}
else if( waitResult == WAIT_FAILED ){
LOG_ERROR("\nERROR, [%s, %d], Wait failed, error %u", __FUNCTION__, __LINE__, GetLastError());
goto EXIT_PRINTING_TEST_IST;
}
/// Check if swathe printing is complete
Int_InterruptDone( hIntr, printingTestSysIrq );
/// Wait signalled, i.e. rising edge interrupt registered by the system
/// Check for spikes
if( Imx7Gpio_GetLevel( hGpio, ioPrintingTestDataRequest ) == ioLow ){
/// Spurious edge detected
LOG_ERROR("\nERROR, [%s, %d], Spurious edge detected on SODIMM 24", __FUNCTION__, __LINE__);
continue;
}
fpga_writeWord( 510, 1 ); /// Address at which the FPGA will generate
/// reset its internal data buffers
for( int i = 0 ; i < HEADS_IN_USE ; i++ ) {
fpga_loadPrintData( i, printTestData );
}
fpga_writeWord( 126, 1 ); /// Address at which the FPGA will generate
/// firing sequence for the print heads
}
EXIT_PRINTING_TEST_IST:
LOG_ERROR("\nCHECK, [%s, %d], Exiting thread", __FUNCTION__, __LINE__ );
CloseHandle( waitHandles[0] );
CloseHandle( waitHandles[1] );
return NO_ERROR;
}