mbed-os/targets/TARGET_RENESAS/TARGET_RZ_A2XX/pwmout_api.c

209 lines
5.7 KiB
C

/* mbed Microcontroller Library
* Copyright (c) 2006-2020 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if DEVICE_PWMOUT
#include "mbed_assert.h"
#include "pwmout_api.h"
#include "cmsis.h"
#include "PeripheralPins.h"
#include "RZ_A2_Init.h"
#include "iodefine.h"
#include "gpio_addrdefine.h"
#include "mbed_drv_cfg.h"
static const volatile struct st_gpt32e *GPT32E[] = {
&GPT32E0, &GPT32E1, &GPT32E2, &GPT32E3,
&GPT32E4, &GPT32E5, &GPT32E6, &GPT32E7
};
void pwmout_init(pwmout_t *obj, PinName pin)
{
// determine the channel
PWMName index = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
MBED_ASSERT(index != (PWMName)NC);
CPG.STBCR3.BIT.MSTP30 = 0;
pinmap_pinout(pin, PinMap_PWM);
obj->index = index;
obj->type = (index & 0x01);
obj->pwm = (volatile struct st_gpt32e *)GPT32E[(index >> 1)];
obj->duty = 0.0f;
/* Set operating mode : saw-wave PWM mode */
obj->pwm->GTCR.BIT.MD = 0x0;
/* Set count direction : up */
obj->pwm->GTUDDTYC.BIT.UDF = 0x1;
obj->pwm->GTUDDTYC.BIT.UD = 0x1;
obj->pwm->GTUDDTYC.BIT.UDF = 0x0;
pwmout_period_us(obj, 1000);
if (obj->type == 0) {
obj->pwm->GTIOR.BIT.GTIOA = 0x19; /* Set GTIOC pin function */
obj->pwm->GTBER.BIT.CCRA = 0x01; /* Set buffer operation : Single buffer operation */
obj->pwm->GTCCRA.LONG = 0; /* Set compare match value */
obj->pwm->GTIOR.BIT.OAE = 0x1; /* Enable GTIOC pin output */
} else {
obj->pwm->GTIOR.BIT.GTIOB = 0x19; /* Set GTIOC pin function */
obj->pwm->GTBER.BIT.CCRB = 0x01; /* Set buffer operation : Single buffer operation */
obj->pwm->GTCCRB.LONG = 0; /* Set compare match value */
obj->pwm->GTIOR.BIT.OBE = 0x1; /* Enable GTIOC pin output */
}
/* Start count operation */
obj->pwm->GTCR.BIT.CST = 0x01;
}
void pwmout_free(pwmout_t *obj)
{
pwmout_write(obj, 0);
}
void pwmout_write(pwmout_t *obj, float value)
{
if (value < 0.0f) {
value = 0.0f;
} else if (value > 1.0f) {
value = 1.0f;
} else {
// Do Nothing
}
obj->duty = value;
if (obj->type == 0) {
obj->pwm->GTCCRC.LONG = obj->pwm->GTPR.LONG * value; /* Set buffer value */
obj->pwm->GTUDDTYC.BIT.OADTYF = 0x1;
if (value == 0.0f) {
obj->pwm->GTUDDTYC.BIT.OADTY = 0x2;
} else if (value == 1.0f) {
obj->pwm->GTUDDTYC.BIT.OADTY = 0x3;
} else {
obj->pwm->GTUDDTYC.BIT.OADTY = 0x0;
}
obj->pwm->GTUDDTYC.BIT.OADTYF = 0x0;
} else {
obj->pwm->GTCCRE.LONG = obj->pwm->GTPR.LONG * value; /* Set buffer value */
obj->pwm->GTUDDTYC.BIT.OBDTYF = 0x1;
if (value == 0.0f) {
obj->pwm->GTUDDTYC.BIT.OBDTY = 0x2;
} else if (value == 1.0f) {
obj->pwm->GTUDDTYC.BIT.OBDTY = 0x3;
} else {
obj->pwm->GTUDDTYC.BIT.OBDTY = 0x0;
}
obj->pwm->GTUDDTYC.BIT.OBDTYF = 0x0;
}
}
float pwmout_read(pwmout_t *obj)
{
float value;
if (obj->type == 0) {
value = (float)obj->pwm->GTCCRC.LONG / (float)obj->pwm->GTPR.LONG;
} else {
value = (float)obj->pwm->GTCCRE.LONG / (float)obj->pwm->GTPR.LONG;
}
return (value > 1.0f) ? (1.0f) : (value);
}
void pwmout_period(pwmout_t *obj, float seconds)
{
pwmout_period_us(obj, seconds * 1000000.0f);
}
void pwmout_period_ms(pwmout_t *obj, int ms)
{
pwmout_period_us(obj, ms * 1000);
}
// Set the PWM period, keeping the duty cycle the same.
void pwmout_period_us(pwmout_t *obj, int us)
{
uint32_t pclk_base;
uint32_t wk_cycle;
if (RZ_A2_IsClockMode0() == false) {
pclk_base = (uint32_t)CM1_RENESAS_RZ_A2_P1_CLK / 1000000;
} else {
pclk_base = (uint32_t)CM0_RENESAS_RZ_A2_P1_CLK / 1000000;
}
uint32_t us_max = 0xFFFFFFFF / pclk_base;
if ((uint32_t)us > us_max) {
us = us_max;
} else if (us < 1) {
us = 1;
} else {
// Do Nothing
}
wk_cycle = pclk_base * us;
obj->pwm->GTCR.BIT.TPCS = 0x0; /* Select count clock */
obj->pwm->GTPR.LONG = wk_cycle - 1; /* Set cycle */
obj->pwm->GTCNT.LONG = 0; /* Set initial value for counter */
/* set duty again */
pwmout_write(obj, obj->duty);
}
int pwmout_read_period_us(pwmout_t *obj)
{
return obj->pwm->GTPR.LONG;
}
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
{
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
}
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
{
pwmout_pulsewidth_us(obj, ms * 1000);
}
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
{
float value = 0;
if (RZ_A2_IsClockMode0() == false) {
value = (float)(us * ((uint32_t)CM0_RENESAS_RZ_A2_P0_CLK / 1000000)) / (float)(obj->pwm->GTPR.LONG + 1);
} else {
value = (float)(us * ((uint32_t)CM1_RENESAS_RZ_A2_P0_CLK / 1000000)) / (float)(obj->pwm->GTPR.LONG + 1);
}
pwmout_write(obj, value);
}
int pwmout_read_pulsewidth_us(pwmout_t *obj)
{
if (obj->type == 0) {
return (float)obj->pwm->GTCCRC.LONG;
}
return (float)obj->pwm->GTCCRE.LONG ;
}
const PinMap *pwmout_pinmap()
{
return PinMap_PWM;
}
#endif