mirror of
https://github.com/elua/elua.git
synced 2025-01-08 20:56:17 +08:00
Partial PWM implementation for lpc17xx.
This commit is contained in:
parent
a3eb58211d
commit
b79ed03629
@ -46,6 +46,10 @@
|
||||
/* TIMER ------------------------------- */
|
||||
#define _TIM
|
||||
|
||||
/* PWM ------------------------------- */
|
||||
#define _PWM 1
|
||||
#define _PWM1 1
|
||||
|
||||
/************************** GLOBAL/PUBLIC MACRO DEFINITIONS *********************************/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "lpc17xx_uart.h"
|
||||
#include "lpc17xx_timer.h"
|
||||
#include "lpc17xx_clkpwr.h"
|
||||
#include "lpc17xx_pwm.h"
|
||||
|
||||
// ****************************************************************************
|
||||
// Platform initialization
|
||||
@ -325,93 +326,70 @@ void platform_cpu_disable_interrupts()
|
||||
{
|
||||
__disable_irq();
|
||||
}
|
||||
/*
|
||||
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// PWM functions
|
||||
|
||||
static const u32 pwm_tcr[] = { ( u32 )&PWM0TCR, ( u32 )&PWM1TCR };
|
||||
static const u32 pwm_pr[] = { ( u32 )&PWM0PR, ( u32 )&PWM1PR };
|
||||
static const u32 pwm_pc[] = { ( u32 )&PWM0PC, ( u32 )&PWM1PC };
|
||||
static const u32 pwm_pcr[] = { ( u32 )&PWM0PCR, ( u32 )&PWM1PCR };
|
||||
static const u32 pwm_mcr[] = { ( u32 )&PWM0MCR, ( u32 )&PWM1MCR };
|
||||
static const u32 pwm_ler[] = { ( u32 )&PWM0LER, ( u32 )&PWM1LER };
|
||||
static const u32 pwm_channels[ 2 ][ 6 ] =
|
||||
{
|
||||
{ ( u32 )&PWM0MR1, ( u32 )&PWM0MR2, ( u32 )&PWM0MR3, ( u32 )&PWM0MR4, ( u32 )&PWM0MR5, ( u32 )&PWM0MR6 },
|
||||
{ ( u32 )&PWM1MR1, ( u32 )&PWM1MR2, ( u32 )&PWM1MR3, ( u32 )&PWM1MR4, ( u32 )&PWM1MR5, ( u32 )&PWM1MR6 },
|
||||
};
|
||||
|
||||
// Timer register definitions
|
||||
enum
|
||||
{
|
||||
PWM_ENABLE = 1,
|
||||
PWM_RESET = 2,
|
||||
PWM_MODE = 8,
|
||||
PWM_ENABLE_1 = 1 << 9,
|
||||
PWM_ENABLE_2 = 1 << 10,
|
||||
PWM_ENABLE_3 = 1 << 11,
|
||||
PWM_ENABLE_4 = 1 << 12,
|
||||
PWM_ENABLE_5 = 1 << 13,
|
||||
PWM_ENABLE_6 = 1 << 14,
|
||||
};
|
||||
|
||||
// Helper function: get timer clock
|
||||
static u32 platform_pwm_get_clock( unsigned id )
|
||||
{
|
||||
unsigned pwmid = id / 6;
|
||||
PREG PWMxPR = ( PREG )pwm_pr[ pwmid ];
|
||||
|
||||
return Fpclk / ( *PWMxPR + 1 );
|
||||
return CLKPWR_GetPCLK( CLKPWR_PCLKSEL_PWM1 ) / ( PWM1->PR + 1 );
|
||||
}
|
||||
|
||||
// Helper function: set timer clock
|
||||
static u32 platform_pwm_set_clock( unsigned id, u32 clock )
|
||||
{
|
||||
u32 div = Fpclk / clock, prevtc;
|
||||
unsigned pwmid = id / 6;
|
||||
PREG PWMxPR = ( PREG )pwm_pr[ pwmid ];
|
||||
PREG PWMxPC = ( PREG )pwm_pc[ pwmid ];
|
||||
PREG PWMxTCR = ( PREG )pwm_tcr[ pwmid ];
|
||||
PWM_TIMERCFG_Type PWMCfgDat;
|
||||
|
||||
prevtc = *PWMxTCR;
|
||||
*PWMxTCR = 0;
|
||||
*PWMxPC = 0;
|
||||
*PWMxPR = div - 1;
|
||||
*PWMxTCR = prevtc;
|
||||
return Fpclk / div;
|
||||
PWMCfgDat.PrescaleOption = PWM_TIMER_PRESCALE_USVAL;
|
||||
PWMCfgDat.PrescaleValue = 1000000ULL / clock;
|
||||
PWM_Init(PWM1, PWM_MODE_TIMER, &PWMCfgDat);
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
||||
// Setup all PWM channels
|
||||
static void platform_setup_pwm()
|
||||
{
|
||||
unsigned i;
|
||||
PREG temp;
|
||||
PWM_TIMERCFG_Type PWMCfgDat;
|
||||
PWM_MATCHCFG_Type PWMMatchCfgDat;
|
||||
|
||||
// Keep clock in reset, set PWM code
|
||||
PWM_ResetCounter(PWM1);
|
||||
|
||||
// Set match mode (reset on MR0 match)
|
||||
PWMMatchCfgDat.IntOnMatch = DISABLE;
|
||||
PWMMatchCfgDat.MatchChannel = 0;
|
||||
PWMMatchCfgDat.ResetOnMatch = ENABLE;
|
||||
PWMMatchCfgDat.StopOnMatch = DISABLE;
|
||||
PWM_ConfigMatch(PWM1, &PWMMatchCfgDat);
|
||||
|
||||
for( i = 0; i < 2; i ++ )
|
||||
{
|
||||
// Keep clock in reset, set PWM code
|
||||
temp = ( PREG )pwm_tcr[ i ];
|
||||
*temp = PWM_RESET;
|
||||
// Set match mode (reset on MR0 match)
|
||||
temp = ( PREG )pwm_mcr[ i ];
|
||||
*temp = 0x02;
|
||||
// Set base frequency to 1MHz
|
||||
platform_pwm_set_clock( i * 6, 1000000 );
|
||||
}
|
||||
// Set base frequency to 1MHz
|
||||
platform_pwm_set_clock( 0, 1000000 );
|
||||
}
|
||||
|
||||
u32 platform_pwm_setup( unsigned id, u32 frequency, unsigned duty )
|
||||
{
|
||||
unsigned pwmid = id / 6, chid = id % 6;
|
||||
PREG PWMxMR0 = pwmid == 0 ? ( PREG )&PWM0MR0 : ( PREG )&PWM1MR0;
|
||||
PREG PWMxMRc = ( PREG )pwm_channels[ pwmid ][ chid ];
|
||||
PREG PWMxLER = ( PREG )pwm_ler[ pwmid ];
|
||||
u32 divisor;
|
||||
|
||||
divisor = platform_pwm_get_clock( id ) / frequency - 1;
|
||||
*PWMxMR0 = divisor;
|
||||
*PWMxMRc = ( divisor * duty ) / 100;
|
||||
*PWMxLER = 1 | ( 1 << ( chid + 1 ) );
|
||||
PWM_MATCHCFG_Type PWMMatchCfgDat;
|
||||
PINSEL_CFG_Type PinCfg;
|
||||
u32 divisor = platform_pwm_get_clock( id ) / frequency - 1;
|
||||
|
||||
PWM_MatchUpdate(PWM1, 0, divisor, PWM_MATCH_UPDATE_NOW); // PWM1 cycle rate
|
||||
PWM_MatchUpdate(PWM1, id, ( divisor * duty ) / 100, PWM_MATCH_UPDATE_NOW); // PWM1 channel edge position
|
||||
|
||||
if ( id > 1 ) // Channel one is permanently single-edge
|
||||
PWM_ChannelConfig( PWM1, id, PWM_CHANNEL_SINGLE_EDGE );
|
||||
|
||||
PWMMatchCfgDat.IntOnMatch = DISABLE;
|
||||
PWMMatchCfgDat.MatchChannel = id;
|
||||
PWMMatchCfgDat.ResetOnMatch = DISABLE;
|
||||
PWMMatchCfgDat.StopOnMatch = DISABLE;
|
||||
PWM_ConfigMatch(PWM1, &PWMMatchCfgDat);
|
||||
|
||||
PWM_ChannelCmd(PWM1, id, ENABLE);
|
||||
|
||||
return platform_pwm_get_clock( id ) / divisor;
|
||||
}
|
||||
@ -419,20 +397,15 @@ u32 platform_pwm_setup( unsigned id, u32 frequency, unsigned duty )
|
||||
u32 platform_pwm_op( unsigned id, int op, u32 data )
|
||||
{
|
||||
u32 res = 0;
|
||||
unsigned pwmid = id / 6;
|
||||
PREG PWMxTCR = ( PREG )pwm_tcr[ pwmid ];
|
||||
PREG PWMxPCR = ( PREG )pwm_pcr[ pwmid ];
|
||||
|
||||
switch( op )
|
||||
{
|
||||
case PLATFORM_PWM_OP_START:
|
||||
*PWMxPCR = PWM_ENABLE_1 | PWM_ENABLE_2 | PWM_ENABLE_3 | PWM_ENABLE_4 | PWM_ENABLE_5 | PWM_ENABLE_6;
|
||||
*PWMxTCR = PWM_ENABLE | PWM_MODE;
|
||||
PWM_Cmd(PWM1, ENABLE);
|
||||
break;
|
||||
|
||||
case PLATFORM_PWM_OP_STOP:
|
||||
*PWMxPCR = 0;
|
||||
*PWMxTCR = PWM_RESET;
|
||||
PWM_Cmd(PWM1, DISABLE);
|
||||
break;
|
||||
|
||||
case PLATFORM_PWM_OP_SET_CLOCK:
|
||||
@ -447,8 +420,6 @@ u32 platform_pwm_op( unsigned id, int op, u32 data )
|
||||
return res;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// ****************************************************************************
|
||||
// Platform specific modules go here
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
_ROM( AUXLIB_PACK, luaopen_pack, pack_map )\
|
||||
_ROM( AUXLIB_BIT, luaopen_bit, bit_map )\
|
||||
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map )\
|
||||
_ROM( AUXLIB_PWM, luaopen_pwm, pwm_map )\
|
||||
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )\
|
||||
_ROM( PS_LIB_TABLE_NAME, luaopen_platform, platform_map )
|
||||
|
||||
@ -54,7 +55,7 @@
|
||||
#define NUM_PIO 5
|
||||
#define NUM_SPI 0
|
||||
#define NUM_UART 4
|
||||
#define NUM_PWM 0
|
||||
#define NUM_PWM 6
|
||||
#define NUM_ADC 0
|
||||
#define NUM_CAN 0
|
||||
// If virtual timers are enabled, the last timer will be used only for them
|
||||
|
Loading…
x
Reference in New Issue
Block a user