ATTINY414 - Routing PWM outputs from timer TCA to ports

Go To Last Post
31 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I understand how the timer works and have that programmed, but I'm struggling on how to route the compare channel outputs to the Ports.  There's a table that indicates WO0 comes out of PB0 and WO1 comes out of PB1 so I have wired my circuit that way, but I can't seem to get anything to appear on the pins.  The datasheet says CTRLC bit one routes TCA00 to the port but then later on its says this is just to select the alternate pin so I assume this isn't what I want (and it doesn't work) ?  

 

Any help most appreciated.  A piece of sample code for a PWM on Port B0 or B1 even more so :-)

Last Edited: Sun. Feb 24, 2019 - 05:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

MikeDB1 wrote:
but I can't seem to get anything to appear on the pins.

The crystal ball is dusty -- what code have you tried?  Do you know that it is running otherwise?  How are you testing?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been wanting to write some tutorials on AVR 0/1 for a while, you are in luck because the first is on timer A and should be helpful to you: https://www.avrfreaks.net/forum/...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks.  The only thing I can see obviously different to what I was doing is that you set the output direction after setting the timer.  I'll play with this tomorrow to see if this has any affect, or whether I missed something in my code.

 

Thanks again

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This could also help:

 

http://ww1.microchip.com/downloa...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Indeed it does - thanks for pointing it out.  I did Google for ages trying to find the information as to why my code wouldn't work, although they seem to set the port direction first so obviously that wasn't the problem.   Hopefully I'll get my project working today.

 

Thanks again

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mike,

 

Welcome. Check this thread, I tried to put all the documents together for different modules of Attiny 1 & 0 series:

 

https://www.avrfreaks.net/forum/...

 

Its from Micrchip and it provides a way if "getting started".

 

Regards,

Moe

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks - interesting that unless you type "getting started" in the google search so that it hits that first, any reference to ATTINY and ADC is overwhelmed by ATTINY85 posts.  Would really have been better if they had given the 0 and 1 series a different series name.  They are great little processors but documentation is both inaccurate and not easy to find.  And they aren't even that new anymore. 

 

However when even RS is selling them for 39p each, they are a true bargain.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would like to point out about the documentation issue, so if you are using attiny212/attiny412, the documentation of the smallest chips are just a copy paste from the upper right side. So take care when designing your custom PCB as even the multiplexing table is wrong.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm actually using the 404 and yes the documentation for that one is a failed copy/paste/delete from higher up the chain.  So far I've worked around the errors but I suspect the PCB may end up with a respin.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have already reported this issue since Oct 2018 about these errors in documentation to Microchip. yet I still see they havent changed a coma in it...

 

The MC support seems like doesnt really care about this issue, I dont know why ?!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And this morning's error

 

In TCB : "The peripheral has it's own prescaler".  No it doesn't, it shares one with TCA but as far as I can see, going into sleep mode shuts this down and as it bypasses the processor prescaler the longest time you can sleep for using TCB is about 2 seconds.  Brilliant !

 

Anybody with a way round this please let me know.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I dunno how to explain it, but MAYBE a work-around is that you use the ULP32 for RTC, put everything in sleep as much as you want and then activate it using periodic interrupt, in this case you only wake up the TCB using PIT....ignoring the prescaler of the TCB.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ofcurse drifting in timing may occur, so high accurate timing may not be achieved using this method. this may work for only power saving issues if that is  your concern.

 

 

EDIT:

check this application note:

http://ww1.microchip.com/downloa...

 

you can use the same concept...

 

 

Regards,

Moe

Last Edited: Mon. Feb 25, 2019 - 12:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hehe - that's exactly what I'm doing as plan B.  I've just noticed there is a 32kHz divided by 64 mentioned in the text so maybe able to get up to 1 minute wakeups

Last Edited: Mon. Feb 25, 2019 - 12:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes doesn't need to be accurate - just needs to go to sleep to maintain battery life until dawn when a solar panel will rechange it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MikeDB1 wrote:
the longest time you can sleep for using TCB is about 2 seconds.  Brilliant !

 

You mean, that since we can't clock TCB from TCA, because it's disabled in sleep mode, we need to use CLK_PER?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes.  You can set that to 32kHz but the processor prescaler is after the tap to TCB so you can't divide it down further.   Trying to use the RTC instead so maybe not the disaster it seemed 5 minutes ago.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hold on, there is something I need to mention, so during sleep time you are using ULP32 with whatever prescaler you have, BUT once you wake up I suggest that you shift the CLK to the main CLK. otherwise your power saving idea maybe senseless

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

its just like driving a car with the first gear for long time...then you are using much energy and oil, but shifting to higher scale reduces gas consumption and more faster but for shorter time...not quite relevant, but you do get the idea, eh ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Yes that's line 1 of the interrupt routine :-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MikeDB1 wrote:

Yes that's line 1 of the interrupt routine :-)

 

yep, you are on the right track....other members here may also come up with other ideas if they have ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just to keep you updated, RTC isn't really a one-shot solution so gone back to TCB and hit some a new problem

 

"There are three steps in the configuration process:
1. Disable the CLK_PER prescaler - The following code snippet will demonstrate how to disable the CLK_PER prescaler:
CPU_CCP = CCP_IOREG_gc;
CLKCTRL.MCLKCTRLB = 0 << CLKCTRL_PEN_bp;"
 

At which point the processor goes gets a burst of 16MHz which is too much for the low voltage VCC I am using and exhibits shall we say anomalous behaviour. 

 

Going to 32kHz first in the hope that fixes this problem but do they even test these things ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry , I could not understand you, maybe a basic code of what you do might help here ?

- First you are writing to clock register...CCP part is clear.

- then you said the processor gets burst of 16MHz, what are you setting code for shifting between MAINCLK and ULP32 CLK ?

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Code below.  The app note writes to MCLKCTRLB first which means my processor running at 2.8v gets a burst of 16MHz and seems to lose itself.  Swapped them round now.

ISR routine similarly swapped around.  On waking up the processor returns from power_down() and carries on working, usually coming straight back after doing a quick ADC and finding the main battery voltage is still too low.

 

Not sure why you even have to disable CLK_PER in MCLKCTRLB but seems to be the case.

 

 

void power_down()

{

            CPU_CCP = CCP_IOREG_gc;                                // Enable writing to protected register
            CLKCTRL.MCLKCTRLA = CLKCTRL_CLKSEL_OSCULP32K_gc;    // Select 32KHz Internal Ultra Low Power Oscillator (OSCULP32K)
            
            CPU_CCP = CCP_IOREG_gc;                                // Enable writing to protected register
            CLKCTRL.MCLKCTRLB = 0 << CLKCTRL_PEN_bp;            //     Disable CLK_PER Prescaler
            
            while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm) {}        // Wait for system oscillator changing to finish
                
            SLPCTRL.CTRLA = SLPCTRL_SMODE_gm | SLPCTRL_SMODE_STDBY_gc; // Enable sleep mode and select Standby mode            
            
            TCB0.CCMP = 32000;                                    // Load the Compare or Capture register with the timeout value
            TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm | TCB_RUNSTDBY_bm; // Enable TCB and set CLK_PER divider to 1 (No Prescaling)
            TCB0.CTRLB = TCB_CNTMODE_TIMEOUT_gc;                // Configure TCB in Periodic Timeout mode
            TCB0.INTCTRL = TCB_CAPT_bm;                            // Enable Capture or Timeout interrupt
            
            sei();
            sleep_mode();

}

 

 

ISR(TCB0_INT_vect)
    {
        TCB0.INTFLAGS = TCB_CAPT_bm;                            // Clear the interrupt flag
        
        TCB0.INTCTRL = 0;                                        // Disable Timeout interrupt

 

        CPU_CCP = CCP_IOREG_gc;                                    // Enable writing to protected register
        CLKCTRL_MCLKCTRLB    = 0b00000001;                        // /2 giving 8MHz                    

 

        CPU_CCP = CCP_IOREG_gc;                                    // Enable writing to protected register
        CLKCTRL.MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc;            // Select main 16MHz oscillator
        
        while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm) {;}        // Wait for system oscillator changing to finish            
    }

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In tests I did previously, I found that the prescaler can be used, at least with OSC20M. But you must set the RUNSTDBY bit in the clock controller OSC20MCTRLA register, or the oscillator will be powered down.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

check the Errata:

http://ww1.microchip.com/downloa...

 

I think ur case might fall to one of these mentioned above

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes it can - but TCB is only 16 bits and would generate an interrupt about few millisecond at the slowest rate it could manage.  I'm thinking it's a bit of a red herring anyway.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also check the fuse setting, maybe you are activating the 16MHZ CLK. I read one time in one of these attiny 1 series that you can set the 16MHZ CLK...only manually via fuse setting, dont know if this is relevant here but anyway

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Indeed it looks like Errata 33.1.2.6 TCB is my problem.  Thanks for pointing it out. 

 

Alsor 33.1.2.4 RTC explains why I was getting nowhere there so I'll go back to that one and try re-arranging the order I write things in and see if they start working.

 

Thanks again 

 

Mike 'banging head against desk'

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are welcome and good luck