EmbDev.net

Forum: µC & Digital Electronics STM32F1xx EXTI problem to trigger interrupt by SWIER


von Gernot (Guest)


Rate this post
useful
not useful
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

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.