This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Timer problem

Hi there!

I have some problems with CAPCOM timer. It was configured:

CPU clock - 40 MHz
prescaler - module clock / 8
Timer0 overflow (usec) - 100
Timer 0 reload register - 0xFE0C

On digital oscilloscope I can see ~9.615 kHz, not 10 kHz.

Can anyone explain this problem?

Some info:

_MCTC1 EQU 1
_RWDC1 EQU 0
_MTTC1 EQU 0

Parents Reply Children
  • Hi Chris!

    May be you right. But:

    It was done to prevent more than 2 comparations (mode 1 can do it) in one period of timer. I think it is reason of strange invert PWM signal. If you can - look at picture: rapidshare.com/.../sample.JPG.html

    My be someone know why it is happens and how to solve it?

  • Hi,

    1) I don't use ST devices only Infineon so maybe I can't help you very much.

    2) I can't download your picture since my time limit has expired for the free use.

    3) It appears to me you are using double compare mode and the 6 pins of P8 for your signals.

    4) CAPCOM2 doesn't have any shadow registers for the channels so you need to be very care full when updating the compare values.

    5) You have decided to update all the compare channels at the timer T7 interrupt and are trying to prevent any missing compare events by stopping T7. However you are not compensating for the time you shut down the timer nor are you really sure of the value of T7 when you stop it. So you still could have a problem here since you don't know what the real value is (most likely it is not zero due to interrupt latency and software execution time).

    6) My suggestion would to have a combination of interrupts, T7 and on the channel compares and dynamically choose when to update the new value as to prevent any glitches. So when the channel is not changing state near the T7 overflow use this interrupt to calculate the next compare value for these channels. If the changing state is near the T7 overflow then you need to update the compare value for the channel at the channel compare event interrupt.

  • Hi again!

    1) ST and infineon are quite similar but there are some mismatches.

    2)You can look at picture at another site:

    www.bestsharing.com/.../sample.JPG.html

    I am still needed in any advises about situation. May be someone have solved similar problem.

    3) Yes, you are right

    4,5) Yep. It is really reason of my problem with timer. If I do not stop timer - I can see 10 kHz PWM on hardware, but it looks like as at picture - with PWM signal invertion at some places.

    6) Thanks. I'll try it. Sounds like it can help. But I don't understand why 12 first "=" operations of interrupt can't be executed in proper minimum time when the changing state is near the T7 overflow.
    Are they really so time-consuming?

    CC16 = CC16_image;
    F2303482 MOV CC16,DPP2:0x0234

    With next string I made 15 value gap at both edges of timer period for 12 MOV commands.

    temp1 = ((unsigned int) Tone.y1 + 0x8000) / 298 + 15;

  • Hi,

    Where is the program execution from (internal or external)? In your first post you tell me that MCTC1 = 1 which means one wait state but is this where your program is executing from (CS1)?

    Given you are running at 40MHz this means you have a possible instruction cycle of 50nsec (without adding a wait state or if you are running from the external bus which has a path of 16-bit verses 32-bit internal).

    So if you make a rough calculation for the response time to get to the T7 interrupt before you begin processing anything. The minimum interrupt response time is 5 states (250nsec). This requires program execution from the internal code memory, no external operand read requests and setting the interrupt request flag during the last state of an instruction cycle. When the interrupt request flag is set during the first state of an instruction cycle, the minimum interrupt response time under these conditions is 6 state times (300nsec). This is just for the interrupt instruction to be fetched now it needs to make it through the pipeline to know it has to jump again to your interrupt service routine. Then you need to account for the preample of the interrupt frame. Which may look something like…

        89: static void timer0 (void) interrupt T7INT
    0002006A ECEF      PUSH     MSW
    0002006C EC2E      PUSH     MAL
    0002006E EC2F      PUSH     MAH
    00020070 C6ED0000  SCXT     MRW,#0x0000
    00020074 EC84      PUSH     IDX0
    00020076 C6030300  SCXT     DPP3,#0x0003
    0002007A C6871000  SCXT     MDC,#0x0010
    0002007E EC06      PUSH     MDH
    00020080 EC07      PUSH     MDL
    00020082 ECF4      PUSH     R4
    00020084 ECF5      PUSH     R5
    00020086 ECF6      PUSH     R6
    00020088 ECF7      PUSH     R7
    0002008A ECF8      PUSH     R8
    0002008C ECF9      PUSH     R9
       100:   T78CON &= ~0x0040;
    0002008E 6690BFFF  AND      T78CON,#0xFFBF
       102:   CC16 = CC16_image;
    00020092 F2302082  MOV      CC16,DPP2:0x0220
       103:         CC19 = CC16_image;
    00020096 F2332082  MOV      CC19,DPP2:0x0220
       104:   CC24 = CC24_image;
    

    Also notice that you have 16-bit and 32-bit opcodes and it takes an extra bus access to get the whole instruction from external memory (hence the advantage of the internal program memory bus which is 32-bits wide).

    Ok how many cycles do you have before you turn off the clock to T7?

    My suggestions to you would be…

    1) You cannot turn off T7 because as you stated you are making wave shaped signals based on a PWM value.
    2) Figure out when to update either in the timer interrupt or on the channel interrupt.
    3) Change "CoSHR #14" as the simulator doesn't like this but should work in the actual device.
    4) At least minimize the ISR something like this...

     while (1) {
     /* service here instead of in the T7 interrupt or make this a high
      * priority task in your system to know it will run as soon as the
      * T7 interrupt has finished
      */
      if(updatePWM == 1) {
        Generate_Sine (&Tone);
        Generate_Sine (&Tone2);
        Generate_Sine (&Tone3);
    
        temp1  = ((unsigned int) Tone.y1  + 0x8000) / 298 + 15;
        temp12 = ((unsigned int) Tone2.y1 + 0x8000) / 298 + 15;
        temp13 = ((unsigned int) Tone3.y1 + 0x8000) / 298 + 15;
    
        CC16_image = 0xFE0C + temp1;
        CC24_image = 0xFFFF - temp1;
        CC17_image = 0xFE0C + temp12;
        CC25_image = 0xFFFF - temp12;
        CC18_image = 0xFE0C + temp13;
        CC26_image = 0xFFFF - temp13;
        updatePWM = 0;
       }
     };
    


    This code for T7 ISR is greatly reduced…

       102: static void timer0 (void) interrupt T7INT {
       103:   T78CON &= ~0x0040;
    000204F2 6690BFFF  AND      T78CON,#0xFFBF
       104:   CC16 = CC16_image;
    000204F6 F2301682  MOV      CC16,DPP2:0x0216
       105:         CC19 = CC16_image;
    000204FA F2331682  MOV      CC19,DPP2:0x0216
       106:   CC24 = CC24_image;
    000204FE F2381A82  MOV      CC24,DPP2:0x021A
       107:         CC27 = CC24_image;
    00020502 F23B1A82  MOV      CC27,DPP2:0x021A
       108:   CC17 = CC17_image;
    00020506 F2311282  MOV      CC17,DPP2:0x0212
       109:         CC20 = CC17_image;
    0002050A F2341282  MOV      CC20,DPP2:0x0212
       110:   CC25 = CC25_image;
    0002050E F2391882  MOV      CC25,DPP2:0x0218
       111:         CC28 = CC25_image;
    00020512 F23C1882  MOV      CC28,DPP2:0x0218
       112:   CC18 = CC18_image;
    00020516 F2321082  MOV      CC18,DPP2:0x0210
       113:         CC21 = CC18_image;
    0002051A F2351082  MOV      CC21,DPP2:0x0210
       114:   CC26 = CC26_image;
    0002051E F23A1482  MOV      CC26,DPP2:0x0214
       115:         CC29 = CC26_image;
    00020522 F23D1482  MOV      CC29,DPP2:0x0214
       116:   T78CON |= 0x0040;
    00020526 76904000  OR       T78CON,#0x0040
       117:         updatePWM = 1;
    0002052A 0F00      BSET     0xFD00.0
    0002052C FB88      RETI
    

  • Hi Chris!

    I've done as you said. It really works! Even without stopping CAPCOM timer!

    You are most usefull man in this forum, thanks a lot.