strange problem of coding style

I have a strange encounter, i use the C style in Arduino IDE without using void loop, my pwm result is correct. But, when I try to use in Arduino way, the pwm result is wrong. Example, I use PLL in C ctyle is working perfectly i get 20 Khz, when i use in Arduino Style program flow as below, the frequency i get is just 2k Hz. The code at my pwm have no typing errors as i have tried to copy the whole block from C style to Arduino style, is still doesn't work.
Also strange is i use a new chip, because i use PLL, i suppose to burn bootloader but i cant burn bootloader with USBasp. But i am surprise i didnt burn bootloader but i can get it work on the C style below, i just upload the program from Arduino IDE sketch, "upload with programmer".
So i thought the Arduino style not working is due to fuse setting issue, so i flash with the arvdudess with FUSE setting with PLL mode. but also not working.
So, the only way, it is working perfectly is a strange way. which using C style without burning bootloader. Can someone explain why the wrong way can get result and correct way cannot get result.
The chip i use is ATTiny861 with hardware programmer of USBasp. Code in Arduino IDE 1.8.2. Use Spence Konde ATTinyCore.
This is pseodo code in Arduino way which is not working.

void setup(){
pinMode(1,OUTPUT);
the rest of the pin setup....

init_pwm();
}

void init_pwm(){
code to start pwm, i also tested using int init_pwm instead of void init_pwm, still fail.
}

void loop(){
}

Below is code in C style, and is working without burning bootloader.

in C style without void loop is working perfectly.  
void init_avrpin(void){
DDRA =0xff;
PORTA =0x00;
}

int init_pwm(void){
code to start pwm 
}

int main(void){
init_avr();
init_pwm();
  while(1){
}
}

I guess the minimum for analysing is that you post the real code instead of

unkommented pseudo-code like

code to start pwm, i also tested using int init_pwm instead of void init_pwm, still fail.

best regards Stefan

If you use your own main() directly then you have to understand the consequences.
main() calls init() which configures the Arduino environment including configuring timers, the ADC etc.

The init_avr just settting the DDRA and PORT pins. No others thing inside.

The Arduino main() is here:

It calls init() in wiring.c

Edit

It does look like Dr Azzy has made some changes very recently to this core which may have fixed an attiny861 bug.

I feel strange and dont know what to do. I can get PLL working in Arduino IDE without burn bootloader. Then Arduino way of writing does not work. I think something is wrong and I hope Dr. Azzy can help clarify.

Please post the whole of your "C style" code that does not work

How are you uploading it to the Arduino and which Arduino board is it ?

OK. If you are preparing a bug report you must have small, but complete and compilable code samples which demonstrate the problem, as has been suggested above.

You could also state the current fuse settings of the device.

But upgrade everything to the latest version before submitting a report.

Also, change the title of your first post to something more meaningful like:

ATtiny861 PWM frequency Issue / SpenceKonde Core

so it gets the right attention.

Edit:

Crossed with @UKHeliBob

UKHeliBob:
Please post the whole of your "C style" code that does not work

How are you uploading it to the Arduino and which Arduino board is it ?

I am not using Arduino UNO board. I am using ISP from USBasp.

Rather than tell us which board you are not using, why not tell which board you are using?

/Enable PLL : Clock (16MHz PLL), Timer1 Clock : 64MHz
//Shall Burn bootloader before upload program
//using USBasp to upload program
//Fuse Setting shall be L: F1, H:D7, E: FF
//USBasp(ATtiny Core) , compile to binary and upload using USBAsp
//Spence Konde ATTinyCore 1.3.3
//ATTiny861

const byte pot = A0;

void setup()
{
  pinMode(6, OUTPUT);//PWM A (OC1B) POSITVE WAVEFORM
  pinMode(4, OUTPUT);//PWM B (OC1D) NEGATIVE WAVEFORM
  
  PRR = ((1<<PRADC)|(1<<PRUSI)|(0<<PRTIM0)|(0<<PRTIM1)); // Power reduction register; shut off the A/D converter, USI and Timer0.
  // init pwm-6, dual slope
  //set when up counting clear when downcounting
  // 10 bit

  PLLCSR =  0x02;      // PLL & enable PLL hexa to binary is b1000 0010
  delay(100);
    while (PLLCSR & (0x01) != 0x01); //wait for PLL to Lock(!(PLLCSR & 1<<PLOCK));
  PLLCSR = 0x06;         // PLL enable PCKE, hex to binary  b1000 0110

  
  //TCCR1A : COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B PWM1A PWM1B
  //        :  0     0       1      0      0      0    0     1
  TCCR1A = 0b10100001;  //21 enable PWM1A
                         // set PWM1A = 0, PWM1B = 1 to disable PWMA
                         //set PWM1A = 1, to get OC1A to generate PWM
   //A is full positive/negative, B is Positive, D is negative

  //TCCR1B : PWM1X PSR1 DTPS11 DTPS10 CS13 CS12 CS11 CS10
   TCCR1B |= (0<<PWM1X)| (1 << CS12) | (0 << CS11) | (0 << CS10);  // prescaler of 8
  
  // f(PWM)=f(PCK)/2(OCR1C+1).  f(PCK)=f(PLL)/prescaler. f(PLL)=64MHz
  //freq = 64M/2*8*175 = 22K  
  
  //TCCR1C : COM1A1S COM1A0S COM1B1S COM1B0S COM1D1 COM1D0 FOC1D PWM1D
  //        :  0       0         1     0       1       0    0       1 
  TCCR1C = 0b10101001;  // enable PWM1D
  
  //TCCR1D : FPIE1 FPEN1 FPNC1 FPES1 FPAC1 FPF1 WGM11 WGM10
  //TCCR1D = 0b00000000;
  TCCR1D = 0b00000001;//01 : Phase Correct PWM mode, also get 20K and duty cycle is working
    
  //TCCR1E
  // - - OC1OE5(PB5) OC1OE4(PB4) OC1OE3(PB3) OC1OE2(PB2) OC1OE1(PB1) OC1OE0(PB0)
  TCCR1E = 0b00101010;
  
  TCNT1 = 0x000;
  
  OCR1A = 0;
  
  OCR1B = 100;
  OCR1D = 100;
  OCR1C = 175;      
}

void loop( ) 
 {  
  
 }

This is the complete code which is not producing 22kHz. Only 2k Hz. If i use the same code in writing using the main style. I get 22kHz. Same hardware. I did not use Arduino board. I just use USBasp and the 6 pins of the ISP connect to the target MCU.

Hi,
WHICH CONTROLLER IC ARE YOU PROGRAMMING?
WHICH MCU ARE YOU PROGRAMMING?

By the looks of the comments in the "code" it is possibly an ATtiny, but which one?

Can you give us a part number?

What is PLL?

Tom... :slight_smile:

TomGeorge:
Hi,
WHICH CONTROLLER IC ARE YOU PROGRAMMING?
WHICH MCU ARE YOU PROGRAMMING?

By the looks of the comments in the "code" it is possibly an ATtiny, but which one?

Can you give us a part number?

What is PLL?

Tom... :slight_smile:

I have written on the code it is ATTiny861.

   TCCR1B |= (0<<PWM1X)| (1 << CS12) | (0 << CS11) | (0 << CS10);  // prescaler of 8

Change that line to use “=“ and set all the bits you need.
The arduino core will already have initialized tccr1b to something you don’t expect.

westfw:

   TCCR1B |= (0<<PWM1X)| (1 << CS12) | (0 << CS11) | (0 << CS10);  // prescaler of 8

Change that line to use “=“ and set all the bits you need.
The arduino core will already have initialized tccr1b to something you don’t expect.

This work. That was something strange as if i use the main (), the | is working. I cannot understand tis deep.
Also why i do not required to burn bootloader for this shall be run in PLL. It is also already setup in the core that as long as I use PLL, the fuse is set correctly ?

why i do not required to burn bootloader for this

Because you are using a programmer

UKHeliBob:
Because you are using a programmer

Oh..Only using Arduino UNO board need to burn bootloader.
Then how the Arduino IDE know which fuse I want to set ?

hamisu-anguan:
Oh..Only using Arduino UNO board need to burn bootloader.
Then how the Arduino IDE know which fuse I want to set ?

From here: ATTinyCore/boards.txt at master · SpenceKonde/ATTinyCore · GitHub

when you select the target board type i.e. your ATtiny861

Edit

Specifically here:

attinyx61.menu.clock.16pll=16 MHz (PLL)
attinyx61.menu.clock.16pll.bootloader.low_fuses=0xF1

That was something strange as if i use the main (), the | is working. I cannot understand tis deep.

When you use main(), nothing has touched any of the AVR peripherals before your code, and the TCCR1B is in its default post-reset state. This happens to be all zeros. so your statement:

 TCCR1B |= (0<<PWM1X)| (1 << CS12) | (0 << CS11) | (0 << CS10);

bitwise-ORs in the bits you have specified (1<<CS12 - note that a bitwise OR with a zero bit does nothing), and the final contents of the register is 1<<CS12. which sets the prescaler to 8, which is what you want.
When compiling with the Arduino IDE, there is still a main() function that runs before setup(), and it initializes some of the AVR peripherals as appropriate for the Arduino environment. this includes setting up Timer1 for use by the analogWrite() PWM routines. It sets the prescaler to 64 by setting

    // set timer 1 prescale factor to 64
    sbi(TCCR1B, CS11);
    sbi(TCCR1B, CS10);

Those bits are STILL set to one when you get to your code and CS12 is set, leaving TCCR1B containing
(CS10 | CS11 | CS12), which is NOT what you want.

You could have also done:

   TCCR1B = 0;  // reset to default state
   TCCR1B |= (0<<PWM1X)| (1 << CS12) | (0 << CS11) | (0 << CS10);  // prescaler of 8

Thank you westfw for this details.

I tried using TTCR1B =0; to reset to default, but it still not working. Then I try using
TCCR1B = 0b00000100 is also not working. I still get divive by 64.

Is there a proper way to override Arduino core setting of this division ? Shall i change the Arduino core wiring.c ?