EmbDev.net

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


Du wurdest von Mikrocontroller.net auf diese Seite weitergeleitet. Zurück zu Mikrocontroller.net
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.