diff --git a/src/platform/lpc17xx/lpc17xx_libcfg.h b/src/platform/lpc17xx/lpc17xx_libcfg.h index 1652ce9f..43a1a976 100755 --- a/src/platform/lpc17xx/lpc17xx_libcfg.h +++ b/src/platform/lpc17xx/lpc17xx_libcfg.h @@ -46,6 +46,10 @@ /* TIMER ------------------------------- */ #define _TIM +/* PWM ------------------------------- */ +#define _PWM 1 +#define _PWM1 1 + /************************** GLOBAL/PUBLIC MACRO DEFINITIONS *********************************/ #ifdef DEBUG diff --git a/src/platform/lpc17xx/platform.c b/src/platform/lpc17xx/platform.c index 91703bcc..c9d86ea8 100644 --- a/src/platform/lpc17xx/platform.c +++ b/src/platform/lpc17xx/platform.c @@ -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 diff --git a/src/platform/lpc17xx/platform_conf.h b/src/platform/lpc17xx/platform_conf.h index 6523273f..9d29fd96 100644 --- a/src/platform/lpc17xx/platform_conf.h +++ b/src/platform/lpc17xx/platform_conf.h @@ -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