Software APIs
pwm_smoketest.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include <stdint.h>
6 
13 #include "sw/device/lib/testing/test_framework/check.h"
15 #include "sw/device/lib/testing/test_framework/ottf_utils.h"
16 
18 
19 OTTF_DEFINE_TEST_CONFIG();
20 
21 static volatile const uint8_t kClocksHz[] = {24, 48, 96};
22 static volatile const uint8_t kDutyCycles[] = {11, 36, 50, 71, 91};
23 
24 static dif_pwm_config_t compute_clk_config(uint32_t pwm_clk) {
25  enum {
26  kDutyCycleResolution = 5,
27  kBeatsPerCycle = 1 << (kDutyCycleResolution + 1), // 2 ^ (DC_RESN + 1)
28  };
29  return (dif_pwm_config_t){
30  .beats_per_pulse_cycle = kBeatsPerCycle,
31  .clock_divisor =
32  ((uint32_t)kClockFreqAonHz / (kBeatsPerCycle * pwm_clk)) - 1};
33 }
34 
35 bool test_main(void) {
36  dif_pwm_t pwm;
38  CHECK_DIF_OK(dif_pwm_init(addr, &pwm));
39 
40  dif_pinmux_t pinmux;
42  CHECK_DIF_OK(dif_pinmux_init(addr, &pinmux));
45 
46  dif_gpio_t gpio;
48  CHECK_DIF_OK(dif_gpio_init(addr, &gpio));
49  CHECK_DIF_OK(dif_gpio_output_set_enabled_all(&gpio, 0x1));
50 
51  // The host uses IOA7 to let the device know when the sampling started.
52  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
55 
56  for (size_t i = 0; i < ARRAYSIZE(kClocksHz); ++i) {
57  dif_pwm_config_t pwm_config = compute_clk_config(kClocksHz[i]);
58  for (size_t j = 0; j < ARRAYSIZE(kDutyCycles); ++j) {
59  dif_pwm_channel_config_t channel_config = {
60  .duty_cycle_a = (uint16_t)(pwm_config.beats_per_pulse_cycle *
61  kDutyCycles[j] / 100),
62  .duty_cycle_b = 0,
63  .phase_delay = 0,
64  .mode = kDifPwmModeFirmware,
65  .polarity = kDifPwmPolarityActiveHigh,
66  .blink_parameter_x = 0,
67  .blink_parameter_y = 0,
68  };
69 
70  CHECK_DIF_OK(dif_pwm_configure(&pwm, pwm_config));
71  CHECK_DIF_OK(
72  dif_pwm_configure_channel(&pwm, kDifPwmChannel0, channel_config));
73 
74  // The IOA7 goes low when the host is sampling.
75  bool not_sampling = true;
76  do {
77  CHECK_DIF_OK(dif_gpio_read(&gpio, 0, &not_sampling));
78  if (!not_sampling) { // Debounce
79  busy_spin_micros(50);
80  CHECK_DIF_OK(dif_gpio_read(&gpio, 0, &not_sampling));
81  }
82  } while (not_sampling);
83 
85  CHECK_DIF_OK(dif_pwm_channel_set_enabled(&pwm, kDifPwmChannel0,
87 
88  // The goes high when the host stop sampling.
89  do {
90  CHECK_DIF_OK(dif_gpio_read(&gpio, 0, &not_sampling));
91  } while (!not_sampling);
92 
93  CHECK_DIF_OK(dif_pwm_channel_set_enabled(&pwm, kDifPwmChannel0,
96  }
97  }
98  return true;
99 }