Daiki Kato / mbed-os-lychee

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

Committer:
dkato
Date:
Fri Feb 02 05:42:23 2018 +0000
Revision:
0:f782d9c66c49
mbed-os for GR-LYCHEE

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:f782d9c66c49 1 /* mbed Microcontroller Library
dkato 0:f782d9c66c49 2 * Copyright (c) 2006-2013 ARM Limited
dkato 0:f782d9c66c49 3 *
dkato 0:f782d9c66c49 4 * Licensed under the Apache License, Version 2.0 (the "License");
dkato 0:f782d9c66c49 5 * you may not use this file except in compliance with the License.
dkato 0:f782d9c66c49 6 * You may obtain a copy of the License at
dkato 0:f782d9c66c49 7 *
dkato 0:f782d9c66c49 8 * http://www.apache.org/licenses/LICENSE-2.0
dkato 0:f782d9c66c49 9 *
dkato 0:f782d9c66c49 10 * Unless required by applicable law or agreed to in writing, software
dkato 0:f782d9c66c49 11 * distributed under the License is distributed on an "AS IS" BASIS,
dkato 0:f782d9c66c49 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dkato 0:f782d9c66c49 13 * See the License for the specific language governing permissions and
dkato 0:f782d9c66c49 14 * limitations under the License.
dkato 0:f782d9c66c49 15 */
dkato 0:f782d9c66c49 16 #include "mbed_assert.h"
dkato 0:f782d9c66c49 17 #include "pwmout_api.h"
dkato 0:f782d9c66c49 18 #include "cmsis.h"
dkato 0:f782d9c66c49 19 #include "PeripheralPins.h"
dkato 0:f782d9c66c49 20 #include "RZ_A1_Init.h"
dkato 0:f782d9c66c49 21 #include "iodefine.h"
dkato 0:f782d9c66c49 22 #include "gpio_addrdefine.h"
dkato 0:f782d9c66c49 23 #include "mbed_drv_cfg.h"
dkato 0:f782d9c66c49 24
dkato 0:f782d9c66c49 25 #define MTU2_PWM_OFFSET 0x20
dkato 0:f782d9c66c49 26
dkato 0:f782d9c66c49 27 #ifdef FUNC_MOTOR_CTL_PWM
dkato 0:f782d9c66c49 28 typedef enum {
dkato 0:f782d9c66c49 29 PWM1A = 0,
dkato 0:f782d9c66c49 30 PWM1B,
dkato 0:f782d9c66c49 31 PWM1C,
dkato 0:f782d9c66c49 32 PWM1D,
dkato 0:f782d9c66c49 33 PWM1E,
dkato 0:f782d9c66c49 34 PWM1F,
dkato 0:f782d9c66c49 35 PWM1G,
dkato 0:f782d9c66c49 36 PWM1H,
dkato 0:f782d9c66c49 37 PWM2A = 0x10,
dkato 0:f782d9c66c49 38 PWM2B,
dkato 0:f782d9c66c49 39 PWM2C,
dkato 0:f782d9c66c49 40 PWM2D,
dkato 0:f782d9c66c49 41 PWM2E,
dkato 0:f782d9c66c49 42 PWM2F,
dkato 0:f782d9c66c49 43 PWM2G,
dkato 0:f782d9c66c49 44 PWM2H,
dkato 0:f782d9c66c49 45 } PWMType;
dkato 0:f782d9c66c49 46
dkato 0:f782d9c66c49 47 static const PWMType PORT[] = {
dkato 0:f782d9c66c49 48 PWM1A, // PWM_PWM1A
dkato 0:f782d9c66c49 49 PWM1B, // PWM_PWM1B
dkato 0:f782d9c66c49 50 PWM1C, // PWM_PWM1C
dkato 0:f782d9c66c49 51 PWM1D, // PWM_PWM1D
dkato 0:f782d9c66c49 52 PWM1E, // PWM_PWM1E
dkato 0:f782d9c66c49 53 PWM1F, // PWM_PWM1F
dkato 0:f782d9c66c49 54 PWM1G, // PWM_PWM1G
dkato 0:f782d9c66c49 55 PWM1H, // PWM_PWM1H
dkato 0:f782d9c66c49 56 PWM2A, // PWM_PWM2A
dkato 0:f782d9c66c49 57 PWM2B, // PWM_PWM2B
dkato 0:f782d9c66c49 58 PWM2C, // PWM_PWM2C
dkato 0:f782d9c66c49 59 PWM2D, // PWM_PWM2D
dkato 0:f782d9c66c49 60 PWM2E, // PWM_PWM2E
dkato 0:f782d9c66c49 61 PWM2F, // PWM_PWM2F
dkato 0:f782d9c66c49 62 PWM2G, // PWM_PWM2G
dkato 0:f782d9c66c49 63 PWM2H, // PWM_PWM2H
dkato 0:f782d9c66c49 64 };
dkato 0:f782d9c66c49 65
dkato 0:f782d9c66c49 66 static __IO uint16_t *PWM_MATCH[] = {
dkato 0:f782d9c66c49 67 &PWMPWBFR_1A, // PWM_PWM1A
dkato 0:f782d9c66c49 68 &PWMPWBFR_1A, // PWM_PWM1B
dkato 0:f782d9c66c49 69 &PWMPWBFR_1C, // PWM_PWM1C
dkato 0:f782d9c66c49 70 &PWMPWBFR_1C, // PWM_PWM1D
dkato 0:f782d9c66c49 71 &PWMPWBFR_1E, // PWM_PWM1E
dkato 0:f782d9c66c49 72 &PWMPWBFR_1E, // PWM_PWM1F
dkato 0:f782d9c66c49 73 &PWMPWBFR_1G, // PWM_PWM1G
dkato 0:f782d9c66c49 74 &PWMPWBFR_1G, // PWM_PWM1H
dkato 0:f782d9c66c49 75 &PWMPWBFR_2A, // PWM_PWM2A
dkato 0:f782d9c66c49 76 &PWMPWBFR_2A, // PWM_PWM2B
dkato 0:f782d9c66c49 77 &PWMPWBFR_2C, // PWM_PWM2C
dkato 0:f782d9c66c49 78 &PWMPWBFR_2C, // PWM_PWM2D
dkato 0:f782d9c66c49 79 &PWMPWBFR_2E, // PWM_PWM2E
dkato 0:f782d9c66c49 80 &PWMPWBFR_2E, // PWM_PWM2F
dkato 0:f782d9c66c49 81 &PWMPWBFR_2G, // PWM_PWM2G
dkato 0:f782d9c66c49 82 &PWMPWBFR_2G, // PWM_PWM2H
dkato 0:f782d9c66c49 83 };
dkato 0:f782d9c66c49 84
dkato 0:f782d9c66c49 85 static uint16_t init_period_ch1 = 0;
dkato 0:f782d9c66c49 86 static uint16_t init_period_ch2 = 0;
dkato 0:f782d9c66c49 87 static int32_t period_ch1 = 1;
dkato 0:f782d9c66c49 88 static int32_t period_ch2 = 1;
dkato 0:f782d9c66c49 89 #endif
dkato 0:f782d9c66c49 90
dkato 0:f782d9c66c49 91 #ifdef FUMC_MTU2_PWM
dkato 0:f782d9c66c49 92 #define MTU2_PWM_SIGNAL 2
dkato 0:f782d9c66c49 93
dkato 0:f782d9c66c49 94 typedef enum {
dkato 0:f782d9c66c49 95 TIOC0A = 0,
dkato 0:f782d9c66c49 96 TIOC0B,
dkato 0:f782d9c66c49 97 TIOC0C,
dkato 0:f782d9c66c49 98 TIOC0D,
dkato 0:f782d9c66c49 99 TIOC1A = 0x10,
dkato 0:f782d9c66c49 100 TIOC1B,
dkato 0:f782d9c66c49 101 TIOC2A = 0x20,
dkato 0:f782d9c66c49 102 TIOC2B,
dkato 0:f782d9c66c49 103 TIOC3A = 0x30,
dkato 0:f782d9c66c49 104 TIOC3B,
dkato 0:f782d9c66c49 105 TIOC3C,
dkato 0:f782d9c66c49 106 TIOC3D,
dkato 0:f782d9c66c49 107 TIOC4A = 0x40,
dkato 0:f782d9c66c49 108 TIOC4B,
dkato 0:f782d9c66c49 109 TIOC4C,
dkato 0:f782d9c66c49 110 TIOC4D,
dkato 0:f782d9c66c49 111 } MTU2_PWMType;
dkato 0:f782d9c66c49 112
dkato 0:f782d9c66c49 113 static const MTU2_PWMType MTU2_PORT[] = {
dkato 0:f782d9c66c49 114 TIOC0A, // PWM_TIOC0A
dkato 0:f782d9c66c49 115 TIOC0C, // PWM_TIOC0C
dkato 0:f782d9c66c49 116 TIOC1A, // PWM_TIOC1A
dkato 0:f782d9c66c49 117 TIOC2A, // PWM_TIOC2A
dkato 0:f782d9c66c49 118 TIOC3A, // PWM_TIOC3A
dkato 0:f782d9c66c49 119 TIOC3C, // PWM_TIOC3C
dkato 0:f782d9c66c49 120 TIOC4A, // PWM_TIOC4A
dkato 0:f782d9c66c49 121 TIOC4C, // PWM_TIOC4C
dkato 0:f782d9c66c49 122 };
dkato 0:f782d9c66c49 123
dkato 0:f782d9c66c49 124 static __IO uint16_t *MTU2_PWM_MATCH[][MTU2_PWM_SIGNAL] = {
dkato 0:f782d9c66c49 125 { &MTU2TGRA_0, &MTU2TGRB_0 }, // PWM_TIOC0A
dkato 0:f782d9c66c49 126 { &MTU2TGRC_0, &MTU2TGRD_0 }, // PWM_TIOC0C
dkato 0:f782d9c66c49 127 { &MTU2TGRA_1, &MTU2TGRB_1 }, // PWM_TIOC1A
dkato 0:f782d9c66c49 128 { &MTU2TGRA_2, &MTU2TGRB_2 }, // PWM_TIOC2A
dkato 0:f782d9c66c49 129 { &MTU2TGRA_3, &MTU2TGRB_3 }, // PWM_TIOC3A
dkato 0:f782d9c66c49 130 { &MTU2TGRC_3, &MTU2TGRD_3 }, // PWM_TIOC3C
dkato 0:f782d9c66c49 131 { &MTU2TGRA_4, &MTU2TGRB_4 }, // PWM_TIOC4A
dkato 0:f782d9c66c49 132 { &MTU2TGRC_4, &MTU2TGRD_4 }, // PWM_TIOC4C
dkato 0:f782d9c66c49 133 };
dkato 0:f782d9c66c49 134
dkato 0:f782d9c66c49 135 static __IO uint8_t *TCR_MATCH[] = {
dkato 0:f782d9c66c49 136 &MTU2TCR_0,
dkato 0:f782d9c66c49 137 &MTU2TCR_1,
dkato 0:f782d9c66c49 138 &MTU2TCR_2,
dkato 0:f782d9c66c49 139 &MTU2TCR_3,
dkato 0:f782d9c66c49 140 &MTU2TCR_4,
dkato 0:f782d9c66c49 141 };
dkato 0:f782d9c66c49 142
dkato 0:f782d9c66c49 143 static __IO uint8_t *TIORH_MATCH[] = {
dkato 0:f782d9c66c49 144 &MTU2TIORH_0,
dkato 0:f782d9c66c49 145 &MTU2TIOR_1,
dkato 0:f782d9c66c49 146 &MTU2TIOR_2,
dkato 0:f782d9c66c49 147 &MTU2TIORH_3,
dkato 0:f782d9c66c49 148 &MTU2TIORH_4,
dkato 0:f782d9c66c49 149 };
dkato 0:f782d9c66c49 150
dkato 0:f782d9c66c49 151 static __IO uint8_t *TIORL_MATCH[] = {
dkato 0:f782d9c66c49 152 &MTU2TIORL_0,
dkato 0:f782d9c66c49 153 NULL,
dkato 0:f782d9c66c49 154 NULL,
dkato 0:f782d9c66c49 155 &MTU2TIORL_3,
dkato 0:f782d9c66c49 156 &MTU2TIORL_4,
dkato 0:f782d9c66c49 157 };
dkato 0:f782d9c66c49 158
dkato 0:f782d9c66c49 159 static __IO uint16_t *TGRA_MATCH[] = {
dkato 0:f782d9c66c49 160 &MTU2TGRA_0,
dkato 0:f782d9c66c49 161 &MTU2TGRA_1,
dkato 0:f782d9c66c49 162 &MTU2TGRA_2,
dkato 0:f782d9c66c49 163 &MTU2TGRA_3,
dkato 0:f782d9c66c49 164 &MTU2TGRA_4,
dkato 0:f782d9c66c49 165 };
dkato 0:f782d9c66c49 166
dkato 0:f782d9c66c49 167 static __IO uint16_t *TGRC_MATCH[] = {
dkato 0:f782d9c66c49 168 &MTU2TGRC_0,
dkato 0:f782d9c66c49 169 NULL,
dkato 0:f782d9c66c49 170 NULL,
dkato 0:f782d9c66c49 171 &MTU2TGRC_3,
dkato 0:f782d9c66c49 172 &MTU2TGRC_4,
dkato 0:f782d9c66c49 173 };
dkato 0:f782d9c66c49 174
dkato 0:f782d9c66c49 175 static __IO uint8_t *TMDR_MATCH[] = {
dkato 0:f782d9c66c49 176 &MTU2TMDR_0,
dkato 0:f782d9c66c49 177 &MTU2TMDR_1,
dkato 0:f782d9c66c49 178 &MTU2TMDR_2,
dkato 0:f782d9c66c49 179 &MTU2TMDR_3,
dkato 0:f782d9c66c49 180 &MTU2TMDR_4,
dkato 0:f782d9c66c49 181 };
dkato 0:f782d9c66c49 182
dkato 0:f782d9c66c49 183 static int MAX_PERIOD[] = {
dkato 0:f782d9c66c49 184 125000,
dkato 0:f782d9c66c49 185 503000,
dkato 0:f782d9c66c49 186 2000000,
dkato 0:f782d9c66c49 187 2000000,
dkato 0:f782d9c66c49 188 2000000,
dkato 0:f782d9c66c49 189 };
dkato 0:f782d9c66c49 190
dkato 0:f782d9c66c49 191 typedef enum {
dkato 0:f782d9c66c49 192 MTU2_PULSE = 0,
dkato 0:f782d9c66c49 193 MTU2_PERIOD
dkato 0:f782d9c66c49 194 } MTU2Signal;
dkato 0:f782d9c66c49 195
dkato 0:f782d9c66c49 196 static uint16_t init_mtu2_period_ch[5] = {0};
dkato 0:f782d9c66c49 197 static int32_t mtu2_period_ch[5] = {1, 1, 1, 1, 1};
dkato 0:f782d9c66c49 198 #endif
dkato 0:f782d9c66c49 199
dkato 0:f782d9c66c49 200 void pwmout_init(pwmout_t* obj, PinName pin) {
dkato 0:f782d9c66c49 201 // determine the channel
dkato 0:f782d9c66c49 202 PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
dkato 0:f782d9c66c49 203 MBED_ASSERT(pwm != (PWMName)NC);
dkato 0:f782d9c66c49 204
dkato 0:f782d9c66c49 205 if (pwm >= MTU2_PWM_OFFSET) {
dkato 0:f782d9c66c49 206 #ifdef FUMC_MTU2_PWM
dkato 0:f782d9c66c49 207 /* PWM by MTU2 */
dkato 0:f782d9c66c49 208 int tmp_pwm;
dkato 0:f782d9c66c49 209
dkato 0:f782d9c66c49 210 // power on
dkato 0:f782d9c66c49 211 CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP33);
dkato 0:f782d9c66c49 212
dkato 0:f782d9c66c49 213 obj->pwm = pwm;
dkato 0:f782d9c66c49 214 tmp_pwm = (int)(obj->pwm - MTU2_PWM_OFFSET);
dkato 0:f782d9c66c49 215 if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000040) == 0x00000040) {
dkato 0:f782d9c66c49 216 obj->ch = 4;
dkato 0:f782d9c66c49 217 MTU2TOER |= 0x36;
dkato 0:f782d9c66c49 218 } else if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000030) == 0x00000030) {
dkato 0:f782d9c66c49 219 obj->ch = 3;
dkato 0:f782d9c66c49 220 MTU2TOER |= 0x09;
dkato 0:f782d9c66c49 221 } else if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000020) == 0x00000020) {
dkato 0:f782d9c66c49 222 obj->ch = 2;
dkato 0:f782d9c66c49 223 } else if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000010) == 0x00000010) {
dkato 0:f782d9c66c49 224 obj->ch = 1;
dkato 0:f782d9c66c49 225 } else {
dkato 0:f782d9c66c49 226 obj->ch = 0;
dkato 0:f782d9c66c49 227 }
dkato 0:f782d9c66c49 228 // Wire pinout
dkato 0:f782d9c66c49 229 pinmap_pinout(pin, PinMap_PWM);
dkato 0:f782d9c66c49 230
dkato 0:f782d9c66c49 231 int bitmask = 1 << (pin & 0xf);
dkato 0:f782d9c66c49 232
dkato 0:f782d9c66c49 233 *PMSR(PINGROUP(pin)) = (bitmask << 16) | 0;
dkato 0:f782d9c66c49 234
dkato 0:f782d9c66c49 235 // default duty 0.0f
dkato 0:f782d9c66c49 236 pwmout_write(obj, 0);
dkato 0:f782d9c66c49 237 if (init_mtu2_period_ch[obj->ch] == 0) {
dkato 0:f782d9c66c49 238 // default period 1ms
dkato 0:f782d9c66c49 239 pwmout_period_us(obj, 1000);
dkato 0:f782d9c66c49 240 init_mtu2_period_ch[obj->ch] = 1;
dkato 0:f782d9c66c49 241 }
dkato 0:f782d9c66c49 242 #endif
dkato 0:f782d9c66c49 243 } else {
dkato 0:f782d9c66c49 244 #ifdef FUNC_MOTOR_CTL_PWM
dkato 0:f782d9c66c49 245 /* PWM */
dkato 0:f782d9c66c49 246 // power on
dkato 0:f782d9c66c49 247 CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP30);
dkato 0:f782d9c66c49 248
dkato 0:f782d9c66c49 249 obj->pwm = pwm;
dkato 0:f782d9c66c49 250 if (((uint32_t)PORT[obj->pwm] & 0x00000010) == 0x00000010) {
dkato 0:f782d9c66c49 251 obj->ch = 2;
dkato 0:f782d9c66c49 252 PWMPWPR_2_BYTE_L = 0x00;
dkato 0:f782d9c66c49 253 } else {
dkato 0:f782d9c66c49 254 obj->ch = 1;
dkato 0:f782d9c66c49 255 PWMPWPR_1_BYTE_L = 0x00;
dkato 0:f782d9c66c49 256 }
dkato 0:f782d9c66c49 257
dkato 0:f782d9c66c49 258 // Wire pinout
dkato 0:f782d9c66c49 259 pinmap_pinout(pin, PinMap_PWM);
dkato 0:f782d9c66c49 260
dkato 0:f782d9c66c49 261 // default to 491us: standard for servos, and fine for e.g. brightness control
dkato 0:f782d9c66c49 262 pwmout_write(obj, 0);
dkato 0:f782d9c66c49 263 if ((obj->ch == 2) && (init_period_ch2 == 0)) {
dkato 0:f782d9c66c49 264 pwmout_period_us(obj, 491);
dkato 0:f782d9c66c49 265 init_period_ch2 = 1;
dkato 0:f782d9c66c49 266 }
dkato 0:f782d9c66c49 267 if ((obj->ch == 1) && (init_period_ch1 == 0)) {
dkato 0:f782d9c66c49 268 pwmout_period_us(obj, 491);
dkato 0:f782d9c66c49 269 init_period_ch1 = 1;
dkato 0:f782d9c66c49 270 }
dkato 0:f782d9c66c49 271 #endif
dkato 0:f782d9c66c49 272 }
dkato 0:f782d9c66c49 273 }
dkato 0:f782d9c66c49 274
dkato 0:f782d9c66c49 275 void pwmout_free(pwmout_t* obj) {
dkato 0:f782d9c66c49 276 pwmout_write(obj, 0);
dkato 0:f782d9c66c49 277 }
dkato 0:f782d9c66c49 278
dkato 0:f782d9c66c49 279 void pwmout_write(pwmout_t* obj, float value) {
dkato 0:f782d9c66c49 280 uint32_t wk_cycle;
dkato 0:f782d9c66c49 281
dkato 0:f782d9c66c49 282 if (obj->pwm >= MTU2_PWM_OFFSET) {
dkato 0:f782d9c66c49 283 #ifdef FUMC_MTU2_PWM
dkato 0:f782d9c66c49 284 /* PWM by MTU2 */
dkato 0:f782d9c66c49 285 int tmp_pwm;
dkato 0:f782d9c66c49 286
dkato 0:f782d9c66c49 287 if (value < 0.0f) {
dkato 0:f782d9c66c49 288 value = 0.0f;
dkato 0:f782d9c66c49 289 } else if (value > 1.0f) {
dkato 0:f782d9c66c49 290 value = 1.0f;
dkato 0:f782d9c66c49 291 } else {
dkato 0:f782d9c66c49 292 // Do Nothing
dkato 0:f782d9c66c49 293 }
dkato 0:f782d9c66c49 294 tmp_pwm = (int)(obj->pwm - MTU2_PWM_OFFSET);
dkato 0:f782d9c66c49 295 wk_cycle = *MTU2_PWM_MATCH[tmp_pwm][MTU2_PERIOD] & 0xffff;
dkato 0:f782d9c66c49 296 // set channel match to percentage
dkato 0:f782d9c66c49 297 if (value == 1.0f) {
dkato 0:f782d9c66c49 298 *MTU2_PWM_MATCH[tmp_pwm][MTU2_PULSE] = (uint16_t)(wk_cycle - 1);
dkato 0:f782d9c66c49 299 } else {
dkato 0:f782d9c66c49 300 *MTU2_PWM_MATCH[tmp_pwm][MTU2_PULSE] = (uint16_t)((float)wk_cycle * value);
dkato 0:f782d9c66c49 301 }
dkato 0:f782d9c66c49 302 #endif
dkato 0:f782d9c66c49 303 } else {
dkato 0:f782d9c66c49 304 #ifdef FUNC_MOTOR_CTL_PWM
dkato 0:f782d9c66c49 305 uint16_t v;
dkato 0:f782d9c66c49 306
dkato 0:f782d9c66c49 307 /* PWM */
dkato 0:f782d9c66c49 308 if (value < 0.0f) {
dkato 0:f782d9c66c49 309 value = 0.0f;
dkato 0:f782d9c66c49 310 } else if (value > 1.0f) {
dkato 0:f782d9c66c49 311 value = 1.0f;
dkato 0:f782d9c66c49 312 } else {
dkato 0:f782d9c66c49 313 // Do Nothing
dkato 0:f782d9c66c49 314 }
dkato 0:f782d9c66c49 315
dkato 0:f782d9c66c49 316 if (obj->ch == 2) {
dkato 0:f782d9c66c49 317 wk_cycle = PWMPWCYR_2 & 0x03ff;
dkato 0:f782d9c66c49 318 } else {
dkato 0:f782d9c66c49 319 wk_cycle = PWMPWCYR_1 & 0x03ff;
dkato 0:f782d9c66c49 320 }
dkato 0:f782d9c66c49 321
dkato 0:f782d9c66c49 322 // set channel match to percentage
dkato 0:f782d9c66c49 323 v = (uint16_t)((float)wk_cycle * value);
dkato 0:f782d9c66c49 324 *PWM_MATCH[obj->pwm] = (v | ((PORT[obj->pwm] & 1) << 12));
dkato 0:f782d9c66c49 325 #endif
dkato 0:f782d9c66c49 326 }
dkato 0:f782d9c66c49 327 }
dkato 0:f782d9c66c49 328
dkato 0:f782d9c66c49 329 float pwmout_read(pwmout_t* obj) {
dkato 0:f782d9c66c49 330 uint32_t wk_cycle;
dkato 0:f782d9c66c49 331 float value;
dkato 0:f782d9c66c49 332
dkato 0:f782d9c66c49 333 if (obj->pwm >= MTU2_PWM_OFFSET) {
dkato 0:f782d9c66c49 334 #ifdef FUMC_MTU2_PWM
dkato 0:f782d9c66c49 335 /* PWM by MTU2 */
dkato 0:f782d9c66c49 336 uint32_t wk_pulse;
dkato 0:f782d9c66c49 337 int tmp_pwm;
dkato 0:f782d9c66c49 338
dkato 0:f782d9c66c49 339 tmp_pwm = (int)(obj->pwm - MTU2_PWM_OFFSET);
dkato 0:f782d9c66c49 340 wk_cycle = *MTU2_PWM_MATCH[tmp_pwm][MTU2_PERIOD] & 0xffff;
dkato 0:f782d9c66c49 341 wk_pulse = *MTU2_PWM_MATCH[tmp_pwm][MTU2_PULSE] & 0xffff;
dkato 0:f782d9c66c49 342 value = ((float)wk_pulse / (float)wk_cycle);
dkato 0:f782d9c66c49 343 #endif
dkato 0:f782d9c66c49 344 } else {
dkato 0:f782d9c66c49 345 #ifdef FUNC_MOTOR_CTL_PWM
dkato 0:f782d9c66c49 346 /* PWM */
dkato 0:f782d9c66c49 347 if (obj->ch == 2) {
dkato 0:f782d9c66c49 348 wk_cycle = PWMPWCYR_2 & 0x03ff;
dkato 0:f782d9c66c49 349 } else {
dkato 0:f782d9c66c49 350 wk_cycle = PWMPWCYR_1 & 0x03ff;
dkato 0:f782d9c66c49 351 }
dkato 0:f782d9c66c49 352 value = ((float)(*PWM_MATCH[obj->pwm] & 0x03ff) / (float)wk_cycle);
dkato 0:f782d9c66c49 353 #endif
dkato 0:f782d9c66c49 354 }
dkato 0:f782d9c66c49 355
dkato 0:f782d9c66c49 356 return (value > 1.0f) ? (1.0f) : (value);
dkato 0:f782d9c66c49 357 }
dkato 0:f782d9c66c49 358
dkato 0:f782d9c66c49 359 void pwmout_period(pwmout_t* obj, float seconds) {
dkato 0:f782d9c66c49 360 pwmout_period_us(obj, seconds * 1000000.0f);
dkato 0:f782d9c66c49 361 }
dkato 0:f782d9c66c49 362
dkato 0:f782d9c66c49 363 void pwmout_period_ms(pwmout_t* obj, int ms) {
dkato 0:f782d9c66c49 364 pwmout_period_us(obj, ms * 1000);
dkato 0:f782d9c66c49 365 }
dkato 0:f782d9c66c49 366
dkato 0:f782d9c66c49 367 #ifdef FUNC_MOTOR_CTL_PWM
dkato 0:f782d9c66c49 368 static void set_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle){
dkato 0:f782d9c66c49 369 uint16_t wk_pwmpbfr;
dkato 0:f782d9c66c49 370 float value;
dkato 0:f782d9c66c49 371 uint16_t v;
dkato 0:f782d9c66c49 372
dkato 0:f782d9c66c49 373 wk_pwmpbfr = *p_pwmpbfr;
dkato 0:f782d9c66c49 374 value = ((float)(wk_pwmpbfr & 0x03ff) / (float)last_cycle);
dkato 0:f782d9c66c49 375 v = (uint16_t)((float)new_cycle * value);
dkato 0:f782d9c66c49 376 *p_pwmpbfr = (v | (wk_pwmpbfr & 0x1000));
dkato 0:f782d9c66c49 377 }
dkato 0:f782d9c66c49 378 #endif
dkato 0:f782d9c66c49 379
dkato 0:f782d9c66c49 380 #ifdef FUMC_MTU2_PWM
dkato 0:f782d9c66c49 381 static void set_mtu2_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle){
dkato 0:f782d9c66c49 382 uint16_t wk_pwmpbfr;
dkato 0:f782d9c66c49 383 float value;
dkato 0:f782d9c66c49 384
dkato 0:f782d9c66c49 385 wk_pwmpbfr = *p_pwmpbfr;
dkato 0:f782d9c66c49 386 value = ((float)(wk_pwmpbfr & 0xffff) / (float)last_cycle);
dkato 0:f782d9c66c49 387 *p_pwmpbfr = (uint16_t)((float)new_cycle * value);
dkato 0:f782d9c66c49 388 }
dkato 0:f782d9c66c49 389 #endif
dkato 0:f782d9c66c49 390
dkato 0:f782d9c66c49 391 // Set the PWM period, keeping the duty cycle the same.
dkato 0:f782d9c66c49 392 void pwmout_period_us(pwmout_t* obj, int us) {
dkato 0:f782d9c66c49 393 uint32_t pclk_base;
dkato 0:f782d9c66c49 394 uint32_t wk_cycle;
dkato 0:f782d9c66c49 395 uint32_t wk_cks = 0;
dkato 0:f782d9c66c49 396 uint16_t wk_last_cycle;
dkato 0:f782d9c66c49 397
dkato 0:f782d9c66c49 398 if (obj->pwm >= MTU2_PWM_OFFSET) {
dkato 0:f782d9c66c49 399 #ifdef FUMC_MTU2_PWM
dkato 0:f782d9c66c49 400 uint64_t wk_cycle_mtu2;
dkato 0:f782d9c66c49 401 int max_us = 0;
dkato 0:f782d9c66c49 402
dkato 0:f782d9c66c49 403 /* PWM by MTU2 */
dkato 0:f782d9c66c49 404 int tmp_pwm;
dkato 0:f782d9c66c49 405 uint8_t tmp_tcr_up;
dkato 0:f782d9c66c49 406 uint8_t tmp_tstr_sp;
dkato 0:f782d9c66c49 407 uint8_t tmp_tstr_st;
dkato 0:f782d9c66c49 408
dkato 0:f782d9c66c49 409 max_us = MAX_PERIOD[obj->ch];
dkato 0:f782d9c66c49 410 if (us > max_us) {
dkato 0:f782d9c66c49 411 us = max_us;
dkato 0:f782d9c66c49 412 } else if (us < 1) {
dkato 0:f782d9c66c49 413 us = 1;
dkato 0:f782d9c66c49 414 } else {
dkato 0:f782d9c66c49 415 // Do Nothing
dkato 0:f782d9c66c49 416 }
dkato 0:f782d9c66c49 417
dkato 0:f782d9c66c49 418 if (RZ_A1_IsClockMode0() == false) {
dkato 0:f782d9c66c49 419 pclk_base = (uint32_t)CM1_RENESAS_RZ_A1_P0_CLK;
dkato 0:f782d9c66c49 420 } else {
dkato 0:f782d9c66c49 421 pclk_base = (uint32_t)CM0_RENESAS_RZ_A1_P0_CLK;
dkato 0:f782d9c66c49 422 }
dkato 0:f782d9c66c49 423
dkato 0:f782d9c66c49 424 wk_cycle_mtu2 = (uint64_t)pclk_base * us;
dkato 0:f782d9c66c49 425 while (wk_cycle_mtu2 >= 65535000000) {
dkato 0:f782d9c66c49 426 if ((obj->ch == 1) && (wk_cks == 3)) {
dkato 0:f782d9c66c49 427 wk_cks+=2;
dkato 0:f782d9c66c49 428 } else if ((obj->ch == 2) && (wk_cks == 3)) {
dkato 0:f782d9c66c49 429 wk_cycle_mtu2 >>= 2;
dkato 0:f782d9c66c49 430 wk_cks+=3;
dkato 0:f782d9c66c49 431 }
dkato 0:f782d9c66c49 432 wk_cycle_mtu2 >>= 2;
dkato 0:f782d9c66c49 433 wk_cks++;
dkato 0:f782d9c66c49 434 }
dkato 0:f782d9c66c49 435 wk_cycle = (uint32_t)(wk_cycle_mtu2 / 1000000);
dkato 0:f782d9c66c49 436
dkato 0:f782d9c66c49 437 tmp_pwm = (int)(obj->pwm - MTU2_PWM_OFFSET);
dkato 0:f782d9c66c49 438 if (((uint8_t)MTU2_PORT[tmp_pwm] & 0x02) == 0x02) {
dkato 0:f782d9c66c49 439 tmp_tcr_up = 0xC0;
dkato 0:f782d9c66c49 440 } else {
dkato 0:f782d9c66c49 441 tmp_tcr_up = 0x40;
dkato 0:f782d9c66c49 442 }
dkato 0:f782d9c66c49 443 if ((obj->ch == 4) || (obj->ch == 3)) {
dkato 0:f782d9c66c49 444 tmp_tstr_sp = ~(0x38 | (1 << (obj->ch + 3)));
dkato 0:f782d9c66c49 445 tmp_tstr_st = (1 << (obj->ch + 3));
dkato 0:f782d9c66c49 446 } else {
dkato 0:f782d9c66c49 447 tmp_tstr_sp = ~(0x38 | (1 << obj->ch));
dkato 0:f782d9c66c49 448 tmp_tstr_st = (1 << obj->ch);
dkato 0:f782d9c66c49 449 }
dkato 0:f782d9c66c49 450 // Counter Stop
dkato 0:f782d9c66c49 451 MTU2TSTR &= tmp_tstr_sp;
dkato 0:f782d9c66c49 452 wk_last_cycle = *MTU2_PWM_MATCH[tmp_pwm][MTU2_PERIOD] & 0xffff;
dkato 0:f782d9c66c49 453 *TCR_MATCH[obj->ch] = tmp_tcr_up | wk_cks;
dkato 0:f782d9c66c49 454 *TIORH_MATCH[obj->ch] = 0x21;
dkato 0:f782d9c66c49 455 if ((obj->ch == 0) || (obj->ch == 3) || (obj->ch == 4)) {
dkato 0:f782d9c66c49 456 *TIORL_MATCH[obj->ch] = 0x21;
dkato 0:f782d9c66c49 457 }
dkato 0:f782d9c66c49 458 *MTU2_PWM_MATCH[tmp_pwm][MTU2_PERIOD] = (uint16_t)wk_cycle; // Set period
dkato 0:f782d9c66c49 459
dkato 0:f782d9c66c49 460 // Set duty again(TGRA)
dkato 0:f782d9c66c49 461 set_mtu2_duty_again(TGRA_MATCH[obj->ch], wk_last_cycle, wk_cycle);
dkato 0:f782d9c66c49 462 if ((obj->ch == 0) || (obj->ch == 3) || (obj->ch == 4)) {
dkato 0:f782d9c66c49 463 // Set duty again(TGRC)
dkato 0:f782d9c66c49 464 set_mtu2_duty_again(TGRC_MATCH[obj->ch], wk_last_cycle, wk_cycle);
dkato 0:f782d9c66c49 465 }
dkato 0:f782d9c66c49 466 *TMDR_MATCH[obj->ch] = 0x02; // PWM mode 1
dkato 0:f782d9c66c49 467
dkato 0:f782d9c66c49 468 // Counter Start
dkato 0:f782d9c66c49 469 MTU2TSTR |= tmp_tstr_st;
dkato 0:f782d9c66c49 470 // Save for future use
dkato 0:f782d9c66c49 471 mtu2_period_ch[obj->ch] = us;
dkato 0:f782d9c66c49 472 #endif
dkato 0:f782d9c66c49 473 } else {
dkato 0:f782d9c66c49 474 #ifdef FUNC_MOTOR_CTL_PWM
dkato 0:f782d9c66c49 475 /* PWM */
dkato 0:f782d9c66c49 476 if (us > 491) {
dkato 0:f782d9c66c49 477 us = 491;
dkato 0:f782d9c66c49 478 } else if (us < 1) {
dkato 0:f782d9c66c49 479 us = 1;
dkato 0:f782d9c66c49 480 } else {
dkato 0:f782d9c66c49 481 // Do Nothing
dkato 0:f782d9c66c49 482 }
dkato 0:f782d9c66c49 483
dkato 0:f782d9c66c49 484 if (RZ_A1_IsClockMode0() == false) {
dkato 0:f782d9c66c49 485 pclk_base = (uint32_t)CM1_RENESAS_RZ_A1_P0_CLK / 10000;
dkato 0:f782d9c66c49 486 } else {
dkato 0:f782d9c66c49 487 pclk_base = (uint32_t)CM0_RENESAS_RZ_A1_P0_CLK / 10000;
dkato 0:f782d9c66c49 488 }
dkato 0:f782d9c66c49 489
dkato 0:f782d9c66c49 490 wk_cycle = pclk_base * us;
dkato 0:f782d9c66c49 491 while (wk_cycle >= 102350) {
dkato 0:f782d9c66c49 492 wk_cycle >>= 1;
dkato 0:f782d9c66c49 493 wk_cks++;
dkato 0:f782d9c66c49 494 }
dkato 0:f782d9c66c49 495 wk_cycle = (wk_cycle + 50) / 100;
dkato 0:f782d9c66c49 496
dkato 0:f782d9c66c49 497 if (obj->ch == 2) {
dkato 0:f782d9c66c49 498 wk_last_cycle = PWMPWCYR_2 & 0x03ff;
dkato 0:f782d9c66c49 499 PWMPWCR_2_BYTE_L = 0xc0 | wk_cks;
dkato 0:f782d9c66c49 500 PWMPWCYR_2 = (uint16_t)wk_cycle;
dkato 0:f782d9c66c49 501
dkato 0:f782d9c66c49 502 // Set duty again
dkato 0:f782d9c66c49 503 set_duty_again(&PWMPWBFR_2A, wk_last_cycle, wk_cycle);
dkato 0:f782d9c66c49 504 set_duty_again(&PWMPWBFR_2C, wk_last_cycle, wk_cycle);
dkato 0:f782d9c66c49 505 set_duty_again(&PWMPWBFR_2E, wk_last_cycle, wk_cycle);
dkato 0:f782d9c66c49 506 set_duty_again(&PWMPWBFR_2G, wk_last_cycle, wk_cycle);
dkato 0:f782d9c66c49 507
dkato 0:f782d9c66c49 508 // Counter Start
dkato 0:f782d9c66c49 509 PWMPWCR_2_BYTE_L |= 0x08;
dkato 0:f782d9c66c49 510
dkato 0:f782d9c66c49 511 // Save for future use
dkato 0:f782d9c66c49 512 period_ch2 = us;
dkato 0:f782d9c66c49 513 } else {
dkato 0:f782d9c66c49 514 wk_last_cycle = PWMPWCYR_1 & 0x03ff;
dkato 0:f782d9c66c49 515 PWMPWCR_1_BYTE_L = 0xc0 | wk_cks;
dkato 0:f782d9c66c49 516 PWMPWCYR_1 = (uint16_t)wk_cycle;
dkato 0:f782d9c66c49 517
dkato 0:f782d9c66c49 518 // Set duty again
dkato 0:f782d9c66c49 519 set_duty_again(&PWMPWBFR_1A, wk_last_cycle, wk_cycle);
dkato 0:f782d9c66c49 520 set_duty_again(&PWMPWBFR_1C, wk_last_cycle, wk_cycle);
dkato 0:f782d9c66c49 521 set_duty_again(&PWMPWBFR_1E, wk_last_cycle, wk_cycle);
dkato 0:f782d9c66c49 522 set_duty_again(&PWMPWBFR_1G, wk_last_cycle, wk_cycle);
dkato 0:f782d9c66c49 523
dkato 0:f782d9c66c49 524 // Counter Start
dkato 0:f782d9c66c49 525 PWMPWCR_1_BYTE_L |= 0x08;
dkato 0:f782d9c66c49 526
dkato 0:f782d9c66c49 527 // Save for future use
dkato 0:f782d9c66c49 528 period_ch1 = us;
dkato 0:f782d9c66c49 529 }
dkato 0:f782d9c66c49 530 #endif
dkato 0:f782d9c66c49 531 }
dkato 0:f782d9c66c49 532 }
dkato 0:f782d9c66c49 533
dkato 0:f782d9c66c49 534 void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
dkato 0:f782d9c66c49 535 pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
dkato 0:f782d9c66c49 536 }
dkato 0:f782d9c66c49 537
dkato 0:f782d9c66c49 538 void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
dkato 0:f782d9c66c49 539 pwmout_pulsewidth_us(obj, ms * 1000);
dkato 0:f782d9c66c49 540 }
dkato 0:f782d9c66c49 541
dkato 0:f782d9c66c49 542 void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
dkato 0:f782d9c66c49 543 float value = 0;
dkato 0:f782d9c66c49 544
dkato 0:f782d9c66c49 545 if (obj->pwm >= MTU2_PWM_OFFSET) {
dkato 0:f782d9c66c49 546 #ifdef FUMC_MTU2_PWM
dkato 0:f782d9c66c49 547 /* PWM by MTU2 */
dkato 0:f782d9c66c49 548 if (mtu2_period_ch[obj->ch] != 0) {
dkato 0:f782d9c66c49 549 value = (float)us / (float)mtu2_period_ch[obj->ch];
dkato 0:f782d9c66c49 550 }
dkato 0:f782d9c66c49 551 #endif
dkato 0:f782d9c66c49 552 } else {
dkato 0:f782d9c66c49 553 #ifdef FUNC_MOTOR_CTL_PWM
dkato 0:f782d9c66c49 554 /* PWM */
dkato 0:f782d9c66c49 555 if (obj->ch == 2) {
dkato 0:f782d9c66c49 556 if (period_ch2 != 0) {
dkato 0:f782d9c66c49 557 value = (float)us / (float)period_ch2;
dkato 0:f782d9c66c49 558 }
dkato 0:f782d9c66c49 559 } else {
dkato 0:f782d9c66c49 560 if (period_ch1 != 0) {
dkato 0:f782d9c66c49 561 value = (float)us / (float)period_ch1;
dkato 0:f782d9c66c49 562 }
dkato 0:f782d9c66c49 563 }
dkato 0:f782d9c66c49 564 #endif
dkato 0:f782d9c66c49 565 }
dkato 0:f782d9c66c49 566 pwmout_write(obj, value);
dkato 0:f782d9c66c49 567 }