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:
Wed Oct 30 21:59:32 2013 +0000
Revision:
2:ddae311a4533
Parent:
0:d0306c0cbee6
fix led blink after soft reset

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jeroen3 0:d0306c0cbee6 1 /**
jeroen3 0:d0306c0cbee6 2 * @file main.c
jeroen3 0:d0306c0cbee6 3 * @brief Main thread controlling everything
jeroen3 0:d0306c0cbee6 4 * @details This main thread received USB commands and executes them to other modules
jeroen3 0:d0306c0cbee6 5 *
jeroen3 0:d0306c0cbee6 6 * @Author Jeroen Lodder
jeroen3 0:d0306c0cbee6 7 * @Date October 2013
jeroen3 0:d0306c0cbee6 8 *
jeroen3 0:d0306c0cbee6 9 * @{
jeroen3 0:d0306c0cbee6 10 */
jeroen3 0:d0306c0cbee6 11
jeroen3 0:d0306c0cbee6 12 #include "mbed.h"
jeroen3 0:d0306c0cbee6 13 #include "smc.h"
jeroen3 0:d0306c0cbee6 14 #include "watchdog.h"
jeroen3 0:d0306c0cbee6 15 #include "USBHID.h"
jeroen3 0:d0306c0cbee6 16 #include "ByteOperations.h"
jeroen3 0:d0306c0cbee6 17 #include "USBHIDProtocol.h"
jeroen3 0:d0306c0cbee6 18 #include "CT16B1_PWM.h"
jeroen3 0:d0306c0cbee6 19
jeroen3 0:d0306c0cbee6 20 /* Main routine handles USB and SMC api */
jeroen3 0:d0306c0cbee6 21
jeroen3 0:d0306c0cbee6 22 #define VERSION 0x02
jeroen3 0:d0306c0cbee6 23
jeroen3 0:d0306c0cbee6 24 /**
jeroen3 0:d0306c0cbee6 25 * @brief USB HID Declarations
jeroen3 0:d0306c0cbee6 26 * @{
jeroen3 0:d0306c0cbee6 27 */
jeroen3 0:d0306c0cbee6 28 USBHID *hid;
jeroen3 0:d0306c0cbee6 29 HID_REPORT send_report __attribute__((aligned (4))); // Aligned for fast access
jeroen3 0:d0306c0cbee6 30 HID_REPORT recv_report __attribute__((aligned (4))); // Aligned for fast access
jeroen3 0:d0306c0cbee6 31 /**
jeroen3 0:d0306c0cbee6 32 * @}
jeroen3 0:d0306c0cbee6 33 */
jeroen3 0:d0306c0cbee6 34
jeroen3 0:d0306c0cbee6 35 /* Input Output */
jeroen3 0:d0306c0cbee6 36 DigitalOut led(P0_21); /**< @brief User led */
jeroen3 0:d0306c0cbee6 37 DigitalIn button(P0_1); /**< @brief User button input (bootloader pin) */
jeroen3 0:d0306c0cbee6 38 DigitalOut aux(P0_22); /**< @brief Auxilary mosfet channel */
jeroen3 0:d0306c0cbee6 39
jeroen3 0:d0306c0cbee6 40 /**
jeroen3 0:d0306c0cbee6 41 * @brief Debounced button reader
jeroen3 0:d0306c0cbee6 42 */
jeroen3 0:d0306c0cbee6 43 Ticker Ticker_button;
jeroen3 0:d0306c0cbee6 44 volatile uint32_t button_history = 0xFF;
jeroen3 0:d0306c0cbee6 45 void Ticker_button_handler(void){
jeroen3 0:d0306c0cbee6 46 button_history <<= 1;
jeroen3 0:d0306c0cbee6 47 button_history |= button;
jeroen3 0:d0306c0cbee6 48 }
jeroen3 0:d0306c0cbee6 49
jeroen3 0:d0306c0cbee6 50 /**
jeroen3 0:d0306c0cbee6 51 * @brief LED Blink Handler
jeroen3 0:d0306c0cbee6 52 */
jeroen3 0:d0306c0cbee6 53 Ticker Ticker_led;
jeroen3 0:d0306c0cbee6 54 void Ticker_led_handler(void){
jeroen3 0:d0306c0cbee6 55 led = !led;
jeroen3 0:d0306c0cbee6 56 }
jeroen3 0:d0306c0cbee6 57
jeroen3 0:d0306c0cbee6 58 /**
jeroen3 0:d0306c0cbee6 59 * @brief Clear buffer contents
jeroen3 0:d0306c0cbee6 60 * @note Requires 4 byte alignement of data
jeroen3 0:d0306c0cbee6 61 * @param[in] c Pointer to @p HID_REPORT.
jeroen3 0:d0306c0cbee6 62 */
jeroen3 0:d0306c0cbee6 63 void empty_report(HID_REPORT *data){
jeroen3 0:d0306c0cbee6 64 register uint32_t *p = (uint32_t *)data->data;
jeroen3 0:d0306c0cbee6 65 for( register int i=0; i<((sizeof(HID_REPORT)-1)/4); i++ ){
jeroen3 0:d0306c0cbee6 66 *p = 0xFFFFFFFF;
jeroen3 0:d0306c0cbee6 67 p++;
jeroen3 0:d0306c0cbee6 68 }
jeroen3 0:d0306c0cbee6 69 }
jeroen3 0:d0306c0cbee6 70
jeroen3 0:d0306c0cbee6 71 /* Program entry */
jeroen3 0:d0306c0cbee6 72 int main(void){
jeroen3 0:d0306c0cbee6 73 /* Init */
jeroen3 0:d0306c0cbee6 74 // reset flags
jeroen3 0:d0306c0cbee6 75 LPC_SYSCON->SYSRSTSTAT = 0x1F;
jeroen3 0:d0306c0cbee6 76 // Motor Control IO config
jeroen3 0:d0306c0cbee6 77 SMC_init();
jeroen3 0:d0306c0cbee6 78 // aux init
jeroen3 0:d0306c0cbee6 79 aux = 0;
jeroen3 0:d0306c0cbee6 80 // LED
jeroen3 0:d0306c0cbee6 81 led = 0;
jeroen3 0:d0306c0cbee6 82 // USB Initialize
jeroen3 0:d0306c0cbee6 83 static USBHID hid_object(64, 64);
jeroen3 0:d0306c0cbee6 84 hid = &hid_object;
jeroen3 0:d0306c0cbee6 85 send_report.length = 64;
jeroen3 0:d0306c0cbee6 86 // button config
jeroen3 0:d0306c0cbee6 87 Ticker_button.attach_us(&Ticker_button_handler, 20000);
jeroen3 0:d0306c0cbee6 88
jeroen3 0:d0306c0cbee6 89 // Ready
jeroen3 0:d0306c0cbee6 90 while(1){
jeroen3 0:d0306c0cbee6 91 // insert idle time, since we cant be running USB stuff all the time
jeroen3 0:d0306c0cbee6 92 wait_us(5000);
jeroen3 0:d0306c0cbee6 93 //try to read a msg
jeroen3 0:d0306c0cbee6 94 if(hid->readNB(&recv_report)){
jeroen3 0:d0306c0cbee6 95 // Data packet received, start parsing
jeroen3 0:d0306c0cbee6 96 int irx=0;
jeroen3 0:d0306c0cbee6 97 int itx=0;
jeroen3 0:d0306c0cbee6 98 send_report.data[itx++] = recv_report.data[0];
jeroen3 0:d0306c0cbee6 99 switch( recv_report.data[irx++] ){
jeroen3 0:d0306c0cbee6 100 case CMD_SYS_CHECK :
jeroen3 0:d0306c0cbee6 101 send_report.data[itx++] = VERSION;
jeroen3 0:d0306c0cbee6 102 break;
jeroen3 0:d0306c0cbee6 103 case CMD_SYS_RESET :
jeroen3 0:d0306c0cbee6 104 // Soft reset
jeroen3 0:d0306c0cbee6 105 SMC_deinit();
jeroen3 0:d0306c0cbee6 106 SMC_init();
jeroen3 0:d0306c0cbee6 107 CT16B1_deinit(0);
jeroen3 0:d0306c0cbee6 108 led = 1;
jeroen3 2:ddae311a4533 109 Ticker_led.detach();
jeroen3 0:d0306c0cbee6 110 aux = 0;
jeroen3 0:d0306c0cbee6 111 empty_report(&recv_report);
jeroen3 0:d0306c0cbee6 112 break;
jeroen3 0:d0306c0cbee6 113 case CMD_LED_OFF :
jeroen3 0:d0306c0cbee6 114 led = 1; // inverted led
jeroen3 0:d0306c0cbee6 115 Ticker_led.detach();
jeroen3 0:d0306c0cbee6 116 break;
jeroen3 0:d0306c0cbee6 117 case CMD_LED_ON :
jeroen3 0:d0306c0cbee6 118 led = 0; // inverted led
jeroen3 0:d0306c0cbee6 119 Ticker_led.detach();
jeroen3 0:d0306c0cbee6 120 break;
jeroen3 0:d0306c0cbee6 121 case CMD_LED_BLINK :
jeroen3 0:d0306c0cbee6 122 Ticker_led.attach_us(&Ticker_led_handler, 100000);
jeroen3 0:d0306c0cbee6 123 break;
jeroen3 0:d0306c0cbee6 124 case CMD_LED_BREATH :
jeroen3 0:d0306c0cbee6 125 // Not implemented
jeroen3 0:d0306c0cbee6 126 break;
jeroen3 0:d0306c0cbee6 127 case CMD_GET_BUTTON :
jeroen3 0:d0306c0cbee6 128 write_32_to_8(&itx, send_report.data, button_history);
jeroen3 0:d0306c0cbee6 129 break;
jeroen3 0:d0306c0cbee6 130 case CMD_SMC_STEP : {
jeroen3 0:d0306c0cbee6 131 uint32_t arg_step = read_8_to_32(&irx, recv_report.data);
jeroen3 0:d0306c0cbee6 132 uint8_t arg_dir = recv_report.data[irx++];
jeroen3 0:d0306c0cbee6 133 uint32_t arg_time = read_8_to_32(&irx, recv_report.data);
jeroen3 0:d0306c0cbee6 134 uint8_t arg_free = recv_report.data[irx++];
jeroen3 0:d0306c0cbee6 135 SMC_step(arg_step, arg_dir, arg_time, arg_free);
jeroen3 0:d0306c0cbee6 136 }
jeroen3 0:d0306c0cbee6 137 break;
jeroen3 0:d0306c0cbee6 138 case CMD_SMC_STATE :
jeroen3 0:d0306c0cbee6 139 write_32_to_8(&itx, send_report.data, SMC_getState());
jeroen3 0:d0306c0cbee6 140 break;
jeroen3 0:d0306c0cbee6 141 case CMD_SMC_STOP :
jeroen3 0:d0306c0cbee6 142 SMC_deinit();
jeroen3 0:d0306c0cbee6 143 break;
jeroen3 0:d0306c0cbee6 144 case CMD_SMC_PAUSE :
jeroen3 0:d0306c0cbee6 145 SMC_pause();
jeroen3 0:d0306c0cbee6 146 break;
jeroen3 0:d0306c0cbee6 147 case CMD_SMC_CONTINUE:
jeroen3 0:d0306c0cbee6 148 SMC_continue();
jeroen3 0:d0306c0cbee6 149 break;
jeroen3 0:d0306c0cbee6 150 case CMD_SMC_FREE :
jeroen3 0:d0306c0cbee6 151 SMC_free();
jeroen3 0:d0306c0cbee6 152 break;
jeroen3 0:d0306c0cbee6 153 case CMD_SMC_BRAKE :
jeroen3 0:d0306c0cbee6 154 SMC_brake();
jeroen3 0:d0306c0cbee6 155 break;
jeroen3 0:d0306c0cbee6 156 case CMD_AUX_OFF :
jeroen3 0:d0306c0cbee6 157 CT16B1_deinit(0);
jeroen3 0:d0306c0cbee6 158 aux = 0;
jeroen3 0:d0306c0cbee6 159 //if(CT16B1_isStarted())
jeroen3 0:d0306c0cbee6 160
jeroen3 0:d0306c0cbee6 161 break;
jeroen3 0:d0306c0cbee6 162 case CMD_AUX_ON :
jeroen3 0:d0306c0cbee6 163 CT16B1_deinit(1);
jeroen3 0:d0306c0cbee6 164 aux = 1;
jeroen3 0:d0306c0cbee6 165 //if(CT16B1_isStarted())
jeroen3 0:d0306c0cbee6 166 break;
jeroen3 0:d0306c0cbee6 167 case CMD_AUX_PWM : {
jeroen3 0:d0306c0cbee6 168 uint16_t dutycycle, period, prescaler;
jeroen3 0:d0306c0cbee6 169 dutycycle = read_8_to_16(&irx, recv_report.data);
jeroen3 0:d0306c0cbee6 170 period = read_8_to_16(&irx, recv_report.data);
jeroen3 0:d0306c0cbee6 171 prescaler = read_8_to_16(&irx, recv_report.data);
jeroen3 0:d0306c0cbee6 172 /* Invert PWM, since timer is inverted */
jeroen3 0:d0306c0cbee6 173 dutycycle = period - dutycycle;
jeroen3 0:d0306c0cbee6 174 if(CT16B1_isStarted()){
jeroen3 0:d0306c0cbee6 175 CT16B1_wait_refresh();
jeroen3 0:d0306c0cbee6 176 CT16B1_set(1, dutycycle);
jeroen3 0:d0306c0cbee6 177 }else{
jeroen3 0:d0306c0cbee6 178 CT16B1_initpwm(period,dutycycle,prescaler);
jeroen3 0:d0306c0cbee6 179 CT16B1_start();
jeroen3 0:d0306c0cbee6 180 }
jeroen3 0:d0306c0cbee6 181 }
jeroen3 0:d0306c0cbee6 182 break;
jeroen3 0:d0306c0cbee6 183 case 0xEE : {
jeroen3 0:d0306c0cbee6 184 hid->sendNB(&send_report);
jeroen3 0:d0306c0cbee6 185 SMC_egg();
jeroen3 0:d0306c0cbee6 186 WatchDog_us bello(100);
jeroen3 0:d0306c0cbee6 187 }
jeroen3 0:d0306c0cbee6 188 break;
jeroen3 0:d0306c0cbee6 189 default:
jeroen3 0:d0306c0cbee6 190 send_report.data[0] = 0xFF; //Failure
jeroen3 0:d0306c0cbee6 191 break;
jeroen3 0:d0306c0cbee6 192 } // Switch
jeroen3 0:d0306c0cbee6 193 // Return command + optional new args
jeroen3 0:d0306c0cbee6 194 hid->send(&send_report);
jeroen3 0:d0306c0cbee6 195 // 0xFF unused bytes
jeroen3 0:d0306c0cbee6 196 empty_report(&recv_report);
jeroen3 0:d0306c0cbee6 197 empty_report(&send_report);
jeroen3 0:d0306c0cbee6 198 } // if packet
jeroen3 0:d0306c0cbee6 199 } // While
jeroen3 0:d0306c0cbee6 200 } // Main
jeroen3 0:d0306c0cbee6 201 /** @} */
jeroen3 0:d0306c0cbee6 202