Skip to content

GIGA: analogWrite(5, 0); faults the processor - Analog APIS are not complete #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
KurtE opened this issue Dec 18, 2024 · 7 comments
Closed

Comments

@KurtE
Copy link

KurtE commented Dec 18, 2024

Describe the bug
analogWrite(5, 0);

Faults on the GIGA...

Output of Serial Monitor

  1. If you have an USB-to-Serial adapter, paste the complete output of the console crash, starting from
uart:~$ sketch
[00:00:11.044,000] <inf> usb_cdc_acm: Device suspended
[00:00:11.269,000] <inf> usb_cdc_acm: Device configured
[00:00:22.948,000] <err> os: ***** BUS FAULT *****
[00:00:22.953,000] <err> os:   Precise data bus error
[00:00:22.959,000] <err> os:   BFAR Address: 0x5f657378
[00:00:22.965,000] <err> os: r0/a1:  0x5f65736c  r1/a2:  0x00000000  r2/a3:  0x2400eee0
[00:00:22.973,000] <err> os: r3/a4:  0x08058a1f r12/ip:  0x00000000 r14/lr:  0x2400e7d7
[00:00:22.982,000] <err> os:  xpsr:  0xa1000000
[00:00:22.987,000] <err> os: s[ 0]:  0x2400f094  s[ 1]:  0x080510ad  s[ 2]:  0x00000000  s[ 3]:  0x0804ef99
[00:00:22.998,000] <err> os: s[ 4]:  0x00000000  s[ 5]:  0x24000568  s[ 6]:  0x000002d8  s[ 7]:  0x0804f057
[00:00:23.008,000] <err> os: s[ 8]:  0x00000000  s[ 9]:  0x00000000  s[10]:  0x2400ec95  s[11]:  0x00000001
[00:00:23.018,000] <err> os: s[12]:  0x2400e75d  s[13]:  0x2400e771  s[14]:  0xfffffffe  s[15]:  0x2400d510
[00:00:23.029,000] <err> os: fpscr:  0x0805b614
[00:00:23.034,000] <err> os: Faulting instruction address (r15/pc): 0x08058a20
[00:00:23.042,000] <err> os: >>> ZEPHYR FATAL ERROR 25: Unknown error on CPU 0
[00:00:23.050,000] <err> os: Current thread: 0x240008b0 (shell_uart)

Optional: attach the sketch

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial) {}

  Serial.println("Start of PWM test");
  delay(10000);

}


void loop() {
  // put your main code here, to run repeatedly:
  for (int i = 0; i < 256; i++) {
    analogWrite(5, i);
    delay(20);
  }

  for (int i = 255; i <= 0; i--) {
    analogWrite(5, i);
    delay(20);
  }
  delay(50);
}

Additional context
Add any other context about the problem here.
Instrumented the code:

void analogWrite(pin_size_t pinNumber, int value)
{
  Serial.print("AnalogWrite called: "); Serial.print(pinNumber);
  Serial.print(" "); Serial.print(value);
  delay(5);
  size_t idx = pwm_pin_index(pinNumber);
  Serial.print(" idx: "); Serial.println(idx); 
  delay(5);
  if (!pwm_is_ready_dt(&arduino_pwm[idx])) {
    return;
  }
  Serial.print("After is ready "); Serial.flush();

  if (idx >= ARRAY_SIZE(arduino_pwm) ) {
    return;
  }

  Serial.print(" ");Serial.print(arduino_pwm[idx].period); Serial.flush();

  if (((uint32_t)value) > arduino_pwm[idx].period) {
    value = arduino_pwm[idx].period;
  } else if (value < 0) {
    value = 0;
  }

  /*
   * A duty ratio determines by the period value defined in dts
   * and the value arguments. So usually the period value sets as 255.
   */
  Serial.println("before Call pwm_set_pulse_dt"); Serial.flush();
  (void)pwm_set_pulse_dt(&arduino_pwm[idx], value);
  Serial.println("After Call pwm_set_pulse_dt"); Serial.flush();
}

Debug output:

Start of PWM test
AnalogWrite called: 5 0 idx: 4294967295

So the line: size_t idx = pwm_pin_index(pinNumber);
returns: 0xffffffff which is obviously > idx >= ARRAY_SIZE(arduino_pwm)

which is checked, unfortunately after the code:
if (!pwm_is_ready_dt(&arduino_pwm[idx])) {
which faulted.
Will swap some code next. But wonder why 5 is not returning a valid index...

@KurtE
Copy link
Author

KurtE commented Dec 18, 2024

Updated the code so does not fault:
Also printed out PWM table

  for(size_t i=0; i<ARRAY_SIZE(arduino_pwm_pins); i++) {
    Serial.print(arduino_pwm_pins[i]);
    Serial.print(" ");
  }

57 0 83 11 6 80 81 3 4

Now to figure out what those pins are ...

I see them defined as:

		pwm-pin-gpios =	    <&gpioj 9 0>,
					<&arduino_header 6 0>,
				    <&arduino_header 5 0>,
				    <&arduino_header 17 0>,
				    <&arduino_header 12 0>,
				    <&arduino_header 2 0>,
				    <&arduino_header 3 0>,
				    <&arduino_header 9 0>,
				    <&arduino_header 10 0>;

But I think <&arduino_header 5 0>, is not pin not D5
But instead A5: from the arduino_r3_connector.dtsi file.
< 5 0 &gpioc 2 0>, /* A5 */
But the numbers maybe still don't make sense... At least to me.
Second edit:
J9->57,
ArduinoHeader 6->D0, or 0
AH5->A5->? Would think 81 by schematic but83? which is A7?
AH17 -> D11
So makes sense.
Guessing table wrong - forgot the first 6 are the analog...

@mjs513
Copy link

mjs513 commented Dec 19, 2024

AH5->A5->? Would think 81 by schematic but83? which is A7?

Yep found that in #7 as well where"

D76-D83 (A0 to A7) ring out to D78-D85 (off by 2)

just noticed though that @facchinm has some comits to fix the pin numbering - see bottom of issue

f69182e

And yeah don't understand the pin table either.

PS sorry been missing all the fun been sick as a dog.

@mjs513
Copy link

mjs513 commented Dec 19, 2024

@KurtE - @facchinm

looking at the BLE Sense overlay it looks like the PWM pins are fully defined but not seeing that in giga overlay or am I missing somethings?

@KurtE KurtE changed the title GIGA: analogWrite(5, 0); faults the processor GIGA: analogWrite(5, 0); faults the processor - Analog APIS are not complete Dec 30, 2024
@KurtE
Copy link
Author

KurtE commented Dec 30, 2024

Edited title as I don't believe that these APIs are complete:

That is, on Arduino analogWrite(pin, value), the value is I believe defined as the range of 0-resolution or fir 8 bits 255.

The current code: simply calls:
(void)pwm_set_pulse_dt(&arduino_pwm[idx], value);

with the value passed in, it compares the value to be between 0 and the period, and the
With the one defined in the current overlay, I believe the period is: pwms = <&cam_clock_pwm 3 PWM_HZ(6000000)
The translation into the devicetree_generated.h:
#define DT_N_S_soc_S_timers_40010000_S_pwm_S_pwmclock_P_pwms_IDX_0_VAL_period 166

So the period is the time in us. So we should map the value something like:
value = map(value, 0, 255, 0, arduino_pwm[idx].period;

analogWriteResolution is not defined or implemented, to allow to change resolution typically between 8 and 12 bits
default of 8...

What about the DAC pins (A12 and A13)

Having difficulties trying to figure out the .dts/.overlay files on how to specify PWM pins.
Things like how to define: TIM1_CH1 versus TIM1_CH1N

Also trying to figure out the multiple sections associated with the camera PWM pin. More on this later...

@KurtE
Copy link
Author

KurtE commented Dec 31, 2024

Quick update: I am having a little luck with PWM. I have Pin 10 limping along, maybe 12 as well have not tried it..
Still very much WIP.

Sections in the overlay with PWM stuff:

// XCLK as PWM from PJ9
&timers1 {
	status = "okay";
	st,prescaler = <0>;

	cam_clock_pwm: pwm {
		status = "okay";
		pinctrl-0 = <&tim1_ch3_pj9>,
				<&tim1_ch1_pk1>,
				<&tim1_ch2_pj11>;
		pinctrl-names = "default";
	};

	cam_clock_pwm: pwm {
		status = "okay";
		pinctrl-0 = <&tim1_ch3_pj9>,
				<&tim1_ch1_pk1>,
				<&tim1_ch2_pj11>;
		pinctrl-names = "default";
	};
};

&cam_clock_pwm {
	/* ...then use the pwmclock node to start the clock generation */
	pwmclock: pwmclock {
		status = "okay";
		compatible = "pwm-clock";
		clock-frequency = <0>;
		#clock-cells = <1>;
		pwms = <&cam_clock_pwm 3 PWM_HZ(6000000) PWM_POLARITY_NORMAL>;
			/*	<&cam_clock_pwm 1 PWM_HZ(500) PWM_POLARITY_NORMAL>, */
			/*	<&cam_clock_pwm 2 PWM_HZ(500) PWM_POLARITY_NORMAL>; */
	};
};
...
		pwm-pin-gpios =	    <&gpioj 9 0>,		/* D57PJ9	TIM1_CH3 */
					<&arduino_header 16 0>,		/* D10 PK1  TIM1_CH1 */
					<&arduino_header 18 0>;		/* D12 PJ11 TIM1_CH2 */

...
		pwms = <&cam_clock_pwm 3 PWM_HZ(6000000) PWM_POLARITY_NORMAL>,
					<&cam_clock_pwm 1 PWM_HZ(20000) PWM_POLARITY_NORMAL>,
					<&cam_clock_pwm 2 PWM_HZ(20000) PWM_POLARITY_NORMAL>;

Analog write in zephyrcommon.cpp

void analogWrite(pin_size_t pinNumber, int value)
{
  Serial.print("analogWrite(");
  Serial.print(pinNumber);
  Serial.print(",");
  Serial.print(value);
  Serial.print(") ");
  size_t idx = pwm_pin_index(pinNumber);
  Serial.print(idx);

  /*
   * Make sure pwm_pin_index returned something
   * valid before we use it as an index
   */
  if (idx >= ARRAY_SIZE(arduino_pwm) ) {
    Serial.print(" > ");
    Serial.print(ARRAY_SIZE(arduino_pwm));
    Serial.println(" - Failed");
    return;
  }

  if (!pwm_is_ready_dt(&arduino_pwm[idx])) {
    Serial.println(" - Failed not ready");
    return;
  }

  if (((uint32_t)value) > arduino_pwm[idx].period) {
    value = arduino_pwm[idx].period;
  } else if (value < 0) {
    value = 0;
  } else {
    value = map(value, 0, 255, 0, arduino_pwm[idx].period - 1);
  }

  /*
   * A duty ratio determines by the period value defined in dts
   * and the value arguments. So usually the period value sets as 255.
   */
  Serial.print(" - Set pulse_dt: ");
  Serial.print(value);
  Serial.print(" ");
  Serial.println(arduino_pwm[idx].period);
  (void)pwm_set_pulse_dt(&arduino_pwm[idx], value);
}

Note currently Pin 10 is outputting at 20mhz pulses. I tried 500 and saw lots of errors about the period does not fit
in a Timer 16...

Test Sketch:

#define analog_pin 10
#define toggle_pin 3
void setup() {
    // put your setup code here, to run once:
    Serial.begin(115200);
    //while (!Serial) {}
    delay(500);

    Serial.println("Start of PWM test");
    pinMode(toggle_pin, OUTPUT);
    delay(1000);
}

void maybe_pause() {
    if (Serial.available()) {
        while (Serial.read() != -1) {}
        Serial.println("Paused");
        while (Serial.read() == -1) {}
        while (Serial.read() != -1) {}

        Serial.print("CR1: 0x"); Serial.println (TIM1->CR1, HEX);
        Serial.print("CR2: 0x"); Serial.println (TIM1->CR2, HEX);
        Serial.print("SMCR: 0x"); Serial.println (TIM1->SMCR, HEX);
        Serial.print("DIER: 0x"); Serial.println (TIM1->DIER, HEX);
        Serial.print("SR: 0x"); Serial.println (TIM1->SR, HEX);
        Serial.print("EGR: 0x"); Serial.println (TIM1->EGR, HEX);
        Serial.print("CCMR1: 0x"); Serial.println (TIM1->CCMR1, HEX);
        Serial.print("CCMR2: 0x"); Serial.println (TIM1->CCMR2, HEX);
        Serial.print("CCER: 0x"); Serial.println (TIM1->CCER, HEX);
        Serial.print("CNT: 0x"); Serial.println (TIM1->CNT, HEX);
        Serial.print("PSC: 0x"); Serial.println (TIM1->PSC, HEX);
        Serial.print("ARR: 0x"); Serial.println (TIM1->ARR, HEX);
        Serial.print("RCR: 0x"); Serial.println (TIM1->RCR, HEX);
        Serial.print("CCR1: 0x"); Serial.println (TIM1->CCR1, HEX);
        Serial.print("CCR2: 0x"); Serial.println (TIM1->CCR2, HEX);
        Serial.print("CCR3: 0x"); Serial.println (TIM1->CCR3, HEX);
        Serial.print("CCR4: 0x"); Serial.println (TIM1->CCR4, HEX);
        Serial.print("BDTR: 0x"); Serial.println (TIM1->BDTR, HEX);
        Serial.print("DCR: 0x"); Serial.println (TIM1->DCR, HEX);
        Serial.print("DMAR: 0x"); Serial.println (TIM1->DMAR, HEX);
        Serial.print("CCMR3: 0x"); Serial.println (TIM1->CCMR3, HEX);
        Serial.print("CCR5: 0x"); Serial.println (TIM1->CCR5, HEX);
        Serial.print("CCR6: 0x"); Serial.println (TIM1->CCR6, HEX);
        Serial.print("AF1: 0x"); Serial.println (TIM1->AF1, HEX);
        Serial.print("AF2: 0x"); Serial.println (TIM1->AF2, HEX);
        Serial.print("TISEL: 0x"); Serial.println (TIM1->TISEL, HEX);
    }
}

void loop() {
    // put your main code here, to run repeatedly:
    digitalWrite(toggle_pin, !digitalRead(toggle_pin));
    digitalWrite(toggle_pin, !digitalRead(toggle_pin));
    for (int i = 0; i < 256; i += 32) {
        analogWrite(analog_pin, i);
        digitalWrite(toggle_pin, !digitalRead(toggle_pin));
        maybe_pause();
        delay(100);
    }

    digitalWrite(toggle_pin, !digitalRead(toggle_pin));
    digitalWrite(toggle_pin, !digitalRead(toggle_pin));
    for (int i = 255; i >= 0; i -= 32) {
        analogWrite(analog_pin, i);
        digitalWrite(toggle_pin, !digitalRead(toggle_pin));
        maybe_pause();
        delay(100);
    }
    delay(50);
}

Output for registers on TIm1 for both MBED and Zypher

MBED Zephyr


CR1: 0x1 CR1: 0x81
CR2: 0x0 CR2: 0x0
SMCR: 0x0 SMCR: 0x0
DIER: 0x0 DIER: 0x0
SR: 0x3001F SR: 0x3001F
EGR: 0x0 EGR: 0x0
CCMR1: 0x68 CCMR1: 0x68
CCMR2: 0x0 CCMR2: 0x0
CCER: 0x1 CCER: 0x1
CNT: 0xFA CNT: 0x244F
PSC: 0xEF PSC: 0x0
ARR: 0x7CF ARR: 0x2EDF
RCR: 0x0 RCR: 0x0
CCR1: 0x5DA CCR1: 0x292C
CCR2: 0x0 CCR2: 0x0
CCR3: 0x0 CCR3: 0x0
CCR4: 0x0 CCR4: 0x0
BDTR: 0x8000 BDTR: 0x8000
DCR: 0x0 DCR: 0x0
DMAR: 0x1 DMAR: 0x81
CCMR3: 0x0 CCMR3: 0x0
CCR5: 0x0 CCR5: 0x0
CCR6: 0x0 CCR6: 0x0
AF1: 0x1 AF1: 0x1
AF2: 0x1 AF2: 0x1
TISEL: 0x0 TISEL: 0x0

More debugging tomorrow, then adding more pins on multiple timers



@KurtE
Copy link
Author

KurtE commented Jan 1, 2025

Quick update: using different sketch which allows me to enter pin and value, to see what happens.

/int  analog_pin = 10;
void setup() {
    // put your setup code here, to run once:
    Serial.begin(115200);
    while (!Serial && millis() < 4000) {}
    delay(500);

    Serial.println("Start of PWM test");
    Serial.println("Enter: <pin> value - to change ");
    Serial.println("   #N - to print out information about timer N");
    delay(1000);
}

void print_timer_info(int iTimer) {
    TIM_TypeDef *ptmr = nullptr;
    switch (iTimer) {
        case 1: ptmr = TIM1; break;
        case 3: ptmr = TIM3; break;
        case 4: ptmr = TIM4; break;
        case 15: ptmr = TIM15; break;
        default: return;
    };
    Serial.print("\nTimer: ");
    Serial.println(iTimer);
    Serial.print("\tCR1: 0x");
    Serial.println(ptmr->CR1, HEX);
    Serial.print("\tCR2: 0x");
    Serial.println(ptmr->CR2, HEX);
    Serial.print("\tSMCR: 0x");
    Serial.println(ptmr->SMCR, HEX);
    Serial.print("\tDIER: 0x");
    Serial.println(ptmr->DIER, HEX);
    Serial.print("\tSR: 0x");
    Serial.println(ptmr->SR, HEX);
    Serial.print("\tEGR: 0x");
    Serial.println(ptmr->EGR, HEX);
    Serial.print("\tCCMR1: 0x");
    Serial.println(ptmr->CCMR1, HEX);
    Serial.print("\tCCMR2: 0x");
    Serial.println(ptmr->CCMR2, HEX);
    Serial.print("\tCCER: 0x");
    Serial.println(ptmr->CCER, HEX);
    Serial.print("\tCNT: 0x");
    Serial.println(ptmr->CNT, HEX);
    Serial.print("\tPSC: 0x");
    Serial.println(ptmr->PSC, HEX);
    Serial.print("\tARR: 0x");
    Serial.println(ptmr->ARR, HEX);
    Serial.print("\tRCR: 0x");
    Serial.println(ptmr->RCR, HEX);
    Serial.print("\tCCR1: 0x");
    Serial.println(ptmr->CCR1, HEX);
    Serial.print("\tCCR2: 0x");
    Serial.println(ptmr->CCR2, HEX);
    Serial.print("\tCCR3: 0x");
    Serial.println(ptmr->CCR3, HEX);
    Serial.print("\tCCR4: 0x");
    Serial.println(ptmr->CCR4, HEX);
    Serial.print("\tBDTR: 0x");
    Serial.println(ptmr->BDTR, HEX);
    Serial.print("\tDCR: 0x");
    Serial.println(ptmr->DCR, HEX);
    Serial.print("\tDMAR: 0x");
    Serial.println(ptmr->DMAR, HEX);
    Serial.print("\tCCMR3: 0x");
    Serial.println(ptmr->CCMR3, HEX);
    Serial.print("\tCCR5: 0x");
    Serial.println(ptmr->CCR5, HEX);
    Serial.print("\tCCR6: 0x");
    Serial.println(ptmr->CCR6, HEX);
    Serial.print("\tAF1: 0x");
    Serial.println(ptmr->AF1, HEX);
    Serial.print("\tAF2: 0x");
    Serial.println(ptmr->AF2, HEX);
    Serial.print("\tTISEL: 0x");
    Serial.println(ptmr->TISEL, HEX);
}

int get_next_cmd_num(int &ich) {
  int num = -1;
  while (ich == ' ') ich = Serial.read();
  if (ich < ' ') return -1; //assume we are done...
  if ((ich >= '0') && (ich <'9')) {
    num = ich - '0';
    for(;;) {
      ich = Serial.read();
      if ((ich < '0') || (ich > '9')) break;
      num = num * 10 + ich - '0';
    }
  }
  return num;
}

void loop() {
  while (Serial.available() == 0) {}

  
  int ich = Serial.read();
  if (ich == '#') {
    ich = Serial.read();
    print_timer_info(get_next_cmd_num(ich));
  } else {
    int p1 = get_next_cmd_num(ich);
    int p2 = get_next_cmd_num(ich);
    
    if (p2 != -1) {
      analog_pin = p1;
      Serial.print("analogWrite(");
      Serial.print(analog_pin);
      Serial.print(",");
      Serial.print(p2);
      Serial.println(")");
      analogWrite(analog_pin, p2);
    } else if (p1 != -1) {
      Serial.print("analogWrite(");
      Serial.print(analog_pin);
      Serial.print(",");
      Serial.print(p1);
      Serial.println(")");
      analogWrite(analog_pin, p1);
    }
  }
}

So far PWM only works on Timer1.

analogWrite(6,128)
analogWrite(6,128) 3 - Set pulse_dt: 82 166
analogWrite(2,128)
analogWrite(2,128) 1 - Set pulse_dt: 82 166
analogWrite(10,128)
analogWrite(10,128) 7 - Set pulse_dt: 1003921 2000000

Output on Serial1 ...


pwm_stm32_set_cycles(0x805acc4, 2, 0, 0, 0)
        nm:pwm, state: 0 1
pwm_stm32_set_cycles(0x805acac, 2, 0, 0, 0)
        nm:pwm, state: 0 1
pwm_stm32_set_cycles(0x805acf4, 1, 2000, 1003, 0)
        nm:pwm, state: 0 1

Here are the changed files:
EDIT:
ChangedFiles.zip

The conf and overlay files are in the normal places. zephyrCommon.cpp is in the cores/arduino directory
the pwm_stm32.c goes into zephyr/devices/pwm... It only added output lines to print the couple of lines on Serial1.
Forgot to show the different timer output:
Pin 6 is on Timer4

Timer: 4
	CR1: 0x1
	CR2: 0x0
	SMCR: 0x0
	DIER: 0x0
	SR: 0x1
	EGR: 0x0
	CCMR1: 0x0
	CCMR2: 0x0
	CCER: 0x0
	CNT: 0x0
	PSC: 0xEF
	ARR: 0x0
	RCR: 0x0
	CCR1: 0x0
	CCR2: 0x0
	CCR3: 0x0
	CCR4: 0x0
	BDTR: 0x0
	DCR: 0x0
	DMAR: 0x1
	CCMR3: 0x0
	CCR5: 0x0
	CCR6: 0x0
	AF1: 0x0
	AF2: 0x0
	TISEL: 0x0

Pin 2 is on Timer15:

Timer: 15
	CR1: 0x1
	CR2: 0x0
	SMCR: 0x0
	DIER: 0x0
	SR: 0x1
	EGR: 0x0
	CCMR1: 0x0
	CCMR2: 0x0
	CCER: 0x0
	CNT: 0x0
	PSC: 0xEF
	ARR: 0x0
	RCR: 0x0
	CCR1: 0x0
	CCR2: 0x0
	CCR3: 0x0
	CCR4: 0x0
	BDTR: 0x8000
	DCR: 0x0
	DMAR: 0x1
	CCMR3: 0x0
	CCR5: 0x0
	CCR6: 0x0
	AF1: 0x1
	AF2: 0x0
	TISEL: 0x0

Pin 10 is on TImer 1:

Timer: 1
	CR1: 0x81
	CR2: 0x0
	SMCR: 0x0
	DIER: 0x0
	SR: 0x3001F
	EGR: 0x0
	CCMR1: 0x68
	CCMR2: 0x0
	CCER: 0x1
	CNT: 0x4C8
	PSC: 0xEF
	ARR: 0x7CF
	RCR: 0x0
	CCR1: 0x3EB
	CCR2: 0x0
	CCR3: 0x0
	CCR4: 0x0
	BDTR: 0x8000
	DCR: 0x0
	DMAR: 0x81
	CCMR3: 0x0
	CCR5: 0x0
	CCR6: 0x0
	AF1: 0x1
	AF2: 0x1
	TISEL: 0x0

Feels like it is missing glue to read in the other PWM timers and fill in things like CCR1...

@KurtE
Copy link
Author

KurtE commented Jan 4, 2025

For the heck of it, I did a few experiments with it today.

I was curious about the stuff in fixups.c, having to do with PWM for camera. I am not setting up for camera, but wondered if it would
initalize Timer15, so I sort of duplicated it

#if defined(CONFIG_BOARD_ARDUINO_GIGA_R1)
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/logging/log.h>

int pwm15_ext_clock_enable(void)
{
	int ret;
	uint32_t rate;
	LOG_PRINTK("pwm15_ext_clock_enable called\n");
	const struct device *pwm15_ext_clk_dev = DEVICE_DT_GET(DT_NODELABEL(pwm15clock));

	if (!device_is_ready(pwm15_ext_clk_dev)) {
		LOG_PRINTK("pwm15_ext_clock_enable called - device not ready\n");
		return -ENODEV;
	}

	ret = clock_control_on(pwm15_ext_clk_dev, (clock_control_subsys_t)0);
	if (ret < 0) {
		return ret;
	}

	ret = clock_control_get_rate(pwm15_ext_clk_dev, (clock_control_subsys_t)0, &rate);
	if (ret < 0) {
		return ret;
	}

	return 0;
}

SYS_INIT(pwm15_ext_clock_enable, APPLICATION, CONFIG_CLOCK_CONTROL_PWM_INIT_PRIORITY);

#endif

Built everything and nothing happend. This function was not called... So did some more hacking and tried calling it directly
from sketch. Would not load, need to add it to the export list and loaded and ran.

Note: the added stuff in the overlay file:

&timers15 {
	status = "okay";
	st,prescaler = <0xef>;

	tim15_pwm: pwm {
		status = "okay";
		pinctrl-0 = <&tim15_ch2_pa3>,
				<&tim15_ch1_pa2>;
		pinctrl-names = "default";
	};
};

&tim15_pwm {
	/* ...then use the timers15 node to start the clock generation */
	pwm15clock: pwmclock {
		status = "okay";
		compatible = "pwm-clock";
		clock-frequency = <0>;
		#clock-cells = <1>;
		pwms = <&tim15_pwm 2 PWM_HZ(500) PWM_POLARITY_NORMAL>;
				/* <&tim15_pwm 1 PWM_HZ(500) PWM_POLARITY_NORMAL>; */
	};
};

As I suspected, Pin 2 started up a sketch start up time. 500hz
Image

However if I try starting any other PWM it stops. For example in my sketch if I do analogWrte(10, 128) that actually
starts up as it is on Timer1, but the one that started on pin 10 stops.

Image

Wondering if PWM will currently only work on Timer1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants