libpynq  (release 5EID0-2023 version 0.3.0 of 2024-04-25 09:42 )
pwm.c
Go to the documentation of this file.
1 /*
2 Copyright (c) 2023 Eindhoven University of Technology
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21 */
22 #include <libpynq.h>
23 
24 enum PWM_Regs {
29 };
30 
31 static struct arm_shared_t channels[NUM_PWMS] = {
32  0,
33 };
34 static volatile uint32_t *initializedChannel[NUM_PWMS] = {
35  NULL,
36 };
37 
38 bool pwm_initialized(const int pwm) {
39  if (pwm < 0 || pwm >= NUM_PWMS) {
40  pynq_error("pwm_initialized: invalid pwm=%d, must be 0..%d-1\n", pwm,
41  NUM_PWMS);
42  }
43  if (initializedChannel[pwm] == NULL) {
44  return false;
45  }
46  return true;
47 }
48 
49 bool check_initialized_pwm(const int pwm) {
50  if (pwm < 0 || pwm >= NUM_PWMS) {
51  pynq_error("pwm_initialized: invalid pwm=%d, must be 0..%d-1\n", pwm,
52  NUM_PWMS);
53  }
54  if (initializedChannel[pwm] == NULL) {
55  pynq_error("pwm_initialized: channel of pwm %d has not been initialized\n",
56  pwm);
57  }
58  return true;
59 }
60 
61 void pwm_init(const int pwm, const uint32_t period) {
62  if (pwm < 0 || pwm >= NUM_PWMS) {
63  pynq_error("pwm_init: invalid pwm=%d, must be 0..%d-1\n", pwm, NUM_PWMS);
64  }
65  uint32_t channelAddr = axi_pwm_base + (pwm * 0x10000);
66  initializedChannel[pwm] = arm_shared_init(&channels[pwm], channelAddr, 512);
67  initializedChannel[pwm][PWM_REG_DUTY] = 0;
68  initializedChannel[pwm][PWM_REG_PERIOD] = period;
69  initializedChannel[pwm][PWM_REG_NEW_STEP_COUNT] = -1;
70 }
71 
72 void pwm_destroy(const int pwm) {
73  (void)check_initialized_pwm(pwm);
74  arm_shared_close(&channels[pwm]);
75  initializedChannel[pwm] = NULL;
76 }
77 
78 uint32_t pwm_get_duty_cycle(const int pwm) {
79  (void)check_initialized_pwm(pwm);
80  return initializedChannel[pwm][PWM_REG_DUTY];
81 }
82 
83 uint32_t pwm_get_period(const int pwm) {
84  (void)check_initialized_pwm(pwm);
85  return initializedChannel[pwm][PWM_REG_PERIOD];
86 }
87 
88 void pwm_set_period(const int pwm, const uint32_t period) {
89  (void)check_initialized_pwm(pwm);
90  initializedChannel[pwm][PWM_REG_PERIOD] = period;
91 }
92 
93 void pwm_set_duty_cycle(const int pwm, const uint32_t duty) {
94  (void)check_initialized_pwm(pwm);
95  initializedChannel[pwm][PWM_REG_DUTY] = duty;
96 }
97 
98 uint32_t pwm_get_steps(const int pwm) {
99  (void)check_initialized_pwm(pwm);
100  return initializedChannel[pwm][PWM_REG_NEW_STEP_COUNT];
101 }
102 
103 void pwm_set_steps(const int pwm, const uint32_t steps) {
104  (void)check_initialized_pwm(pwm);
105  initializedChannel[pwm][PWM_REG_NEW_STEP_COUNT] = steps;
106 }
NUM_PWMS
@ NUM_PWMS
Definition: pwm.h:47
pynq_error
#define pynq_error(...)
Definition: log.h:118
check_initialized_pwm
bool check_initialized_pwm(const int pwm)
Definition: pwm.c:49
arm_shared_t
Definition: arm_shared_memory_system.h:39
pwm_destroy
void pwm_destroy(const int pwm)
Removes the instantiated shared memory system of the PWM channel.
Definition: pwm.c:4
arm_shared_close
void arm_shared_close(arm_shared *handle)
Definition: arm_shared_memory_system.c:70
pwm_set_duty_cycle
void pwm_set_duty_cycle(const int pwm, const uint32_t duty)
Sets the duty cycle for the specified PWM channel.
Definition: pwm.c:5
pwm_set_steps
void pwm_set_steps(const int pwm, const uint32_t steps)
Generates steps steps on the PWM channel.
Definition: pwm.c:9
PWM_Regs
PWM_Regs
Definition: pwm.c:24
steps
steps
Definition: stepper.c:59
pwm_get_period
uint32_t pwm_get_period(const int pwm)
Returns the period of a certain PWM channel.
Definition: pwm.c:7
PWM_REG_PERIOD
@ PWM_REG_PERIOD
Definition: pwm.c:26
PWM_REG_CUR_STEP_COUNT
@ PWM_REG_CUR_STEP_COUNT
Definition: pwm.c:28
pwm_get_duty_cycle
uint32_t pwm_get_duty_cycle(const int pwm)
Gets the duty cycle of the specified PWM channel.
Definition: pwm.c:8
pwm_initialized
bool pwm_initialized(const int pwm)
Checks if the channel index is initialized.
Definition: pwm.c:2
PWM_REG_DUTY
@ PWM_REG_DUTY
Definition: pwm.c:25
arm_shared_init
void * arm_shared_init(arm_shared *handle, const uint32_t address, const uint32_t length)
Definition: arm_shared_memory_system.c:32
PWM_REG_NEW_STEP_COUNT
@ PWM_REG_NEW_STEP_COUNT
Definition: pwm.c:27
pwm_set_period
void pwm_set_period(const int pwm, const uint32_t period)
Sets the period for the specified PWM channel.
Definition: pwm.c:6
pwm_init
void pwm_init(const int pwm, const uint32_t period)
Initializes the PWM channel with the specified period.
Definition: pwm.c:3
pwm_get_steps
uint32_t pwm_get_steps(const int pwm)
Get the number of steps a certain channel has taken so far.
Definition: pwm.c:10
libpynq.h