diff --git a/Makefile b/Makefile index 4bb93535..2b6fa749 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,8 @@ C_SOURCES = \ Src/usbd_cdc_if.c \ Src/syscalls.c \ MotorControl/utils.c \ - MotorControl/low_level.c + MotorControl/commands.c \ + MotorControl/low_level.c ASM_SOURCES = \ startup/startup_stm32f405xx.s diff --git a/MotorControl/commands.c b/MotorControl/commands.c new file mode 100644 index 00000000..8674a256 --- /dev/null +++ b/MotorControl/commands.c @@ -0,0 +1,314 @@ +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include + +/* Private macros ------------------------------------------------------------*/ +/* Private typedef -----------------------------------------------------------*/ +/* Global constant data ------------------------------------------------------*/ +/* Global variables ----------------------------------------------------------*/ +extern PCD_HandleTypeDef hpcd_USB_OTG_FS; +/* Private constant data -----------------------------------------------------*/ +// variables exposed to usb/serial interface via set/get/monitor +// Note: this will be depricated soon +static float* const exposed_floats[] = { + &vbus_voltage, // ro + NULL, //&elec_rad_per_enc, // ro + &motors[0].pos_setpoint, // rw + &motors[0].pos_gain, // rw + &motors[0].vel_setpoint, // rw + &motors[0].vel_gain, // rw + &motors[0].vel_integrator_gain, // rw + &motors[0].vel_integrator_current, // rw + &motors[0].vel_limit, // rw + &motors[0].current_setpoint, // rw + &motors[0].calibration_current, // rw + &motors[0].phase_inductance, // ro + &motors[0].phase_resistance, // ro + &motors[0].current_meas.phB, // ro + &motors[0].current_meas.phC, // ro + &motors[0].DC_calib.phB, // rw + &motors[0].DC_calib.phC, // rw + &motors[0].shunt_conductance, // rw + &motors[0].phase_current_rev_gain, // rw + &motors[0].current_control.current_lim, // rw + &motors[0].current_control.p_gain, // rw + &motors[0].current_control.i_gain, // rw + &motors[0].current_control.v_current_control_integral_d, // rw + &motors[0].current_control.v_current_control_integral_q, // rw + &motors[0].current_control.Ibus, // ro + &motors[0].encoder.phase, // ro + &motors[0].encoder.pll_pos, // rw + &motors[0].encoder.pll_vel, // rw + &motors[0].encoder.pll_kp, // rw + &motors[0].encoder.pll_ki, // rw + &motors[1].pos_setpoint, // rw + &motors[1].pos_gain, // rw + &motors[1].vel_setpoint, // rw + &motors[1].vel_gain, // rw + &motors[1].vel_integrator_gain, // rw + &motors[1].vel_integrator_current, // rw + &motors[1].vel_limit, // rw + &motors[1].current_setpoint, // rw + &motors[1].calibration_current, // rw + &motors[1].phase_inductance, // ro + &motors[1].phase_resistance, // ro + &motors[1].current_meas.phB, // ro + &motors[1].current_meas.phC, // ro + &motors[1].DC_calib.phB, // rw + &motors[1].DC_calib.phC, // rw + &motors[1].shunt_conductance, // rw + &motors[1].phase_current_rev_gain, // rw + &motors[1].current_control.current_lim, // rw + &motors[1].current_control.p_gain, // rw + &motors[1].current_control.i_gain, // rw + &motors[1].current_control.v_current_control_integral_d, // rw + &motors[1].current_control.v_current_control_integral_q, // rw + &motors[1].current_control.Ibus, // ro + &motors[1].encoder.phase, // ro + &motors[1].encoder.pll_pos, // rw + &motors[1].encoder.pll_vel, // rw + &motors[1].encoder.pll_kp, // rw + &motors[1].encoder.pll_ki, // rw +}; + +static int* const exposed_ints[] = { + (int*)&motors[0].control_mode, // rw + &motors[0].encoder.encoder_offset, // rw + &motors[0].encoder.encoder_state, // ro + &motors[0].error, // rw + (int*)&motors[1].control_mode, // rw + &motors[1].encoder.encoder_offset, // rw + &motors[1].encoder.encoder_state, // ro + &motors[1].error, // rw +}; + +static bool* const exposed_bools[] = { + &motors[0].thread_ready, // ro + &motors[0].enable_control, // rw + &motors[0].do_calibration, // rw + &motors[0].calibration_ok, // ro + &motors[1].thread_ready, // ro + &motors[1].enable_control, // rw + &motors[1].do_calibration, // rw + &motors[1].calibration_ok, // ro +}; + +static uint16_t* const exposed_uint16[] = { + &motors[0].control_deadline, // rw + &motors[0].last_cpu_time, // ro + &motors[1].control_deadline, // rw + &motors[1].last_cpu_time, // ro +}; + +/* Private variables ---------------------------------------------------------*/ +monitoring_slot monitoring_slots[20] = {0}; +/* Private function prototypes -----------------------------------------------*/ +static void print_monitoring(int limit); + +/* Function implementations --------------------------------------------------*/ +void motor_parse_cmd(uint8_t* buffer, int len) { + // TODO very hacky way of terminating sscanf at end of buffer: + // We should do some proper struct packing instead of using sscanf altogether + buffer[len] = 0; + + // check incoming packet type + if (buffer[0] == 'p') { + // position control + unsigned motor_number; + float pos_setpoint, vel_feed_forward, current_feed_forward; + int numscan = sscanf((const char*)buffer, "p %u %f %f %f", &motor_number, &pos_setpoint, &vel_feed_forward, ¤t_feed_forward); + if (numscan == 4 && motor_number < num_motors) { + set_pos_setpoint(&motors[motor_number], pos_setpoint, vel_feed_forward, current_feed_forward); + } + } else if (buffer[0] == 'v') { + // velocity control + unsigned motor_number; + float vel_feed_forward, current_feed_forward; + int numscan = sscanf((const char*)buffer, "v %u %f %f", &motor_number, &vel_feed_forward, ¤t_feed_forward); + if (numscan == 3 && motor_number < num_motors) { + set_vel_setpoint(&motors[motor_number], vel_feed_forward, current_feed_forward); + } + } else if (buffer[0] == 'c') { + // current control + unsigned motor_number; + float current_feed_forward; + int numscan = sscanf((const char*)buffer, "c %u %f", &motor_number, ¤t_feed_forward); + if (numscan == 2 && motor_number < num_motors) { + set_current_setpoint(&motors[motor_number], current_feed_forward); + } + } else if (buffer[0] == 'g') { // GET + // g <0:float,1:int,2:bool,3:uint16> index + int type = 0; + int index = 0; + int numscan = sscanf((const char*)buffer, "g %u %u", &type, &index); + if (numscan == 2) { + switch(type){ + case 0: { + printf("%f\n",*exposed_floats[index]); + break; + }; + case 1: { + printf("%d\n",*exposed_ints[index]); + break; + }; + case 2: { + printf("%d\n",*exposed_bools[index]); + break; + }; + case 3: { + printf("%hu\n",*exposed_uint16[index]); + break; + }; + } + } + } else if (buffer[0] == 's') { // SET + // s <0:float,1:int,2:bool,3:uint16> index value + int type = 0; + int index = 0; + int numscan = sscanf((const char*)buffer, "s %u %u", &type, &index); + if (numscan == 2) { + switch(type) { + case 0: { + sscanf((const char*)buffer, "s %u %u %f", &type, &index, exposed_floats[index]); + break; + }; + case 1: { + sscanf((const char*)buffer, "s %u %u %d", &type, &index, exposed_ints[index]); + break; + }; + case 2: { + int btmp = 0; + sscanf((const char*)buffer, "s %u %u %d", &type, &index, &btmp); + *exposed_bools[index] = btmp ? true : false; + break; + }; + case 3: { + sscanf((const char*)buffer, "s %u %u %hu", &type, &index, exposed_uint16[index]); + break; + }; + } + } + } else if (buffer[0] == 'm') { // Setup Monitor + // m <0:float,1:int,2:bool,3:uint16> index monitoring_slot + int type = 0; + int index = 0; + int slot = 0; + int numscan = sscanf((const char*)buffer, "m %u %u %u", &type, &index, &slot); + if (numscan == 3) { + monitoring_slots[slot].type = type; + monitoring_slots[slot].index = index; + } + } else if (buffer[0] == 'o') { // Output Monitor + int limit = 0; + int numscan = sscanf((const char*)buffer, "o %u", &limit); + if (numscan == 1) { + print_monitoring(limit); + } + } +} + +static void print_monitoring(int limit) { + for (int i=0;iInstance->NDTR; + // Re-run state-machine forever + for (;;) { + //Inialize recieve state machine + bool reset_read_state = false; + bool read_active = false; + uint32_t parse_buffer_idx = 0; + //Run state machine until reset + do { + // Fetch the circular buffer "write pointer", where it would write next + uint32_t rcv_idx = UART_BUFFER_SIZE - huart4.hdmarx->Instance->NDTR; + // During sleeping, we may have fallen several characters behind, so we keep + // going until we are caught up, before we sleep again + while (rcv_idx != last_rcv_idx) { + // Fetch the next char, rotate read ptr + uint8_t c = dma_circ_buffer[last_rcv_idx]; + if (++last_rcv_idx == UART_BUFFER_SIZE) + last_rcv_idx = 0; + // Look for start character + if (c == '$') { + read_active = true; + continue; // do not record start char + } + // Record into parse buffer when actively reading + if (read_active) { + parse_buffer[parse_buffer_idx++] = c; + if (c == '\r' || c == '\n' || c == '!') { + // End of command string: exchange end char with terminating null + parse_buffer[parse_buffer_idx-1] = '\0'; + motor_parse_cmd(parse_buffer, parse_buffer_idx); + // Reset receieve state machine + reset_read_state = true; + break; + } else if (parse_buffer_idx == UART_BUFFER_SIZE - 1) { + // We are not at end of command, and receiving another character after this + // would go into the last slot, which is reserved for terminating null. + // We have effectively overflowed parse buffer: abort. + reset_read_state = true; + break; + } + } + } + // When we reach here, we are out of immediate characters to fetch out of buffer + // So we sleep for a bit. + osDelay(1); + } while (!reset_read_state); + } + + for (;;) { + // Wait for signalling from USB interrupt (OTG_FS_IRQHandler) + osSemaphoreWait(sem_usb_irq, osWaitForever); + // Irq processing loop + //while(HAL_NVIC_GetActive(OTG_FS_IRQn)) { + HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); + //} + // Let the irq (OTG_FS_IRQHandler) fire again. + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + } + + // If we get here, then this task is done + vTaskDelete(osThreadGetId()); +} \ No newline at end of file diff --git a/MotorControl/commands.h b/MotorControl/commands.h new file mode 100644 index 00000000..ec5e101a --- /dev/null +++ b/MotorControl/commands.h @@ -0,0 +1,10 @@ +#ifndef COMMANDS_H +#define COMMANDS_H + +#include + +/* Exported functions --------------------------------------------------------*/ +void cmd_parse_thread(void const * argument); +void motor_parse_cmd(uint8_t* buffer, int len); + +#endif /* COMMANDS_H */ diff --git a/MotorControl/low_level.c b/MotorControl/low_level.c index a7cf7fa2..5a219052 100755 --- a/MotorControl/low_level.c +++ b/MotorControl/low_level.c @@ -34,6 +34,11 @@ // Arbitrary non-zero inital value to avoid division by zero if ADC reading is late float vbus_voltage = 12.0f; +// For now, this automatically updates to the interface that most +// recently recieved a command. In the future we may want to separate +// debug printf and the main serial comms. +SerialPrintf_t serial_printf_select = SERIAL_PRINTF_IS_NONE; + // TODO stick parameter into struct #define ENCODER_CPR (600*4) #define POLE_PAIRS 7 @@ -221,107 +226,9 @@ static const int current_meas_hz = CURRENT_MEAS_HZ; /* Private variables ---------------------------------------------------------*/ static float brake_resistance = 0.47f; // [ohm] -/* Monitoring */ -monitoring_slot monitoring_slots[20] = {0}; - -/* variables exposed to usb interface via set/get/monitor - * If you change something here, don't forget to regenerate the python interface with generate_api.py - * ro/rw : read only/read write -> ro prevents the code generator from generating setter - * */ - -float* exposed_floats[] = { - &vbus_voltage, // ro - &elec_rad_per_enc, // ro - &motors[0].pos_setpoint, // rw - &motors[0].pos_gain, // rw - &motors[0].vel_setpoint, // rw - &motors[0].vel_gain, // rw - &motors[0].vel_integrator_gain, // rw - &motors[0].vel_integrator_current, // rw - &motors[0].vel_limit, // rw - &motors[0].current_setpoint, // rw - &motors[0].calibration_current, // rw - &motors[0].phase_inductance, // ro - &motors[0].phase_resistance, // ro - &motors[0].current_meas.phB, // ro - &motors[0].current_meas.phC, // ro - &motors[0].DC_calib.phB, // rw - &motors[0].DC_calib.phC, // rw - &motors[0].shunt_conductance, // rw - &motors[0].phase_current_rev_gain, // rw - &motors[0].current_control.current_lim, // rw - &motors[0].current_control.p_gain, // rw - &motors[0].current_control.i_gain, // rw - &motors[0].current_control.v_current_control_integral_d, // rw - &motors[0].current_control.v_current_control_integral_q, // rw - &motors[0].current_control.Ibus, // ro - &motors[0].encoder.phase, // ro - &motors[0].encoder.pll_pos, // rw - &motors[0].encoder.pll_vel, // rw - &motors[0].encoder.pll_kp, // rw - &motors[0].encoder.pll_ki, // rw - &motors[1].pos_setpoint, // rw - &motors[1].pos_gain, // rw - &motors[1].vel_setpoint, // rw - &motors[1].vel_gain, // rw - &motors[1].vel_integrator_gain, // rw - &motors[1].vel_integrator_current, // rw - &motors[1].vel_limit, // rw - &motors[1].current_setpoint, // rw - &motors[1].calibration_current, // rw - &motors[1].phase_inductance, // ro - &motors[1].phase_resistance, // ro - &motors[1].current_meas.phB, // ro - &motors[1].current_meas.phC, // ro - &motors[1].DC_calib.phB, // rw - &motors[1].DC_calib.phC, // rw - &motors[1].shunt_conductance, // rw - &motors[1].phase_current_rev_gain, // rw - &motors[1].current_control.current_lim, // rw - &motors[1].current_control.p_gain, // rw - &motors[1].current_control.i_gain, // rw - &motors[1].current_control.v_current_control_integral_d, // rw - &motors[1].current_control.v_current_control_integral_q, // rw - &motors[1].current_control.Ibus, // ro - &motors[1].encoder.phase, // ro - &motors[1].encoder.pll_pos, // rw - &motors[1].encoder.pll_vel, // rw - &motors[1].encoder.pll_kp, // rw - &motors[1].encoder.pll_ki, // rw -}; - -int* exposed_ints[] = { - (int*)&motors[0].control_mode, // rw - &motors[0].encoder.encoder_offset, // rw - &motors[0].encoder.encoder_state, // ro - &motors[0].error, // rw - (int*)&motors[1].control_mode, // rw - &motors[1].encoder.encoder_offset, // rw - &motors[1].encoder.encoder_state, // ro - &motors[1].error, // rw -}; - -bool* exposed_bools[] = { - &motors[0].thread_ready, // ro - &motors[0].enable_control, // rw - &motors[0].do_calibration, // rw - &motors[0].calibration_ok, // ro - &motors[1].thread_ready, // ro - &motors[1].enable_control, // rw - &motors[1].do_calibration, // rw - &motors[1].calibration_ok, // ro -}; - -uint16_t* exposed_uint16[] = { - &motors[0].control_deadline, // rw - &motors[0].last_cpu_time, // ro - &motors[1].control_deadline, // rw - &motors[1].last_cpu_time, // ro -}; - /* Private function prototypes -----------------------------------------------*/ // Command Handling -static void print_monitoring(int limit); + // Utility static uint16_t check_timing(Motor_t* motor); static void global_fault(int error); @@ -361,27 +268,7 @@ static void control_motor_loop(Motor_t* motor); // TODO move to different file //-------------------------------- -static void print_monitoring(int limit) { - for (int i=0;ipos_setpoint = pos_setpoint; @@ -410,109 +297,6 @@ void set_current_setpoint(Motor_t* motor, float current_setpoint) { #endif } -void motor_parse_cmd(uint8_t* buffer, int len) { - - // TODO very hacky way of terminating sscanf at end of buffer: - // We should do some proper struct packing instead of using sscanf altogether - buffer[len] = 0; - - // check incoming packet type - if (buffer[0] == 'p') { - // position control - unsigned motor_number; - float pos_setpoint, vel_feed_forward, current_feed_forward; - int numscan = sscanf((const char*)buffer, "p %u %f %f %f", &motor_number, &pos_setpoint, &vel_feed_forward, ¤t_feed_forward); - if (numscan == 4 && motor_number < num_motors) { - set_pos_setpoint(&motors[motor_number], pos_setpoint, vel_feed_forward, current_feed_forward); - } - } else if (buffer[0] == 'v') { - // velocity control - unsigned motor_number; - float vel_feed_forward, current_feed_forward; - int numscan = sscanf((const char*)buffer, "v %u %f %f", &motor_number, &vel_feed_forward, ¤t_feed_forward); - if (numscan == 3 && motor_number < num_motors) { - set_vel_setpoint(&motors[motor_number], vel_feed_forward, current_feed_forward); - } - } else if (buffer[0] == 'c') { - // current control - unsigned motor_number; - float current_feed_forward; - int numscan = sscanf((const char*)buffer, "c %u %f", &motor_number, ¤t_feed_forward); - if (numscan == 2 && motor_number < num_motors) { - set_current_setpoint(&motors[motor_number], current_feed_forward); - } - } else if (buffer[0] == 'g') { // GET - // g <0:float,1:int,2:bool,3:uint16> index - int type = 0; - int index = 0; - int numscan = sscanf((const char*)buffer, "g %u %u", &type, &index); - if (numscan == 2) { - switch(type){ - case 0: { - printf("%f\n",*exposed_floats[index]); - break; - }; - case 1: { - printf("%d\n",*exposed_ints[index]); - break; - }; - case 2: { - printf("%d\n",*exposed_bools[index]); - break; - }; - case 3: { - printf("%hu\n",*exposed_uint16[index]); - break; - }; - } - } - } else if (buffer[0] == 's') { // SET - // s <0:float,1:int,2:bool,3:uint16> index value - int type = 0; - int index = 0; - int numscan = sscanf((const char*)buffer, "s %u %u", &type, &index); - if (numscan == 2) { - switch(type) { - case 0: { - sscanf((const char*)buffer, "s %u %u %f", &type, &index, exposed_floats[index]); - break; - }; - case 1: { - sscanf((const char*)buffer, "s %u %u %d", &type, &index, exposed_ints[index]); - break; - }; - case 2: { - int btmp = 0; - sscanf((const char*)buffer, "s %u %u %d", &type, &index, &btmp); - *exposed_bools[index] = btmp ? true : false; - break; - }; - case 3: { - sscanf((const char*)buffer, "s %u %u %hu", &type, &index, exposed_uint16[index]); - break; - }; - } - } - } else if (buffer[0] == 'm') { // Setup Monitor - // m <0:float,1:int,2:bool,3:uint16> index monitoring_slot - int type = 0; - int index = 0; - int slot = 0; - int numscan = sscanf((const char*)buffer, "m %u %u %u", &type, &index, &slot); - if (numscan == 3) { - monitoring_slots[slot].type = type; - monitoring_slots[slot].index = index; - } - } else if (buffer[0] == 'o') { // Output Monitor - int limit = 0; - int numscan = sscanf((const char*)buffer, "o %u", &limit); - if (numscan == 1) { - print_monitoring(limit); - } - } -} - - //-------------------------------- // Utility //-------------------------------- @@ -1050,6 +834,7 @@ static bool motor_calibration(Motor_t* motor){ // Test functions //-------------------------------- +__attribute__((unused)) static void scan_motor_loop(Motor_t* motor, float omega, float voltage_magnitude) { for (;;) { for (float ph = 0.0f; ph < 2.0f * M_PI; ph += omega * current_meas_period) { @@ -1069,6 +854,7 @@ static void scan_motor_loop(Motor_t* motor, float omega, float voltage_magnitude } //TODO integrate as mode in main control loop +__attribute__((unused)) static void FOC_voltage_loop(Motor_t* motor, float v_d, float v_q) { for (;;) { osSignalWait(M_SIGNAL_PH_CURRENT_MEAS, osWaitForever); diff --git a/MotorControl/low_level.h b/MotorControl/low_level.h index 5f0f7f80..5df86f39 100644 --- a/MotorControl/low_level.h +++ b/MotorControl/low_level.h @@ -142,10 +142,17 @@ typedef struct{ int index; } monitoring_slot; +typedef enum { + SERIAL_PRINTF_IS_NONE, + SERIAL_PRINTF_IS_USB, + SERIAL_PRINTF_IS_UART, +} SerialPrintf_t; + /* Exported constants --------------------------------------------------------*/ extern float vbus_voltage; extern Motor_t motors[]; extern const int num_motors; +extern SerialPrintf_t serial_printf_select; /* Exported variables --------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/ @@ -165,7 +172,4 @@ void vbus_sense_adc_cb(ADC_HandleTypeDef* hadc, bool injected); //@TODO move motor thread to high level file void motor_thread(void const * argument); -//@TODO move cmd parsing to high level file -void motor_parse_cmd(uint8_t* buffer, int len); - #endif //__LOW_LEVEL_H diff --git a/Src/freertos.c b/Src/freertos.c index a61e7ee9..b8cee15a 100644 --- a/Src/freertos.c +++ b/Src/freertos.c @@ -54,15 +54,14 @@ /* USER CODE BEGIN Includes */ #include "freertos_vars.h" #include "low_level.h" -#include "usart.h" -#include "version.h" +#include "commands.h" /* USER CODE END Includes */ /* Variables -----------------------------------------------------------------*/ osThreadId defaultTaskHandle; /* USER CODE BEGIN Variables */ -extern PCD_HandleTypeDef hpcd_USB_OTG_FS; + /* USER CODE END Variables */ /* Function prototypes -------------------------------------------------------*/ @@ -143,89 +142,6 @@ void StartDefaultTask(void const * argument) /* USER CODE BEGIN Application */ -//TODO move this to a different file -// Thread to handle deffered processing of USB interrupt -void usb_cmd_thread(void const * argument) { - - //DMA open loop continous circular buffer - //1ms delay periodic, chase DMA ptr around, on new data: - // Check for start char - // copy into parse-buffer - // check for end-char - // checksum, etc. - - #define UART_BUFFER_SIZE 64 - static uint8_t dma_circ_buffer[UART_BUFFER_SIZE]; - static uint8_t parse_buffer[UART_BUFFER_SIZE]; - - // DMA is set up to recieve in a circular buffer forever. - // We dont use interrupts to fetch the data, instead we periodically read - // data out of the circular buffer into a parse buffer, controlled by a state machine - HAL_UART_Receive_DMA(&huart4, dma_circ_buffer, sizeof(dma_circ_buffer)); - - uint32_t last_rcv_idx = UART_BUFFER_SIZE - huart4.hdmarx->Instance->NDTR; - // Re-run state-machine forever - for (;;) { - //Inialize recieve state machine - bool reset_read_state = false; - bool read_active = false; - uint32_t parse_buffer_idx = 0; - //Run state machine until reset - do { - // Fetch the circular buffer "write pointer", where it would write next - uint32_t rcv_idx = UART_BUFFER_SIZE - huart4.hdmarx->Instance->NDTR; - // During sleeping, we may have fallen several characters behind, so we keep - // going until we are caught up, before we sleep again - while (rcv_idx != last_rcv_idx) { - // Fetch the next char, rotate read ptr - uint8_t c = dma_circ_buffer[last_rcv_idx]; - if (++last_rcv_idx == UART_BUFFER_SIZE) - last_rcv_idx = 0; - // Look for start character - if (c == '$') { - read_active = true; - continue; // do not record start char - } - // Record into parse buffer when actively reading - if (read_active) { - parse_buffer[parse_buffer_idx++] = c; - if (c == '\r' || c == '\n' || c == '!') { - // End of command string: exchange end char with terminating null - parse_buffer[parse_buffer_idx-1] = '\0'; - motor_parse_cmd(parse_buffer, parse_buffer_idx); - // Reset receieve state machine - reset_read_state = true; - break; - } else if (parse_buffer_idx == UART_BUFFER_SIZE - 1) { - // We are not at end of command, and receiving another character after this - // would go into the last slot, which is reserved for terminating null. - // We have effectively overflowed parse buffer: abort. - reset_read_state = true; - break; - } - } - } - // When we reach here, we are out of immediate characters to fetch out of buffer - // So we sleep for a bit. - osDelay(1); - } while (!reset_read_state); - } - - for (;;) { - // Wait for signalling from USB interrupt (OTG_FS_IRQHandler) - osSemaphoreWait(sem_usb_irq, osWaitForever); - // Irq processing loop - //while(HAL_NVIC_GetActive(OTG_FS_IRQn)) { - HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); - //} - // Let the irq (OTG_FS_IRQHandler) fire again. - HAL_NVIC_EnableIRQ(OTG_FS_IRQn); - } - - // If we get here, then this task is done - vTaskDelete(osThreadGetId()); -} - /* USER CODE END Application */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Src/syscalls.c b/Src/syscalls.c index 7a2e590a..d8fd9283 100644 --- a/Src/syscalls.c +++ b/Src/syscalls.c @@ -7,6 +7,7 @@ #include #include "usbd_cdc_if.h" +#include //int _read(int file, char *data, int len) {} //int _close(int file) {} diff --git a/Src/usbd_cdc_if.c b/Src/usbd_cdc_if.c index 862cd359..a9d9d29c 100644 --- a/Src/usbd_cdc_if.c +++ b/Src/usbd_cdc_if.c @@ -50,7 +50,7 @@ #include "usbd_cdc_if.h" /* USER CODE BEGIN INCLUDE */ #include "utils.h" -#include "low_level.h" +#include "commands.h" /* USER CODE END INCLUDE */ /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY