Design-in of LPC11U24 (lqfp48) of mbed as Steppermotor controller with USB control.

Dependencies:   USBDevice mbed

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

Committer:
jeroen3
Date:
Mon Oct 28 18:26:28 2013 +0000
Revision:
0:d0306c0cbee6
Child:
1:e7709c579a18
Initial mbed upload

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jeroen3 0:d0306c0cbee6 1 /**
jeroen3 0:d0306c0cbee6 2 * @file CT32B0_PWM.cpp
jeroen3 0:d0306c0cbee6 3 * @brief Small driver to user CT32B0 for PWM
jeroen3 0:d0306c0cbee6 4 *
jeroen3 0:d0306c0cbee6 5 * @author Jeroen Lodder
jeroen3 0:d0306c0cbee6 6 * @date Oktober 2013
jeroen3 0:d0306c0cbee6 7 *
jeroen3 0:d0306c0cbee6 8 * @note Since only one timer is used to supply 4 PWM channels
jeroen3 0:d0306c0cbee6 9 * a problem occurs because CT32B0 only support 3 PWM channels.
jeroen3 0:d0306c0cbee6 10 *
jeroen3 0:d0306c0cbee6 11 * Since this software is designed for a H-Bridge implementation
jeroen3 0:d0306c0cbee6 12 * only 2 of 4 PWM channels are required to be active simultaneously.
jeroen3 0:d0306c0cbee6 13 *
jeroen3 0:d0306c0cbee6 14 * This is where the stage variable comes in:
jeroen3 0:d0306c0cbee6 15 * Stage 0: PWM enabled on MAT 0, MAT 1 and MAT 2.
jeroen3 0:d0306c0cbee6 16 * Stage 1: PWM enabled on MAT 0, MAT 1 and MAT 3.
jeroen3 0:d0306c0cbee6 17 * Unused MAT outputs will be pullled down.
jeroen3 0:d0306c0cbee6 18 * @{
jeroen3 0:d0306c0cbee6 19 */
jeroen3 0:d0306c0cbee6 20 #include "mbed.h"
jeroen3 0:d0306c0cbee6 21 #include "CT32B0_PWM.h"
jeroen3 0:d0306c0cbee6 22
jeroen3 0:d0306c0cbee6 23 // Prescaler 48 gives 1 us per tick
jeroen3 0:d0306c0cbee6 24 #define CT32B0_PRESCALER 48 /**< @brief Timer prescaler from AHBCLK */
jeroen3 0:d0306c0cbee6 25
jeroen3 0:d0306c0cbee6 26 /* Static makes them private to this module */
jeroen3 0:d0306c0cbee6 27 volatile static uint8_t stage = 0; /**< @brief Stage identifier for mat2/3 swap */
jeroen3 0:d0306c0cbee6 28 volatile static uint32_t period = 0; /**< @brief PWM Period register */
jeroen3 0:d0306c0cbee6 29 volatile static uint32_t mat[4]; /**< @brief PWM Mat output registers */
jeroen3 0:d0306c0cbee6 30 volatile static uint32_t default_period_us; /**< @brief Given period in us */
jeroen3 0:d0306c0cbee6 31 volatile static uint32_t defaultstate; /**< @brief Default PWM state on init */
jeroen3 0:d0306c0cbee6 32
jeroen3 0:d0306c0cbee6 33 /**
jeroen3 0:d0306c0cbee6 34 * @brief Initializes PWM
jeroen3 0:d0306c0cbee6 35 *
jeroen3 0:d0306c0cbee6 36 * @param[in] period_us Period in us, when prescaler is 48
jeroen3 0:d0306c0cbee6 37 * @param[in] defaultstate State after initializing
jeroen3 0:d0306c0cbee6 38 * @note Run Start() to start pwm
jeroen3 0:d0306c0cbee6 39 */
jeroen3 0:d0306c0cbee6 40 void CT32B0_initpwm(uint32_t period_us, uint32_t defaultstate){
jeroen3 0:d0306c0cbee6 41 // Calculte period
jeroen3 0:d0306c0cbee6 42 period = period_us;
jeroen3 0:d0306c0cbee6 43
jeroen3 0:d0306c0cbee6 44 // Store latest setting
jeroen3 0:d0306c0cbee6 45 mat[0] = defaultstate;
jeroen3 0:d0306c0cbee6 46 mat[1] = defaultstate;
jeroen3 0:d0306c0cbee6 47 mat[2] = defaultstate;
jeroen3 0:d0306c0cbee6 48 mat[3] = defaultstate;
jeroen3 0:d0306c0cbee6 49
jeroen3 0:d0306c0cbee6 50 LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6)|(1<<9);
jeroen3 0:d0306c0cbee6 51
jeroen3 0:d0306c0cbee6 52 LPC_CT32B0->IR = 0x5F; // Clear int
jeroen3 0:d0306c0cbee6 53 LPC_CT32B0->TCR = 2; // Reset
jeroen3 0:d0306c0cbee6 54 LPC_CT32B0->PR = CT32B0_PRESCALER;
jeroen3 0:d0306c0cbee6 55 LPC_CT32B0->CCR = 0; // No capture
jeroen3 0:d0306c0cbee6 56 LPC_CT32B0->EMR = 0; // Not required, refer to PWMC
jeroen3 0:d0306c0cbee6 57 LPC_CT32B0->CTCR = 0; // No special counters mode
jeroen3 0:d0306c0cbee6 58
jeroen3 0:d0306c0cbee6 59 // Set outputs to stage
jeroen3 0:d0306c0cbee6 60 if(!stage){
jeroen3 0:d0306c0cbee6 61 // Stage 0, use MAT2 as period
jeroen3 0:d0306c0cbee6 62 LPC_CT32B0->PWMC = (1<<0)|(1<<1)|(0<<2)|(1<<3);
jeroen3 0:d0306c0cbee6 63 LPC_CT32B0->MCR = (1<<7); // Reset on MR2
jeroen3 0:d0306c0cbee6 64 LPC_CT32B0->MR2 = period;
jeroen3 0:d0306c0cbee6 65 LPC_CT32B0->MR3 = defaultstate;
jeroen3 0:d0306c0cbee6 66
jeroen3 0:d0306c0cbee6 67 LPC_GPIO->DIR[1] |= (1<<26); // Disable P1_26
jeroen3 0:d0306c0cbee6 68 LPC_GPIO->CLR[1] = (1<<26);
jeroen3 0:d0306c0cbee6 69 LPC_IOCON->PIO1_26 = 0x0; // Change pin mode
jeroen3 0:d0306c0cbee6 70 LPC_IOCON->PIO1_27 = 0x1;
jeroen3 0:d0306c0cbee6 71 }else{
jeroen3 0:d0306c0cbee6 72 // Stage 1, use MAT3 as period
jeroen3 0:d0306c0cbee6 73 LPC_CT32B0->PWMC = (1<<0)|(1<<1)|(1<<2)|(0<<3);
jeroen3 0:d0306c0cbee6 74 LPC_CT32B0->MCR = (1<<10); //Reset on MR3
jeroen3 0:d0306c0cbee6 75 LPC_CT32B0->MR2 = defaultstate;
jeroen3 0:d0306c0cbee6 76 LPC_CT32B0->MR3 = period;
jeroen3 0:d0306c0cbee6 77
jeroen3 0:d0306c0cbee6 78 LPC_GPIO->DIR[1] |= (1<<27); // Disable P1_27
jeroen3 0:d0306c0cbee6 79 LPC_GPIO->CLR[1] = (1<<27);
jeroen3 0:d0306c0cbee6 80 LPC_IOCON->PIO1_26 = 0x1;
jeroen3 0:d0306c0cbee6 81 LPC_IOCON->PIO1_27 = 0x0; // Change pin mode
jeroen3 0:d0306c0cbee6 82 }
jeroen3 0:d0306c0cbee6 83
jeroen3 0:d0306c0cbee6 84 // MAT 1 and MAT 2 are not affected by stage
jeroen3 0:d0306c0cbee6 85 LPC_CT32B0->MR0 = defaultstate;
jeroen3 0:d0306c0cbee6 86 LPC_CT32B0->MR1 = defaultstate;
jeroen3 0:d0306c0cbee6 87 LPC_IOCON->PIO1_24 = 0x1; // Change pin mode
jeroen3 0:d0306c0cbee6 88 LPC_IOCON->PIO1_25 = 0x1; // Change pin mode
jeroen3 0:d0306c0cbee6 89
jeroen3 0:d0306c0cbee6 90 LPC_CT32B0->TCR = 0;
jeroen3 0:d0306c0cbee6 91 }
jeroen3 0:d0306c0cbee6 92
jeroen3 0:d0306c0cbee6 93 /**
jeroen3 0:d0306c0cbee6 94 * @brief Re-Initializes PWM
jeroen3 0:d0306c0cbee6 95 */
jeroen3 0:d0306c0cbee6 96 void CT32B0_reinitpwm(void){
jeroen3 0:d0306c0cbee6 97 CT32B0_initpwm(default_period_us,defaultstate );
jeroen3 0:d0306c0cbee6 98 }
jeroen3 0:d0306c0cbee6 99
jeroen3 0:d0306c0cbee6 100 /**
jeroen3 0:d0306c0cbee6 101 * @brief Start PWM
jeroen3 0:d0306c0cbee6 102 */
jeroen3 0:d0306c0cbee6 103 void CT32B0_start(void){
jeroen3 0:d0306c0cbee6 104 LPC_CT32B0->TCR = 1; // Enable
jeroen3 0:d0306c0cbee6 105 }
jeroen3 0:d0306c0cbee6 106
jeroen3 0:d0306c0cbee6 107 /**
jeroen3 0:d0306c0cbee6 108 * @brief Stop PWM
jeroen3 0:d0306c0cbee6 109 * @param[in] state PWM output state when pwm disabled
jeroen3 0:d0306c0cbee6 110 */
jeroen3 0:d0306c0cbee6 111 void CT32B0_deinit(uint8_t state){
jeroen3 0:d0306c0cbee6 112 LPC_CT32B0->TCR = 2; // Disable and reset counter
jeroen3 0:d0306c0cbee6 113 // Set all to GPIO
jeroen3 0:d0306c0cbee6 114 LPC_IOCON->PIO1_24 = 0;
jeroen3 0:d0306c0cbee6 115 LPC_IOCON->PIO1_25 = 0;
jeroen3 0:d0306c0cbee6 116 LPC_IOCON->PIO1_26 = 0;
jeroen3 0:d0306c0cbee6 117 LPC_IOCON->PIO1_27 = 0;
jeroen3 0:d0306c0cbee6 118 LPC_GPIO->DIR[1] |= (1<<24)|(1<<25)|(1<<26)|(1<<27);
jeroen3 0:d0306c0cbee6 119 if(state)
jeroen3 0:d0306c0cbee6 120 LPC_GPIO->SET[1] = (1<<24)|(1<<25)|(1<<26)|(1<<27);
jeroen3 0:d0306c0cbee6 121 else
jeroen3 0:d0306c0cbee6 122 LPC_GPIO->CLR[1] = (1<<24)|(1<<25)|(1<<26)|(1<<27);
jeroen3 0:d0306c0cbee6 123 }
jeroen3 0:d0306c0cbee6 124
jeroen3 0:d0306c0cbee6 125 /**
jeroen3 0:d0306c0cbee6 126 * @brief Set stage
jeroen3 0:d0306c0cbee6 127 * @param[in] stagearg 1 or 0
jeroen3 0:d0306c0cbee6 128 */
jeroen3 0:d0306c0cbee6 129 void CT32B0_stage(uint8_t stagearg){
jeroen3 0:d0306c0cbee6 130 stage = stagearg;
jeroen3 0:d0306c0cbee6 131 // Set outputs to stage
jeroen3 0:d0306c0cbee6 132 if(!stage){
jeroen3 0:d0306c0cbee6 133 // Stage 0, use MAT2 as period
jeroen3 0:d0306c0cbee6 134 LPC_CT32B0->PWMC = (1<<0)|(1<<1)|(0<<2)|(1<<3);
jeroen3 0:d0306c0cbee6 135 LPC_CT32B0->MCR = (1<<7); // Reset on MR2
jeroen3 0:d0306c0cbee6 136 LPC_CT32B0->MR2 = period;
jeroen3 0:d0306c0cbee6 137 LPC_CT32B0->MR3 = mat[3];
jeroen3 0:d0306c0cbee6 138 LPC_GPIO->CLR[1] = (1<<26);
jeroen3 0:d0306c0cbee6 139 LPC_GPIO->SET[1] = (1<<27);
jeroen3 0:d0306c0cbee6 140 LPC_IOCON->PIO1_26 = 0x0; // GPIO
jeroen3 0:d0306c0cbee6 141 LPC_IOCON->PIO1_27 = 0x1;
jeroen3 0:d0306c0cbee6 142 }else{
jeroen3 0:d0306c0cbee6 143 // Stage 1, use MAT3 as period
jeroen3 0:d0306c0cbee6 144 LPC_CT32B0->PWMC = (1<<0)|(1<<1)|(1<<2)|(0<<3);
jeroen3 0:d0306c0cbee6 145 LPC_CT32B0->MCR = (1<<10); //Reset on MR3
jeroen3 0:d0306c0cbee6 146 LPC_CT32B0->MR2 = mat[2];
jeroen3 0:d0306c0cbee6 147 LPC_CT32B0->MR3 = period;
jeroen3 0:d0306c0cbee6 148 LPC_GPIO->CLR[1] = (1<<27);
jeroen3 0:d0306c0cbee6 149 LPC_GPIO->SET[1] = (1<<26);
jeroen3 0:d0306c0cbee6 150 LPC_IOCON->PIO1_26 = 0x1;
jeroen3 0:d0306c0cbee6 151 LPC_IOCON->PIO1_27 = 0x0; // GPIO
jeroen3 0:d0306c0cbee6 152 }
jeroen3 0:d0306c0cbee6 153 }
jeroen3 0:d0306c0cbee6 154
jeroen3 0:d0306c0cbee6 155 /**
jeroen3 0:d0306c0cbee6 156 * @brief Reload all match compare registers
jeroen3 0:d0306c0cbee6 157 */
jeroen3 0:d0306c0cbee6 158 void CT32B0_reload_mat(void){
jeroen3 0:d0306c0cbee6 159 LPC_CT32B0->MR0 = mat[0];
jeroen3 0:d0306c0cbee6 160 LPC_CT32B0->MR1 = mat[1];
jeroen3 0:d0306c0cbee6 161 if(!stage){
jeroen3 0:d0306c0cbee6 162 LPC_CT32B0->MR3 = mat[3];
jeroen3 0:d0306c0cbee6 163 }else{
jeroen3 0:d0306c0cbee6 164 LPC_CT32B0->MR2 = mat[2];
jeroen3 0:d0306c0cbee6 165 }
jeroen3 0:d0306c0cbee6 166 }
jeroen3 0:d0306c0cbee6 167
jeroen3 0:d0306c0cbee6 168 /**
jeroen3 0:d0306c0cbee6 169 * @brief Set channel PWM
jeroen3 0:d0306c0cbee6 170 */
jeroen3 0:d0306c0cbee6 171 void CT32B0_set(uint8_t matnr, uint32_t value){
jeroen3 0:d0306c0cbee6 172 mat[matnr] = value;
jeroen3 0:d0306c0cbee6 173 CT32B0_reload_mat();
jeroen3 0:d0306c0cbee6 174 }
jeroen3 0:d0306c0cbee6 175
jeroen3 0:d0306c0cbee6 176 /**
jeroen3 0:d0306c0cbee6 177 * @brief Wait for timer to reach 0
jeroen3 0:d0306c0cbee6 178 */
jeroen3 0:d0306c0cbee6 179 void CT32B0_wait_refresh(void){
jeroen3 0:d0306c0cbee6 180 if( (LPC_CT32B0->TCR & 1) )
jeroen3 0:d0306c0cbee6 181 while(LPC_CT32B0->TC != 0);
jeroen3 0:d0306c0cbee6 182 }
jeroen3 0:d0306c0cbee6 183 /**
jeroen3 0:d0306c0cbee6 184 * @}
jeroen3 0:d0306c0cbee6 185 */
jeroen3 0:d0306c0cbee6 186