Design-in of LPC11U24 (lqfp48) of mbed as Steppermotor controller with USB control.
Mbed repository of Stepper Motor Control board. Using mbed LPC11U24 chip with HID USB.
Hardware in copy repo on bitbucket https://bitbucket.org/jeroen3/stepper-motor-board
CT32B0_PWM.cpp
- Committer:
- jeroen3
- Date:
- 2013-10-28
- Revision:
- 1:e7709c579a18
- Parent:
- 0:d0306c0cbee6
File content as of revision 1:e7709c579a18:
/** * @file CT32B0_PWM.cpp * @brief Small driver to user CT32B0 for PWM * * @author Jeroen Lodder * @date Oktober 2013 * * @note Since only one timer is used to supply 4 PWM channels * a problem occurs because CT32B0 only support 3 PWM channels. * * Since this software is designed for a H-Bridge implementation * only 2 of 4 PWM channels are required to be active simultaneously. * * This is where the stage variable comes in: * Stage 0: PWM enabled on MAT 0, MAT 1 and MAT 2. * Stage 1: PWM enabled on MAT 0, MAT 1 and MAT 3. * Unused MAT outputs will be pullled down. * @{ */ #include "mbed.h" #include "CT32B0_PWM.h" // Prescaler 48 gives 1 us per tick #define CT32B0_PRESCALER 48 /**< @brief Timer prescaler from AHBCLK */ /* Static makes them private to this module */ volatile static uint8_t stage = 0; /**< @brief Stage identifier for mat2/3 swap */ volatile static uint32_t period = 0; /**< @brief PWM Period register */ volatile static uint32_t mat[4]; /**< @brief PWM Mat output registers */ volatile static uint32_t default_period_us; /**< @brief Given period in us */ volatile static uint32_t defaultstate; /**< @brief Default PWM state on init */ /** * @brief Initializes PWM * * @param[in] period_us Period in us, when prescaler is 48 * @param[in] defaultstate State after initializing * @note Run Start() to start pwm */ void CT32B0_initpwm(uint32_t period_us, uint32_t defaultstate){ // Calculte period period = period_us; // Store latest setting mat[0] = defaultstate; mat[1] = defaultstate; mat[2] = defaultstate; mat[3] = defaultstate; LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6)|(1<<9); LPC_CT32B0->IR = 0x5F; // Clear int LPC_CT32B0->TCR = 2; // Reset LPC_CT32B0->PR = CT32B0_PRESCALER; LPC_CT32B0->CCR = 0; // No capture LPC_CT32B0->EMR = 0; // Not required, refer to PWMC LPC_CT32B0->CTCR = 0; // No special counters mode // Set outputs to stage if(!stage){ // Stage 0, use MAT2 as period LPC_CT32B0->PWMC = (1<<0)|(1<<1)|(0<<2)|(1<<3); LPC_CT32B0->MCR = (1<<7); // Reset on MR2 LPC_CT32B0->MR2 = period; LPC_CT32B0->MR3 = defaultstate; LPC_GPIO->DIR[1] |= (1<<26); // Disable P1_26 LPC_GPIO->CLR[1] = (1<<26); LPC_IOCON->PIO1_26 = 0x0; // Change pin mode LPC_IOCON->PIO1_27 = 0x1; }else{ // Stage 1, use MAT3 as period LPC_CT32B0->PWMC = (1<<0)|(1<<1)|(1<<2)|(0<<3); LPC_CT32B0->MCR = (1<<10); //Reset on MR3 LPC_CT32B0->MR2 = defaultstate; LPC_CT32B0->MR3 = period; LPC_GPIO->DIR[1] |= (1<<27); // Disable P1_27 LPC_GPIO->CLR[1] = (1<<27); LPC_IOCON->PIO1_26 = 0x1; LPC_IOCON->PIO1_27 = 0x0; // Change pin mode } // MAT 1 and MAT 2 are not affected by stage LPC_CT32B0->MR0 = defaultstate; LPC_CT32B0->MR1 = defaultstate; LPC_IOCON->PIO1_24 = 0x1; // Change pin mode LPC_IOCON->PIO1_25 = 0x1; // Change pin mode LPC_CT32B0->TCR = 0; } /** * @brief Re-Initializes PWM */ void CT32B0_reinitpwm(void){ CT32B0_initpwm(default_period_us,defaultstate ); } /** * @brief Start PWM */ void CT32B0_start(void){ LPC_CT32B0->TCR = 1; // Enable } /** * @brief Stop PWM * @param[in] state PWM output state when pwm disabled */ void CT32B0_deinit(uint8_t state){ LPC_CT32B0->TCR = 2; // Disable and reset counter // Set all to GPIO LPC_IOCON->PIO1_24 = 0; LPC_IOCON->PIO1_25 = 0; LPC_IOCON->PIO1_26 = 0; LPC_IOCON->PIO1_27 = 0; LPC_GPIO->DIR[1] |= (1<<24)|(1<<25)|(1<<26)|(1<<27); if(state) LPC_GPIO->SET[1] = (1<<24)|(1<<25)|(1<<26)|(1<<27); else LPC_GPIO->CLR[1] = (1<<24)|(1<<25)|(1<<26)|(1<<27); } /** * @brief Set stage * @param[in] stagearg 1 or 0 */ void CT32B0_stage(uint8_t stagearg){ stage = stagearg; // Set outputs to stage if(!stage){ // Stage 0, use MAT2 as period LPC_CT32B0->PWMC = (1<<0)|(1<<1)|(0<<2)|(1<<3); LPC_CT32B0->MCR = (1<<7); // Reset on MR2 LPC_CT32B0->MR2 = period; LPC_CT32B0->MR3 = mat[3]; LPC_GPIO->CLR[1] = (1<<26); LPC_GPIO->SET[1] = (1<<27); LPC_IOCON->PIO1_26 = 0x0; // GPIO LPC_IOCON->PIO1_27 = 0x1; }else{ // Stage 1, use MAT3 as period LPC_CT32B0->PWMC = (1<<0)|(1<<1)|(1<<2)|(0<<3); LPC_CT32B0->MCR = (1<<10); //Reset on MR3 LPC_CT32B0->MR2 = mat[2]; LPC_CT32B0->MR3 = period; LPC_GPIO->CLR[1] = (1<<27); LPC_GPIO->SET[1] = (1<<26); LPC_IOCON->PIO1_26 = 0x1; LPC_IOCON->PIO1_27 = 0x0; // GPIO } } /** * @brief Reload all match compare registers */ void CT32B0_reload_mat(void){ LPC_CT32B0->MR0 = mat[0]; LPC_CT32B0->MR1 = mat[1]; if(!stage){ LPC_CT32B0->MR3 = mat[3]; }else{ LPC_CT32B0->MR2 = mat[2]; } } /** * @brief Set channel PWM */ void CT32B0_set(uint8_t matnr, uint32_t value){ mat[matnr] = value; CT32B0_reload_mat(); } /** * @brief Wait for timer to reach 0 */ void CT32B0_wait_refresh(void){ if( (LPC_CT32B0->TCR & 1) ) while(LPC_CT32B0->TC != 0); } /** * @} */