This is a part of the Kinetiszer project.
pwm_timer.c@0:cb80470434eb, 2014-10-28 (annotated)
- Committer:
- Clemo
- Date:
- Tue Oct 28 12:19:42 2014 +0000
- Revision:
- 0:cb80470434eb
Error & warning free.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Clemo | 0:cb80470434eb | 1 | /* |
Clemo | 0:cb80470434eb | 2 | * @brief PWM timer driver |
Clemo | 0:cb80470434eb | 3 | * |
Clemo | 0:cb80470434eb | 4 | * @note |
Clemo | 0:cb80470434eb | 5 | * Copyright (C) Elektor, 2014 |
Clemo | 0:cb80470434eb | 6 | * All rights reserved. |
Clemo | 0:cb80470434eb | 7 | * |
Clemo | 0:cb80470434eb | 8 | * @par |
Clemo | 0:cb80470434eb | 9 | * This software is supplied "AS IS" without any warranties of any kind, |
Clemo | 0:cb80470434eb | 10 | * and Elektor and its licensor disclaim any and all warranties, express |
Clemo | 0:cb80470434eb | 11 | * or implied, including all implied warranties of merchantability, |
Clemo | 0:cb80470434eb | 12 | * fitness for a particular purpose and non-infringement of intellectual |
Clemo | 0:cb80470434eb | 13 | * property rights. Elektor assumes no responsibility or liability for |
Clemo | 0:cb80470434eb | 14 | * the use of the software, conveys no license or rights under any patent, |
Clemo | 0:cb80470434eb | 15 | * copyright, mask work right, or any other intellectual property rights in |
Clemo | 0:cb80470434eb | 16 | * or to any products. Elektor reserves the right to make changes in the |
Clemo | 0:cb80470434eb | 17 | * software without notification. Elektor also makes no representation or |
Clemo | 0:cb80470434eb | 18 | * warranty that such application will be suitable for the specified use |
Clemo | 0:cb80470434eb | 19 | * without further testing or modification. |
Clemo | 0:cb80470434eb | 20 | * |
Clemo | 0:cb80470434eb | 21 | * @par |
Clemo | 0:cb80470434eb | 22 | * Permission to use, copy, modify, and distribute this software and its |
Clemo | 0:cb80470434eb | 23 | * documentation is hereby granted, under Elektor's and its licensor's |
Clemo | 0:cb80470434eb | 24 | * relevant copyrights in the software, without fee. This copyright, |
Clemo | 0:cb80470434eb | 25 | * permission, and disclaimer notice must appear in all copies of this code. |
Clemo | 0:cb80470434eb | 26 | */ |
Clemo | 0:cb80470434eb | 27 | |
Clemo | 0:cb80470434eb | 28 | #include "board.h" |
Clemo | 0:cb80470434eb | 29 | #include "pwm_timer.h" |
Clemo | 0:cb80470434eb | 30 | |
Clemo | 0:cb80470434eb | 31 | |
Clemo | 0:cb80470434eb | 32 | #define PWM_TIMER_DUTY_CYCLE_MAX (1000) |
Clemo | 0:cb80470434eb | 33 | |
Clemo | 0:cb80470434eb | 34 | #define LPC_TIMER16_0 ((LPC_TIMER_T*)0) |
Clemo | 0:cb80470434eb | 35 | #define TIMER_16_0_IRQn (0) |
Clemo | 0:cb80470434eb | 36 | #define LPC_TIMER16_1 ((LPC_TIMER_T*)1) |
Clemo | 0:cb80470434eb | 37 | #define TIMER_16_1_IRQn (1) |
Clemo | 0:cb80470434eb | 38 | #define LPC_TIMER32_0 ((LPC_TIMER_T*)2) |
Clemo | 0:cb80470434eb | 39 | #define TIMER_32_0_IRQn (2) |
Clemo | 0:cb80470434eb | 40 | #define LPC_TIMER32_1 ((LPC_TIMER_T*)3) |
Clemo | 0:cb80470434eb | 41 | #define TIMER_32_1_IRQn (3) |
Clemo | 0:cb80470434eb | 42 | |
Clemo | 0:cb80470434eb | 43 | |
Clemo | 0:cb80470434eb | 44 | const pwm_timer_t pwm_timers[PWM_TIMERS] = |
Clemo | 0:cb80470434eb | 45 | { |
Clemo | 0:cb80470434eb | 46 | { // 0 |
Clemo | 0:cb80470434eb | 47 | LPC_TIMER16_0, |
Clemo | 0:cb80470434eb | 48 | TIMER_16_0_IRQn, |
Clemo | 0:cb80470434eb | 49 | PWM_TIMER_FREQUENCY_REGISTER, |
Clemo | 0:cb80470434eb | 50 | { |
Clemo | 0:cb80470434eb | 51 | { 0, 8, IOCON_FUNC2, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 52 | { 0, 9, IOCON_FUNC2, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 53 | { 0, 10, IOCON_FUNC3, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 54 | { (uint8_t)-1, (uint8_t)-1, (uint32_t)-1, (uint32_t)-1 }, |
Clemo | 0:cb80470434eb | 55 | }, |
Clemo | 0:cb80470434eb | 56 | }, |
Clemo | 0:cb80470434eb | 57 | { // 1 |
Clemo | 0:cb80470434eb | 58 | LPC_TIMER16_1, |
Clemo | 0:cb80470434eb | 59 | TIMER_16_1_IRQn, |
Clemo | 0:cb80470434eb | 60 | PWM_TIMER_FREQUENCY_REGISTER, |
Clemo | 0:cb80470434eb | 61 | { |
Clemo | 0:cb80470434eb | 62 | { 0, 21, IOCON_FUNC1, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 63 | { 0, 22, IOCON_FUNC2, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 64 | { (uint8_t)-1, (uint8_t)-1, (uint32_t)-1, (uint32_t)-1 }, |
Clemo | 0:cb80470434eb | 65 | { (uint8_t)-1, (uint8_t)-1, (uint32_t)-1, (uint32_t)-1 }, |
Clemo | 0:cb80470434eb | 66 | }, |
Clemo | 0:cb80470434eb | 67 | }, |
Clemo | 0:cb80470434eb | 68 | { // 2 |
Clemo | 0:cb80470434eb | 69 | LPC_TIMER32_0, |
Clemo | 0:cb80470434eb | 70 | TIMER_32_0_IRQn, |
Clemo | 0:cb80470434eb | 71 | PWM_TIMER_FREQUENCY_REGISTER, |
Clemo | 0:cb80470434eb | 72 | { |
Clemo | 0:cb80470434eb | 73 | { 0, 18, IOCON_FUNC2, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 74 | { 0, 19, IOCON_FUNC2, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 75 | { 0, 1, IOCON_FUNC2, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 76 | { 1, 27, IOCON_FUNC1, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 77 | }, |
Clemo | 0:cb80470434eb | 78 | }, |
Clemo | 0:cb80470434eb | 79 | { // 3 |
Clemo | 0:cb80470434eb | 80 | LPC_TIMER32_1, |
Clemo | 0:cb80470434eb | 81 | TIMER_32_1_IRQn, |
Clemo | 0:cb80470434eb | 82 | PWM_TIMER_FREQUENCY_REGISTER, |
Clemo | 0:cb80470434eb | 83 | { |
Clemo | 0:cb80470434eb | 84 | { 0, 13, IOCON_FUNC3, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 85 | { 0, 14, IOCON_FUNC3, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 86 | { 0, 15, IOCON_FUNC3, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 87 | { 0, 16, IOCON_FUNC2, PWM_TIMER_DEFAULT_DUTY_CYCLE }, |
Clemo | 0:cb80470434eb | 88 | }, |
Clemo | 0:cb80470434eb | 89 | } |
Clemo | 0:cb80470434eb | 90 | }; |
Clemo | 0:cb80470434eb | 91 | |
Clemo | 0:cb80470434eb | 92 | |
Clemo | 0:cb80470434eb | 93 | void PwmTimer_Init(const pwm_timer_t *p_timer, uint32_t frequency) |
Clemo | 0:cb80470434eb | 94 | { |
Clemo | 0:cb80470434eb | 95 | // Setup timer. |
Clemo | 0:cb80470434eb | 96 | //Chip_TIMER_Init(p_timer->timer); |
Clemo | 0:cb80470434eb | 97 | //Chip_TIMER_Reset(p_timer->timer); |
Clemo | 0:cb80470434eb | 98 | // Register the MRx register that will determine the frequency. |
Clemo | 0:cb80470434eb | 99 | //Chip_TIMER_ResetOnMatchEnable(p_timer->timer,p_timer->frequency_register); |
Clemo | 0:cb80470434eb | 100 | // Load the frequency register. |
Clemo | 0:cb80470434eb | 101 | PwmTimer_SetFrequency(p_timer,frequency); |
Clemo | 0:cb80470434eb | 102 | //PwmTimer_Start(p_timer->timer); |
Clemo | 0:cb80470434eb | 103 | } |
Clemo | 0:cb80470434eb | 104 | |
Clemo | 0:cb80470434eb | 105 | |
Clemo | 0:cb80470434eb | 106 | void PwmTimer_InitChannel(const pwm_timer_t *p_timer, uint8_t channel, uint32_t duty_cycle) |
Clemo | 0:cb80470434eb | 107 | { |
Clemo | 0:cb80470434eb | 108 | // Setup pin multiplexer. |
Clemo | 0:cb80470434eb | 109 | //Chip_IOCON_PinMuxSet(LPC_IOCON,p_timer->channel[channel].port,p_timer->channel[channel].pin,IOCON_DIGMODE_EN|IOCON_MODE_INACT|p_timer->channel[channel].function); |
Clemo | 0:cb80470434eb | 110 | // Make the pin an output. |
Clemo | 0:cb80470434eb | 111 | //Chip_GPIO_WriteDirBit(LPC_GPIO_PORT,p_timer->channel[channel].port,p_timer->channel[channel].pin,OUTPUT); |
Clemo | 0:cb80470434eb | 112 | |
Clemo | 0:cb80470434eb | 113 | // Activate PWM mode on the duty-cycle register. |
Clemo | 0:cb80470434eb | 114 | // CPV 09042014: for some reason the LPCOpen library doesn't know about the PWMC register, |
Clemo | 0:cb80470434eb | 115 | // so I added it myself. |
Clemo | 0:cb80470434eb | 116 | //p_timer->timer->PWMC |= 1 << channel; |
Clemo | 0:cb80470434eb | 117 | PwmTimer_SetDutyCycle(p_timer,channel,duty_cycle); |
Clemo | 0:cb80470434eb | 118 | } |
Clemo | 0:cb80470434eb | 119 | |
Clemo | 0:cb80470434eb | 120 | |
Clemo | 0:cb80470434eb | 121 | void PwmTimer_SetFrequency(const pwm_timer_t *p_timer, uint32_t frequency) |
Clemo | 0:cb80470434eb | 122 | { |
Clemo | 0:cb80470434eb | 123 | //Chip_TIMER_SetMatch(p_timer->timer,p_timer->frequency_register,Chip_Clock_GetSystemClockRate()/frequency); |
Clemo | 0:cb80470434eb | 124 | } |
Clemo | 0:cb80470434eb | 125 | |
Clemo | 0:cb80470434eb | 126 | |
Clemo | 0:cb80470434eb | 127 | void PwmTimer_SetDutyCycle(const pwm_timer_t *p_timer, uint8_t channel, uint32_t duty_cycle) |
Clemo | 0:cb80470434eb | 128 | { |
Clemo | 0:cb80470434eb | 129 | if (duty_cycle>PWM_TIMER_DUTY_CYCLE_MAX) duty_cycle = PWM_TIMER_DUTY_CYCLE_MAX; |
Clemo | 0:cb80470434eb | 130 | //Chip_TIMER_SetMatch(p_timer->timer,channel,duty_cycle*p_timer->timer->MR[p_timer->frequency_register]/PWM_TIMER_DUTY_CYCLE_MAX); |
Clemo | 0:cb80470434eb | 131 | } |
Clemo | 0:cb80470434eb | 132 | |
Clemo | 0:cb80470434eb | 133 | |
Clemo | 0:cb80470434eb | 134 | void PwmTimer_Start(const pwm_timer_t *p_timer) |
Clemo | 0:cb80470434eb | 135 | { |
Clemo | 0:cb80470434eb | 136 | //Chip_TIMER_Enable(p_timer->timer); |
Clemo | 0:cb80470434eb | 137 | } |
Clemo | 0:cb80470434eb | 138 | |
Clemo | 0:cb80470434eb | 139 | |
Clemo | 0:cb80470434eb | 140 | void PwmTimer_Stop(const pwm_timer_t *p_timer) |
Clemo | 0:cb80470434eb | 141 | { |
Clemo | 0:cb80470434eb | 142 | //Chip_TIMER_Disable(p_timer->timer); |
Clemo | 0:cb80470434eb | 143 | } |
Clemo | 0:cb80470434eb | 144 | |
Clemo | 0:cb80470434eb | 145 | |
Clemo | 0:cb80470434eb | 146 | void PwmTimer_EnableInterrupt(const pwm_timer_t *p_timer, uint8_t channel) |
Clemo | 0:cb80470434eb | 147 | { |
Clemo | 0:cb80470434eb | 148 | // Select the match register that will generate interrupts. |
Clemo | 0:cb80470434eb | 149 | //Chip_TIMER_MatchEnableInt(p_timer->timer,channel); |
Clemo | 0:cb80470434eb | 150 | // Enable timer interrupt. |
Clemo | 0:cb80470434eb | 151 | //NVIC_ClearPendingIRQ(p_timer->irq); |
Clemo | 0:cb80470434eb | 152 | //NVIC_EnableIRQ(p_timer->irq); |
Clemo | 0:cb80470434eb | 153 | } |
Clemo | 0:cb80470434eb | 154 |