Forum Index
HomeZBasic Home   Forum RulesForum Rules   Forum FAQForum FAQ   MemberlistMemberlist   UsergroupsUsergroups   RSS FeedRSS Feed
Site SearchSite Search   LinksLinks   DownloadDownload   Digests and SubscriptionsDigests and Subscriptions
ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in   RegisterRegister
multiple PWM capture
Goto page Previous  1, 2, 3, 4
 
Post new topic   Reply to topic    Forum Index -> ZX-1281
Author Message
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR

Posted: 06 January 2009, 0:09 AM    Post subject: Reply with quote

sturgessb wrote:
ah figured it, needed to be Register.PCMSK2
You are right. I overlooked that detail.
Code:
Sub Main()
  If Semaphore(Register.Timer1Busy) Then
    Register.TCCR1A = 0
    Register.TCCR1B = &H02
    Register.TCCR1C = 0
  End If
  Register.PCIFR = &Hff
  Register.PCMSK2 = Bx0000_0001  ' bit zero only
  Register.PCICR = Bx0000_0100  ' PCINT2, PortC
End Sub
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 06 January 2009, 0:11 AM    Post subject: Reply with quote

dkinzer wrote:
Interrupts are not used to implement I2C master mode but an interrupt is required to implement I2C slave mode.


So seeing as i want to set this up as an I2C slave, which interrupt do i need to not use, is it an external interrupt or one of the ports?

Cheers
Ben
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR

Posted: 06 January 2009, 0:17 AM    Post subject: Reply with quote

sturgessb wrote:
So seeing as i want to set this up as an I2C slave, which interrupt do i need to not use, is it an external interrupt or one of the ports?
The I2C interrupt is internally generated and not related to any specific I/O pin. The fact that you want to eventually implement I2C slave code will have no impact on pin choice except, of course, that you need to keep the SDA and SCL pins available.
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 06 January 2009, 16:20 PM    Post subject: Reply with quote

Don, is this the right setup for 8 bit timer 0 on 24n, with overflow interrupt

Code:
Register.TIMSK0 = &H01 'is this right?
Register.TCCR0A = 0
Register.TCCR0B = &H03

ISR TIMER0_OVF()
   tempint = tempint + 1
END ISR


Cheers

ben
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR

Posted: 06 January 2009, 17:09 PM    Post subject: Reply with quote

sturgessb wrote:
is this the right setup for 8 bit timer 0 on 24n, with overflow interrupt
Yes but you can't use Timer0 because it is used for the RTC. You'll note that Register.Timer0Busy will always be true on a ZX-24 indicating that it is in use already.

The other 8-bit timer is Timer2 which you can use if you don't use any of the software UART channels (3-6).
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 11 January 2009, 17:59 PM    Post subject: Reply with quote

Hey guys, Can anyone see a way of optimising this any more? Im getting a few random values and not the value stability I was looking for.

So I think I need to get the runtime of the ISR down a bit more more. Could using Naked mode help? Can i get rid of those shr() functions, so everything is inline? any other ideas welcome!

As you can see im using an 8 bit timer, and using overflow to count the highbyte, so im getting a 16 bit timer value. I need to do this as TIMER1 is need for outputcapture. If I use the 16 bit timer for this, I dont get the large random jumps that i get with the 8bit version but the value jitter is still the same.

PWM input is on pins 7-10 on zx24n

Code:


'DECLARATIONS
   PUBLIC timer2Data(1 to 2) as Byte
   PUBLIC timer2Value As UnsignedInteger Alias timer2Data

   'PWM vars for 2 ports
   PUBLIC PC_i as Byte
   PUBLIC PC_TimerVal as UnsignedInteger
   PUBLIC PC_B1 as byte
   PUBLIC PC_B0 as byte
   PUBLIC PC_BitsChanged as byte
   PUBLIC PC_StartTime(0 to 7) as UnsignedInteger
   PUBLIC PC_Width(0 to 7) as UnsignedInteger

   'OUT
   Const Chan6_Pin as Byte = 6
   
Sub Main()
   Call PutPin(Chan6_Pin,zxOutputLow)
   
   'PC INTERUPTS
   Register.PCIFR = &Hff
   Register.PCICR = Bx0000_0100 ' PCINT2, PortC, PORT A
   Register.PCMSK2 = Bx0011_1100 'PORT C
   Register.PCMSK0 = Bx0000_1111 'PORT A
   
   'TIMER 2 8bit
   If Semaphore(Register.Timer2Busy) Then
      Register.TCCR2B = &H02
      Register.TIMSK2 = Bx0000_0001
   End If
   
   'MAIN LOOP
   Do
      Debug.Print PC_width(0) &", "& PC_width(1) &", "& PC_width(2) &", "& PC_width(3)
      Call sleep(0.10)
   Loop
End Sub


'**************************************************************************
ISR Timer2_OVF()
   timer2Data(2) = timer2Data(2) + 1
END ISR

ISR PCINT2()
      PC_B1 = Register.PinC
      Timer2Data(1) = Register.TCNT2
      PC_TimerVal = timer2Value
   PC_BitsChanged = PC_B1 XOR PC_B0
   PC_B0 = PC_B1
   for PC_i = 0 to 3
      'find a changed bit
      if shr(PC_BitsChanged,2) = 1 then
         if shr(PC_B1,2) = 1 then   'if changed pin high 'starts with pin 10 not 12
            PC_StartTime(PC_i) = PC_TimerVal
         else   'pin low
            PC_Width(PC_i) = (PC_TimerVal - PC_StartTime(PC_i))
         end if
      end if
      PC_BitsChanged = shr(PC_BitsChanged, 1)
      PC_B1 = shr(PC_B1, 1)
   next
END ISR



Cheers

Ben
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR

Posted: 12 January 2009, 4:21 AM    Post subject: Reply with quote

sturgessb wrote:
So I think I need to get the runtime of the ISR down a bit more more. Could using Naked mode help? Can i get rid of those shr() functions, so everything is inline?
I'm not convinced that the execution time of the ISR is causing the occasional unexpected data values. I would be more inclined to suspect interference from other ISRs; in this case the RTC. If you have access to a logic analyzer, you can add instructions to the ISR to facilitate measuring its execution time. That should suggest which hypothesis to pursue. You can probably also set up the logic analyzer to show you if/when the pin change ISR is not being executed timely, a circumstance that could lead to unexpected data values.

As for the Naked attribute, you can't just add the attribute to the ISR and expect the code to run properly. With that attribute in effect, the compiler omits the generation of some very essential instructions; it becomes your responsibility to include in the ISR all of the essential assembly language instructions to prevent the ISR code from corrupting registers that other code is expecting to remain unchanged. Consequently, use of the Naked attribute is recommended only for those who a) are skilled assembly language programmers, b) completely understand AVR assembly language, and c) understand the register assumptions relied on by the avr-gcc compiler.

As for the shr calls, while it is true that I recommended avoiding System Library calls in your ISR, it turns out that not all System Library invocations result in calls to procedures external to the ISR. I've reproduced below the C code generated by the ZBasic compiler for the ISR that you posted. Comparison of this code with the original ZBasic code reveals that the shr function is realized by using the C operator >>. In fact, there are no obvious function calls anywhere in the generated C code. Further, I claim that the assembly language instructions ultimately produced for the ISR contain no call instructions at all. This can be verified by examining the .lss file (see the discussion in another post on how to do so).

Code:
ISR(PCINT2_vect)
{
  zv_PC_B1 = PINC;
  zv_timer2Data[1 - 1] = TCNT2;
  zv_PC_TimerVal = *zv_timer2Value;
  zv_PC_BitsChanged = zv_PC_B1 ^ zv_PC_B0;
  zv_PC_B0 = zv_PC_B1;
  {
    uint8_t _zv_forEndTemp01 = 3;
    for (zv_PC_i = 0; zv_PC_i <= _zv_forEndTemp01; zv_PC_i++)
    {
      if ((zv_PC_BitsChanged >> 2) == 1)
      {
        if ((zv_PC_B1 >> 2) == 1)
        {
          zv_PC_StartTime[zv_PC_i] = zv_PC_TimerVal;
        }
        else
        {
          zv_PC_Width[zv_PC_i] = zv_PC_TimerVal - zv_PC_StartTime[zv_PC_i];
        }
      }
      zv_PC_BitsChanged = zv_PC_BitsChanged >> 1;
      zv_PC_B1 = zv_PC_B1 >> 1;
    }
  }
}
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 01 August 2010, 23:44 PM    Post subject: Reply with quote

hmmm, I wonder if the new xmega devices could be the answer for this problem!?

Ben
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 02 August 2010, 7:08 AM    Post subject: Reply with quote

With the ZX-128a1, would it be possible to input capture 6 pwm channels and output 4 hardware pwm channels?

If not what would be maximum possible be.

Cheers

Ben
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 689

Posted: 02 August 2010, 13:32 PM    Post subject: Reply with quote

sturgessb wrote:
With the ZX-128a1, would it be possible to input capture 6 pwm channels and output 4 hardware pwm channels?

If not what would be maximum possible be.

Cheers

Ben


The XMega 128A4 family has five 16-bit timers. So, I think you can do input capture on 5 channels simultaneously. I have not verified that all 5 pins are independent of each other on the chip.

In my quick inspection of the atmel document, it indicates that there are 4 input capture channels on 3 of the timers, and I did not investigate what they mean by that. AFAIK, one timer will allow one input capture at a time.

-Tony
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR

Posted: 02 August 2010, 15:45 PM    Post subject: Reply with quote

sturgessb wrote:
With the ZX-128a1, would it be possible to input capture 6 pwm channels and output 4 hardware pwm channels?
The xmega128a1 has eight 16-bit timers. One of these is used for the RTC leaving 7 for other purposes. The timers are of two types, Type 0 and Type 1, the difference being the number of compare match registers. The Type 0 timers have four compare match registers (thus supporting 4 PWM outputs with a common base frequency) while the Type 1 timers have only two. Each port C through F has one timer of each type, named TCx0 and TCx1, where x is {C, D, E. F}.

The RTC uses TCC1, leaving TCC0, TCD0, TCE0, TCF0 and TCD1, TCE1 TCF1 for other purposes. With careful selection of input capture and PWM channels, you should be able to have six concurrent input capture processes and then use a remaining Type 0 timer for the four PWM channels as long as it is workable to have the same base frequency for the PWM channels.

In contrast to the mega devices, the compare match registers on the xmega can be used for either input or output purposes. Theoretically, then, you could have four input captures running on a single Type 0 timer. The InputCaptureEx() routine, however, does not exploit this capability, being limited to one input capture per timer. If you wanted to perform multiple input captures using a single timer you'd have to write your own ISRs for managing the multiple capture interrupts and the single overflow interrupt.
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 689

Posted: 02 August 2010, 15:54 PM    Post subject: Reply with quote

dkinzer wrote:
The xmega128a1 has eight 16-bit timers....


oops, sorry for my bad info about the XMega128A4. I looked at the wrong CPU datasheet!

-Tony
Back to top
sturgessb



Joined: 25 Apr 2008
Posts: 246
Location: Norwich, UK

Posted: 02 August 2010, 20:08 PM    Post subject: Reply with quote

Thanks guys.

4 input captures on one timer sure sounds interesting. This would means I could get away with a smaller ic with less timers. Although I don't think the 32a4 would be up to it.

Ben
Back to top
Display posts from previous:   
Post new topic   Reply to topic    Forum Index -> ZX-1281 Time synchro. with the server - Timezone/DST with your computer
Goto page Previous  1, 2, 3, 4
Page 4 of 4

 


All content Copyright © 2005-2012 Elba Corp. All Rights Reserved.
Opinions expressed in posts are those of the author and not necessarily those of Elba Corp.
Powered by phpBB © 2001, 2005 phpBB Group