Hallo,
i have the following problem to solve:
an interrupt should be triggered when the frame-signal of a 
SPI-interface changes from 0 to 1. If, at the time of enabling this 
interrupt, the frame-signal is already high, the interrupt should be 
triggered by software instead of the rising edge.
I am using int-structures representing the register-bits of EXTI and 
other peripherals mapped to the according places within the 
bit-banding-area of the micro. These are name XXXbbbits. I am also using 
bit-structures which are representing the structures of their according 
registers to manipulate two or more bits at a time. Those are called 
XXXbits and are mapped to the registers original locations.
My SPI acts as a Slave.
I tried the following:
| 1 |   #define TDXSPIClearFrameInt()            EXTIbbbits.PR.PR4=EXTI_PR_INT_CLR
 | 
| 2 |   #define TDXSPIDisableFrameInt()          EXTIbbbits.IMR.MR4=EXTI_IMR_INT_DIS
 | 
| 3 |   #define TDXSPIEnableFrameInt()          EXTIbbbits.IMR.MR4=EXTI_IMR_INT_EN
 | 
| 4 |   #define TDXSPIClearPendingFrameInt()    NVIC_ClearPendingIRQ(EXTI4_IRQn)
 | 
| 5 |   #define TDXSPISelectRisingFrameInt()    EXTIbbbits.RTSR.TR4=EXTI_RTSR_RE_EN
 | 
| 6 |   #define TDXSPIUnselectRisingFrameInt()  EXTIbbbits.RTSR.TR4=EXTI_RTSR_RE_DIS
 | 
| 7 |   #define TDXSPISelectFallingFrameInt()    EXTIbbbits.FTSR.TR4=EXTI_FTSR_FE_EN
 | 
| 8 |   #define TDXSPIUnselectFallingFrameInt()  EXTIbbbits.FTSR.TR4=EXTI_FTSR_FE_DIS
 | 
| 9 |   #define TDXSPICondRqFrameInt(cond)      EXTIbbbits.SWIER.SWIER4=cond?EXTI_SWIER_INT_RQ:~EXTI_SWIER_INT_RQ
 | 
| 10 |   #define TDXSPIRequestFrameInt()          EXTIbbbits.SWIER.SWIER4=EXTI_SWIER_INT_RQ
 | 
| 11 | 
 | 
| 12 |   #define EXTI_IMR_INT_DIS         0u
 | 
| 13 |   #define EXTI_IMR_INT_EN          1u
 | 
| 14 |   #define EXTI_EMR_EVT_DIS         0u
 | 
| 15 |   #define EXTI_EMR_EVT_EN          1u
 | 
| 16 |   #define EXTI_RTSR_RE_DIS         0u
 | 
| 17 |   #define EXTI_RTSR_RE_EN          1u
 | 
| 18 |   #define EXTI_FTSR_FE_DIS         0u
 | 
| 19 |   #define EXTI_FTSR_FE_EN          1u
 | 
| 20 |   #define EXTI_SWIER_INT_RQ        1u
 | 
| 21 |   #define EXTI_PR_INT_CLR          1u
 | 
| 22 | 
 | 
| 23 | 
 | 
| 24 | void TDXSPISetTimeOut(enum eTDXSPITimeOutIntSources Source)
 | 
| 25 | {
 | 
| 26 |   // Set time-out-value, enable interrupt for retrigger
 | 
| 27 |   // timer is not startet in case of RX or TX since we don't know when the TDX starts transmission
 | 
| 28 |   // timer is started after reception of the first unit
 | 
| 29 |   // timer-interrupt only used for checking FRAME-idle-time
 | 
| 30 |   // FRAME-interrupt is used to start timer in case of TX and FRAME supervision
 | 
| 31 |   // time-out occured when UIF-flag is set
 | 
| 32 |   TDXSPIDisableFrameInt();                              // disable FRAME-interrrupts
 | 
| 33 |   TDXSPIUnselectRisingFrameInt();                        // not sensitive to any edge
 | 
| 34 |   TDXSPIUnselectFallingFrameInt();  
 | 
| 35 |   TDXSPIDisableTimerInt();                              // disable timer-interruptss
 | 
| 36 |   TDXSPIStopTimer();                                    // stop timer
 | 
| 37 |   switch(Source)
 | 
| 38 |   {
 | 
| 39 |     case TDXSPITimeOutIntSource_SPIRX:                  // initialize timer to supervise time-out during reception
 | 
| 40 |       <some initialization>
 | 
| 41 |       break;
 | 
| 42 | 
 | 
| 43 |     case TDXSPITimeOutIntSource_SPITX:                  // initialize timer to supervise time-out during transmission
 | 
| 44 |       <some other initialization>
 | 
| 45 |       break;
 | 
| 46 |     
 | 
| 47 |     case TDXSPITimeOutIntSource_RDY:                    // initialize timer to supervise maximum response-time to RDY
 | 
| 48 |       <some other initialization>
 | 
| 49 |       break;
 | 
| 50 |     
 | 
| 51 |     case TDXSPITimeOutIntSource_FRAME:                  // initialize timer to supervise minimum idle-time of FRAME-signal
 | 
| 52 |       TDXSPITimerReloadReg=TDXSPIFRMMINIDLE;
 | 
| 53 |       TDXSPIUpdateTimer();
 | 
| 54 |       TDXSPIClearTimerStatus();
 | 
| 55 |       TDXSPIDEnableTimerInt();                          // enable timer-INTs
 | 
| 56 |       TDXSPISelectRisingFrameInt();                      // Rising edge interrupt only
 | 
| 57 |       TDXSPIClearFrameInt();                            // clear pending INTs
 | 
| 58 |       TDXSPIClearPendingFrameInt();
 | 
| 59 |       if(TDXSPIFrameIsIdle())                            // request Int manually if FRAME is already idle
 | 
| 60 |       {
 | 
| 61 |         TDXSPIRequestFrameInt();
 | 
| 62 |       }
 | 
| 63 |       TDXSPIEnableFrameInt();                            // enable FRAME-INTs
 | 
| 64 |     break;
 | 
Unfortunately, no interrupt is issued by software. The interrupt is 
triggered only by hardware when the next positive edge occurs. But this 
is one telegram to late.
If I exchange the last two commands, it runs ok:
| 1 |       TDXSPIEnableFrameInt();                            // enable FRAME-INTs
 | 
| 2 |       if(TDXSPIFrameIsIdle())                            // request Int manually if FRAME is already idle
 | 
| 3 |       {
 | 
| 4 |         TDXSPIRequestFrameInt();
 | 
| 5 |       }
 | 
But, I ran into a race-condition when FRAME has its positive edge while 
the TDXSPIEnableFrameInt() is executed. In this case, the interrupt is 
triggered twice, first by hardware, than again by the if-clause. This 
should not happen.
I have no Idea, why the pending-bit is not set, when I use the first 
example. The only way I found, was to disable the intrerrupts either 
globally or in the NVIC, which I dislike both.
Has anybody a better idea or an explanation, why the first example 
doesn't work?
Thanks in advance
Gernot