WIP: PWM pin mapping.
Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
parent
eeb7b3fc6f
commit
d42b7664ac
|
@ -7,22 +7,118 @@
|
|||
#include "fsl_ctimer.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_iocon.h"
|
||||
#include "fsl_power.h"
|
||||
|
||||
/* Gem private */
|
||||
#include "machine-pwm/src/pwm.h"
|
||||
|
||||
#define PWM_IMPL_CT_ID (x)((x >> 2) & 0x07)
|
||||
/**
|
||||
* LPC55S69 has 5 CTimers, each with 4 Match channels, each channel can route up to 2 pins
|
||||
* Total: 40 PWM capable pins (at most)
|
||||
* Actual: 30 pins (shared).
|
||||
*/
|
||||
|
||||
static const uint32_t pwm_channel_map[5][4] = {
|
||||
{0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL}, // CTIMER0
|
||||
{0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL}, // CTIMER1
|
||||
{0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL}, // CTIMER2
|
||||
{0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL}, // CTIMER3
|
||||
{0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL}, // CTIMER4
|
||||
#define PWM_IMPL_INST_COUNT 5
|
||||
#define PWM_IMPL_INST_CH 4
|
||||
|
||||
/* Timer channel ID fields */
|
||||
|
||||
#define PWM_IMPL_CT_OFFSET_Pos 0
|
||||
#define PWM_IMPL_CT_OFFSET_Msk (1U << PWM_IMPL_CT_OFFSET_Pos)
|
||||
|
||||
#define PWM_IMPL_CT_CH_Pos 1
|
||||
#define PWM_IMPL_CT_CH_Msk (3U << PWM_IMPL_CT_CH_Pos)
|
||||
|
||||
#define PWM_IMPL_CT_INST_Pos 4
|
||||
#define PWM_IMPL_CT_INST_Msk (0x1FU << PWM_IMPL_CT_INST_Pos)
|
||||
|
||||
#define PWM_IMPL_CT_OFFSET(x) ((x & PWM_IMPL_CT_OFFSET_Msk) >> PWM_IMPL_CT_OFFSET_Pos)
|
||||
#define PWM_IMPL_CT_CH(x) ((x & PWM_IMPL_CT_CH_Msk) >> PWM_IMPL_CT_CH_Pos)
|
||||
#define PWM_IMPL_CT_INST(x) ((x & PWM_IMPL_CT_INST_Msk) >> PWM_IMPL_CT_INST_Pos)
|
||||
|
||||
/* Pin ID fields */
|
||||
|
||||
#define PWM_IMPL_PIN_ID_Pos 0
|
||||
#define PWM_IMPL_PIN_ID_Msk (0x1FU << PWM_IMPL_PIN_ID_Pos)
|
||||
|
||||
#define PWM_IMPL_PIN_PORT_Pos 5
|
||||
#define PWM_IMPL_PIN_PORT_Msk (7U << PWM_IMPL_PIN_PORT_Pos)
|
||||
|
||||
#define PWM_IMPL_PIN_FUNC_Pos 8
|
||||
#define PWM_IMPL_PIN_FUNC_Msk (0x0FU << PWM_IMPL_PIN_FUNC_Pos)
|
||||
|
||||
#define PWM_IMPL_PIN_VALID_Pos 31
|
||||
#define PWM_IMPL_PIN_VALID_Msk (1U << PWM_IMPL_PIN_VALID_Pos)
|
||||
|
||||
#define PWM_IMPL_PIN_PORT(x) ((x & PWM_IMPL_PIN_PORT_Msk) >> PWM_IMPL_PIN_PORT_Pos)
|
||||
#define PWM_IMPL_PIN_ID(x) ((x & PWM_IMPL_PIN_ID_Msk) >> PWM_IMPL_PIN_ID_Pos)
|
||||
#define PWM_IMPL_PIN_FUNC(x) ((x & PWM_IMPL_PIN_FUNC_Msk) >> PWM_IMPL_PIN_FUNC_Pos)
|
||||
#define PWM_IMPL_PIN_VALID(x) ((x & PWM_IMPL_PIN_VALID_Msk) >> PWM_IMPL_PIN_VALID_Pos)
|
||||
|
||||
#define PWM_IMPL_PIN(port, id, func) \
|
||||
(((port << PWM_IMPL_PIN_PORT_Pos) & PWM_IMPL_PIN_PORT_Msk) | ((id << PWM_IMPL_PIN_ID_Pos) & PWM_IMPL_PIN_ID_Msk) | \
|
||||
((func << PWM_IMPL_PIN_FUNC_Pos) & PWM_IMPL_PIN_FUNC_Msk) | PWM_IMPL_PIN_VALID_Msk)
|
||||
|
||||
static const uint32_t s_pwm_channel_map[PWM_IMPL_INST_COUNT][PWM_IMPL_INST_COUNT * 2] = {
|
||||
{
|
||||
PWM_IMPL_PIN(0, 0, 3), PWM_IMPL_PIN(0, 30, 3), // CT0MAT0, Channel ID: 0, 1
|
||||
PWM_IMPL_PIN(0, 3, 2), PWM_IMPL_PIN(0, 31, 3), // CT0MAT1, Channel ID: 2, 3
|
||||
PWM_IMPL_PIN(0, 19, 3), PWM_IMPL_PIN(1, 31, 3), // CT0MAT2, Channel ID: 4, 5
|
||||
PWM_IMPL_PIN(1, 2, 3), PWM_IMPL_PIN(1, 27, 3), // CT0MAT3, Channel ID: 6, 7
|
||||
},
|
||||
{
|
||||
PWM_IMPL_PIN(0, 18, 3), PWM_IMPL_PIN(1, 10, 3), // CT1MAT0, Channel ID: 8, 9
|
||||
PWM_IMPL_PIN(0, 20, 2), PWM_IMPL_PIN(1, 12, 3), // CT1MAT1, Channel ID: 10, 11
|
||||
PWM_IMPL_PIN(0, 23, 2), PWM_IMPL_PIN(1, 14, 3), // CT1MAT2, Channel ID: 12, 13
|
||||
PWM_IMPL_PIN(1, 16, 3), 0x00000000UL, // CT1MAT3, Channel ID: 14, 15
|
||||
},
|
||||
{
|
||||
PWM_IMPL_PIN(0, 10, 3), PWM_IMPL_PIN(1, 5, 3), // CT2MAT0, Channel ID: 16, 17
|
||||
PWM_IMPL_PIN(1, 4, 3), PWM_IMPL_PIN(1, 6, 3), // CT2MAT1, Channel ID: 18, 19
|
||||
PWM_IMPL_PIN(0, 11, 2), PWM_IMPL_PIN(1, 7, 3), // CT2MAT2, Channel ID: 20, 21
|
||||
PWM_IMPL_PIN(0, 29, 3), PWM_IMPL_PIN(1, 22, 3), // CT2MAT3, Channel ID: 22, 23
|
||||
},
|
||||
{
|
||||
PWM_IMPL_PIN(0, 5, 3), 0x00000000UL, // CT3MAT0, Channel ID: 24, 25
|
||||
PWM_IMPL_PIN(1, 19, 3), 0x00000000UL, // CT3MAT1, Channel ID: 26, 27
|
||||
PWM_IMPL_PIN(0, 27, 3), PWM_IMPL_PIN(1, 21, 3), // CT3MAT2, Channel ID: 28, 29
|
||||
PWM_IMPL_PIN(1, 22, 3), PWM_IMPL_PIN(1, 27, 3), // CT3MAT3, Channel ID: 30, 31
|
||||
},
|
||||
{
|
||||
PWM_IMPL_PIN(0, 6, 3), 0x00000000UL, // CT4MAT0, Channel ID: 32, 33
|
||||
0x00000000UL, 0x00000000UL, // CT4MAT1, Channel ID: 34, 35
|
||||
0x00000000UL, 0x00000000UL, // CT4MAT2, Channel ID: 36, 37
|
||||
0x00000000UL, 0x00000000UL, // CT4MAT3, Channel ID: 38, 39
|
||||
},
|
||||
};
|
||||
|
||||
int mrb_machine_pwm_impl_config_set(uint32_t channel, machine_pwm_config_t *config) {
|
||||
printf("Init pin: %ld, freq: %ld, duty: %d\n", channel, config->freq, config->duty);
|
||||
uint8_t ctimer_id = PWM_IMPL_CT_INST(channel);
|
||||
uint8_t ctimer_mat = PWM_IMPL_CT_CH(channel);
|
||||
uint8_t ctimer_off = PWM_IMPL_CT_OFFSET(channel);
|
||||
|
||||
/* Sanity checks */
|
||||
if ((ctimer_id >= PWM_IMPL_INST_COUNT) || (ctimer_mat >= PWM_IMPL_INST_CH)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ctimer_pin = s_pwm_channel_map[ctimer_id][ctimer_off];
|
||||
|
||||
/* Check valid bit to see if there really is a pin for this channel */
|
||||
if (PWM_IMPL_PIN_VALID(ctimer_pin) == 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* FIXME: Check CTIMER status and match channel status before setting pin mode */
|
||||
/* TODO: Set up CTIMER if not configured previously */
|
||||
/* FIXME: How to determine whether CTIMER is set up previously? Tips: CTIMER might be used by other gems... */
|
||||
|
||||
/* Function is retrieved from const array. */
|
||||
uint32_t iocon_mode = IOCON_PIO_SLEW(0) | IOCON_DIGITAL_EN | IOCON_PIO_FUNC(PWM_IMPL_PIN_FUNC(ctimer_pin));
|
||||
|
||||
/* Setup pin */
|
||||
IOCON_PinMuxSet(IOCON, PWM_IMPL_PIN_PORT(ctimer_pin), PWM_IMPL_PIN_ID(ctimer_pin), iocon_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue