char* combine_path(char *iter, const char *beg, const char *end, const char *path, char** psplitter) { assert(beg<=end); assert(iter>=beg); assert(iter<=end); char *splitter=iter; const char *read=path; unsigned len; bool volume=false; char c; while(iter!=end) { c=*read++; if(c==0) break; if(!is_splitter(c)) { *iter++=c; continue; } len=iter-splitter; if(len<1) continue; if(*splitter=='.') { if(len==1) { iter=splitter; continue; } else if(len==2 && splitter[1]=='.') { if(splitter==beg) { if(volume) { iter=const_cast<char*>(beg); continue; } beg=iter+1; } else { char *last=splitter-2; while(last>beg) { if(*last==xfilepath::ms_splitter) { ++last; break; } --last; } assert(last>=beg); len=splitter-last-1; if(len==2 && *last=='.' && last[1]=='.') { beg=iter+1; } else if(last[len-1]==':') { iter=splitter; beg=splitter; volume=true; continue; } else { iter=last; splitter=last; continue; } } } } else if(splitter[len-1]==':') { beg=iter+1; volume=true; } *iter++=xfilepath::ms_splitter; splitter=iter; } if(psplitter) *psplitter=splitter; return iter; }
int main(void) { /* USER CODE BEGIN 1 */ // create pointer to MX_SPI_Init() function in order to use it in utility functions MX_SPI1_Init_Pointer = &MX_SPI1_Init; /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); //MX_SPI1_Init(); MX_TIM16_Init(); MX_TIM17_Init(); MX_USART1_UART_Init(); MX_USART2_UART_Init(); MX_WWDG_Init(); /* USER CODE BEGIN 2 */ // delete MX_SPI1_Init(); up there after regenerating code with mx cube //================================================================================= /// some basic setups //================================================================================= // input is up // output is down uart_queue_initialize(&uart_input_queue); uart_queue_initialize(&uart_output_queue); uart_queue_initialize(&uart_command_queue); // load setup_data from flash to struct: config_data_flash_struct setup_data; get_from_Flash(); LED_init(); if(setup_data.initied_0xAA!=0xAA) { reset_joint(); } part_init(); /// FIND DIRECTION = WAIT FOR FIRST 'R' DIRECTION_SET = 0; PROGRAMM_SENSOR = 0; SET_FLASH = 0; UP_STATE = IDLE; DOWN_STATE = IDLE; // init some huart stuff huart_DOWN = &huart1; huart_UP = &huart2; uint16_t si = 0; data_mode = 0; HAL_StatusTypeDef status; // create empty messages Line empty_command_line; empty_command_line.text[0] = empty; for(si=1; si < DOWN_MESSAGE_LENGTH-1; si++) { empty_command_line.text[si] = si; } empty_command_line.text[DOWN_MESSAGE_LENGTH-1] = ComputeCRCN(empty_command_line.text, DOWN_MESSAGE_LENGTH-1); empty_command_line.length = DOWN_MESSAGE_LENGTH; Line empty_up_line; empty_up_line.text[0] = empty; for(si=1; si < UP_MESSAGE_LENGTH-1; si++) { empty_up_line.text[si] = si; } empty_up_line.text[UP_MESSAGE_LENGTH-1] = ComputeCRCN(empty_up_line.text, UP_MESSAGE_LENGTH-1); empty_up_line.length = UP_MESSAGE_LENGTH; // start timer HAL_TIM_Base_Start(&htim16); HAL_TIM_Base_Start(&htim17); // send some initial init messages uart_queue_push_line(&uart_input_queue, &init_message_line); if(is_splitter(setup_data.type)) { for(si = 0; si < 8; si++) { if(setup_data.splitter_outputs[si]==1) { uart_queue_push_line(&uart_input_queue, &splitter_message_lines[si]); skc[si] = 1; } } } int redled_timeout_timer = __HAL_TIM_GetCounter(&htim16); int init_timout_timer = __HAL_TIM_GetCounter(&htim16); interrupt_up_timeout_time = __HAL_TIM_GetCounter(&htim16); interrupt_down_timeout_time = __HAL_TIM_GetCounter(&htim16); int new_sensor_timer = __HAL_TIM_GetCounter(&htim16); int up_timeout_timer = __HAL_TIM_GetCounter(&htim16); int kids_timer[] = {-1,-1,-1,-1,-1,-1,-1,-1}; transmittedUP=0; receivedUP=0; transmittedDOWN=0; receivedDOWN=0; uint8_t TIMEDOUT = 0; update_sensor_messages(); HAL_HalfDuplex_EnableTransmitterReceiver(huart_DOWN); HAL_HalfDuplex_EnableTransmitterReceiver(huart_UP); HAL_UART_Receive_DMA(huart_UP, up_buffer, DOWN_MESSAGE_LENGTH + 1); HAL_UART_Receive_DMA(huart_DOWN, down_buffer, DOWN_MESSAGE_LENGTH + 1); led_set(1, 1, 0); //while(1); //if(is_splitter(setup_data.type)) HAL_WWDG_Start(&hwwdg); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ get_up_time = __HAL_TIM_GetCounter(&htim16); uint8_t WDGO = 0; uint8_t WDSET = 0; while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ // if((WD_UP && WD_DOWN) || DIRECTION_SET==0) // { // WD_UP = 0; // WD_DOWN = 0; // // for up and dwn we have own flags // // HAL_WWDG_Refresh(&hwwdg, 127); // } if(DIRECTION_SET && WDSET==0) { HAL_WWDG_Start(&hwwdg); WDSET = 1; up_timeout_timer = __HAL_TIM_GetCounter(&htim16); } if(WDGO==0 || is_splitter(setup_data.type)==0) { HAL_WWDG_Refresh(&hwwdg, 127); } // if there was no poll from above a certain time = reset! if(__HAL_TIM_GetCounter(&htim16) - interrupt_up_timeout_time > 250) { WDGO = 1; get_up(1); interrupt_up_timeout_time = __HAL_TIM_GetCounter(&htim16); UP_STATE = IDLE; } // if there was no interrupt call for data from below if(__HAL_TIM_GetCounter(&htim16) - interrupt_down_timeout_time > 250) { WDGO = 1; HAL_UART_DMAStop(huart_DOWN); HAL_UART_DMAResume(huart_DOWN); if(!DIRECTION_SET) { HAL_HalfDuplex_EnableTransmitterReceiver(huart_DOWN); HAL_UART_Receive_DMA(huart_DOWN, down_buffer, DOWN_MESSAGE_LENGTH + 1); } interrupt_down_timeout_time = __HAL_TIM_GetCounter(&htim16); DOWN_STATE = IDLE; } // wait for directions to be set if(!DIRECTION_SET) { led_set(8, 1, 8); continue; } led_set(8, 0, 8); if(__HAL_TIM_GetCounter(&htim16) - get_up_time > 20 && receivedUP == 0) { get_up(0); } // red blinking led if(__HAL_TIM_GetCounter(&htim16) - redled_timeout_timer > 250) { HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); redled_timeout_timer = __HAL_TIM_GetCounter(&htim16); } if(__HAL_TIM_GetCounter(&htim16) - up_timeout_timer > 500) { WDGO = 1; } // sent init messages if(__HAL_TIM_GetCounter(&htim16) - init_timout_timer > 1000) { uart_queue_replace_push_line(&uart_input_queue, &init_message_line, setup_data.id); if(is_splitter(setup_data.type)) { for(si = 0; si < 8; si++) { if(setup_data.splitter_outputs[si]==1) { uart_queue_push_line(&uart_input_queue, &splitter_message_lines[si]); } } } init_timout_timer = __HAL_TIM_GetCounter(&htim16); } if(SET_FLASH && UP_STATE == IDLE && DOWN_STATE == IDLE) { HAL_HalfDuplex_EnableTransmitter(huart_UP); set_in_Flash(&setup_data); SET_FLASH = 0; get_up(1); } if(PROGRAMM_SENSOR && UP_STATE == IDLE && DOWN_STATE == IDLE) { HAL_HalfDuplex_EnableTransmitter(huart_UP); if(setup_data.hardware == 2) init_2D(hspi1, GPIOA, GPIO_PIN_3); else init_2D(hspi1, GPIOB, GPIO_PIN_1); PROGRAMM_SENSOR = 0; get_up(1); } /// UP_STATE_MACHINE switch(UP_STATE) { case IDLE: if(SET_FLASH || PROGRAMM_SENSOR) { UP_STATE = IDLE; break; } if(receivedUP) { receivedUP = 0; if(up_buffer[0] == poll_receive /*&& __HAL_TIM_GetCounter(&htim16) - receivedUPtime < 5*/) { if(UP_RESEND_MESSAGE==0) { //update_sensor_messages(); uint8_t n_up_messages = 0; while(uart_queue_is_empty(&uart_input_queue)==0 && (n_up_messages < UP_MESSAGES_MAX)) { uart_queue_pop_line(&uart_input_queue, &send_up_line); memcpy(&poll_up_buffer[n_up_messages*(UP_MESSAGE_LENGTH)], send_up_line.text, UP_MESSAGE_LENGTH); n_up_messages++; } while(n_up_messages < UP_MESSAGES_MAX) { memcpy(&poll_up_buffer[n_up_messages*(UP_MESSAGE_LENGTH)], empty_up_line.text, UP_MESSAGE_LENGTH); n_up_messages++; } poll_up_size = n_up_messages*UP_MESSAGE_LENGTH; } UP_RESEND_MESSAGE = 0; UP_STATE = SENDING; HAL_HalfDuplex_EnableTransmitter(huart_UP); HAL_UART_Transmit_DMA(huart_UP, poll_up_buffer, poll_up_size); int something_else = __HAL_TIM_GetCounter(&htim16); if(up_buffer[1]!=empty) { memcpy(command_in_line.text, &up_buffer[1], DOWN_MESSAGE_LENGTH); command_in_line.length = DOWN_MESSAGE_LENGTH; uint8_t checksum = ComputeCRCN(command_in_line.text, DOWN_MESSAGE_LENGTH-1); if(checksum == command_in_line.text[DOWN_MESSAGE_LENGTH-1]) { if(command_in_line.text[0] == poll_direct || getIDfromMessage(command_in_line.text)==setup_data.id) { uart_queue_push_line(&uart_command_queue, &command_in_line); if((command_in_line.text[0] == poll_send) && (setup_data.type==NODE_JOINT_TUT_TU)) uart_queue_push_line(&uart_output_queue, &command_in_line); } else if(getIDfromMessage(command_in_line.text)==BROADCAST_ID) { uart_queue_push_line(&uart_command_queue, &command_in_line); uart_queue_push_line(&uart_output_queue, &command_in_line); } else { uart_queue_push_line(&uart_output_queue, &command_in_line); } } } if(is_splitter(setup_data.type)) { /*__disable_irq(); delayUS(10000); __enable_irq();*/ } else { update_sensor_messages(); } up_timeout_time = __HAL_TIM_GetCounter(&htim16); } else { //HAL_UART_DMAStop(huart_UP); //HAL_UART_DMAResume(huart_UP); // HAL_UART_Receive(huart_UP, &up_buffer[1], DOWN_MESSAGE_LENGTH, 2); get_up(1); } } break; case SENDING: if(transmittedUP) { UP_STATE = END; transmittedUP = 0; } else if(__HAL_TIM_GetCounter(&htim16) - up_timeout_time > 10) { HAL_UART_DMAStop(huart_UP); HAL_UART_DMAResume(huart_UP); UP_STATE = END; } break; case END: WD_UP = 1; up_timeout_timer = __HAL_TIM_GetCounter(&htim16); // work on commands UP_STATE = IDLE; get_up(1); break; } uint8_t s=0; switch(DOWN_STATE) { case DELAY: if(is_splitter(setup_data.type) || (__HAL_TIM_GetCounter(&htim16) - down_timeout_time > 7) /* && TIMEDOUT==0 */) DOWN_STATE = IDLE; /*else if (__HAL_TIM_GetCounter(&htim16) - down_timeout_time > 5) DOWN_STATE = IDLE;*/ break; case IDLE: // do nothing if(SET_FLASH || PROGRAMM_SENSOR) { DOWN_STATE = IDLE; break; } if(is_splitter(setup_data.type)) { if(splitter_kids_counter[i_p_splitter] > 10) { splitter_kids_counter[i_p_splitter] = 9; kids_timer[i_p_splitter] = __HAL_TIM_GetCounter(&htim16) + 200; } if(kids_timer[i_p_splitter]!=-1 && kids_timer[i_p_splitter] > __HAL_TIM_GetCounter(&htim16)) { interrupt_down_timeout_time = __HAL_TIM_GetCounter(&htim16); DOWN_STATE = END; break; } if(skc[i_p_splitter] == 0) { send_down_line = send_down_line_now; } else { send_down_line = empty_command_line; } } if(skc[0]+skc[1]+skc[2]+skc[3]+skc[4]+skc[5]+skc[6]+skc[7] >= n_splitter) { if(uart_queue_is_empty(&uart_output_queue)==0) { uart_queue_pop_line(&uart_output_queue, &send_down_line_now); send_down_line = send_down_line_now; for(s=0; s<n_splitter; s++) skc[s] = 0; } else { send_down_line = empty_command_line; for(s=0; s<n_splitter; s++) skc[s] = 1; } } //send_down_line = empty_command_line; if(is_splitter(setup_data.type)) { MPX_UART_Open(i_p_splitter); } DOWN_STATE = RECEIVING; //__disable_irq(); HAL_HalfDuplex_EnableTransmitter(huart_DOWN); status = HAL_UART_Transmit(huart_DOWN, "R", 1, 3); status = HAL_UART_Transmit(huart_DOWN, send_down_line.text, DOWN_MESSAGE_LENGTH, 5); //__enable_irq(); // DMA Receive for 3 HAL_HalfDuplex_EnableTransmitterReceiver(huart_DOWN); HAL_UART_Receive_DMA(huart_DOWN, poll_down_buffer, UP_MESSAGE_LENGTH*UP_MESSAGES_MAX); down_timeout_time = __HAL_TIM_GetCounter(&htim16); break; case RECEIVING: if(receivedDOWN) { receivedDOWN = 0; splitter_kids_counter[i_p_splitter] = 0; skc[i_p_splitter] = 1; kids_timer[i_p_splitter] = -1; // no more transmitting checksum, only calculating uint8_t checksum = ComputeCRCN(&poll_down_buffer[poll_down_size-UP_MESSAGE_LENGTH], UP_MESSAGE_LENGTH-1); uint8_t i = 0; for(i=0; i<UP_MESSAGES_MAX; i++) { // check checksum if(1 /*checksum == poll_down_buffer[i*UP_MESSAGE_LENGTH-1]*/) { Line sensor_message_line; memcpy(sensor_message_line.text, &poll_down_buffer[i*UP_MESSAGE_LENGTH], UP_MESSAGE_LENGTH); sensor_message_line.length = UP_MESSAGE_LENGTH; if(sensor_message_line.text[0]==empty) break; // delete messages from T joint but the answer_data, there update angles[3] if(getIDfromMessage(sensor_message_line.text)==setup_data.id && setup_data.type == NODE_JOINT_TUT_TU && data_mode!=2) { if(sensor_message_line.text[0] == answer_data) angles[3] = ((sensor_message_line.text[15] << 8) & 0xFF00) + sensor_message_line.text[16]; } else // for the other kinds (splitter, init, data from other) replace them if already in queue, ack messages always add to queue { // if it's from own child, add own id if(sensor_message_line.text[5]==0) { sensor_message_line.text[5] = (setup_data.id >> 24) & 0xFF; sensor_message_line.text[6] = (setup_data.id >> 16) & 0xFF; sensor_message_line.text[7] = (setup_data.id >> 8) & 0xFF; sensor_message_line.text[8] = setup_data.id & 0xFF; // add splitter branch number if(is_splitter(setup_data.type)) sensor_message_line.text[5] |= ((i_p_splitter << 4) & 0xF0); } UpdateCRCLine(&sensor_message_line); if(sensor_message_line.text[0] == answer_ack || sensor_message_line.text[0] == splitter) uart_queue_push_line(&uart_input_queue, &sensor_message_line); else uart_queue_replace_push_line(&uart_input_queue, &sensor_message_line, getIDfromMessage(sensor_message_line.text)); } } } DOWN_STATE = END; TIMEDOUT = 0; } else if(__HAL_TIM_GetCounter(&htim16) - down_timeout_time > 13)