void Watchdog_Init() { __WWDG_CLK_ENABLE(); /*##-2- Configure the WWDG peripheral ######################################*/ /* WWDG clock counter = (PCLK1 (32MHz)/4096)/8) = 976.6 Hz (~1024 us) WWDG Window value = 80 means that the WWDG counter should be refreshed only when the counter is below 80 (and greater than 64) otherwise a reset will be generated. WWDG Counter value = 127, WWDG timeout = ~1024 us * 64 = 65.536 ms In this case the refresh window is: ~1024 * (127-80) = 48.128 ms < refresh window < ~1024 * 64 = 65.536 ms */ WatchdogHandle.Instance = WWDG; WatchdogHandle.Init.Prescaler = WWDG_PRESCALER_8; WatchdogHandle.Init.Window = 0x7F; WatchdogHandle.Init.Counter = 0x7F; HAL_WWDG_Init(&WatchdogHandle); /*##-3- Start the WWDG #####################################################*/ HAL_WWDG_Start(&WatchdogHandle); // Timer_For_Main_Loop_Init(); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* STM32F2xx HAL library initialization: - Configure the Flash prefetch, instruction and Data caches - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); /* Configure the system clock to 120 MHz */ SystemClock_Config(); /* Configure LED1, LED2, LED3 */ BSP_LED_Init(LED1); BSP_LED_Init(LED2); BSP_LED_Init(LED3); /* Configure User push-button */ BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI); /*##-1- Check if the system has resumed from WWDG reset ####################*/ if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET) { /* WWDGRST flag set: Turn LED1 on */ BSP_LED_On(LED1); /* Clear reset flags */ __HAL_RCC_CLEAR_RESET_FLAGS(); } else { /* WWDGRST flag is not set: Turn LED1 off */ BSP_LED_Off(LED1); } /*##-2- Configure the WWDG peripheral ######################################*/ /* WWDG clock counter = (PCLK1 (30MHz)/4096)/8) = 915 Hz (~1092 us) WWDG Window value = 80 means that the WWDG counter should be refreshed only when the counter is below 80 (and greater than 64/0x40) otherwise a reset will be generated. WWDG Counter value = 127, WWDG timeout = ~1092 us * 64 = 70 ms */ WwdgHandle.Instance = WWDG; WwdgHandle.Init.Prescaler = WWDG_PRESCALER_8; WwdgHandle.Init.Window = 80; WwdgHandle.Init.Counter = 127; if (HAL_WWDG_Init(&WwdgHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /*##-3- Start the WWDG #####################################################*/ if (HAL_WWDG_Start(&WwdgHandle) != HAL_OK) { Error_Handler(); } /* Infinite loop */ while (1) { /* Toggle LED2 */ BSP_LED_Toggle(LED2); /* Insert 60 ms delay */ HAL_Delay(60); /* Refresh WWDG: update counter value to 127, the refresh window is: between 51 ms (~1092 * (127-80)) and 70 ms (~1092 * 64) */ if (HAL_WWDG_Refresh(&WwdgHandle, 127) != HAL_OK) { Error_Handler(); } } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* STM32F3xx HAL library initialization: - Configure the Flash prefetch - Systick timer is configured by default as source of time base, but user can eventually implement his proper time base source (a general purpose timer for example or other time source), keeping in mind that Time base duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and handled in milliseconds basis. - Set NVIC Group Priority to 4 - Low Level Initialization */ HAL_Init(); /* Configure LED1, LED2, LED3 */ BSP_LED_Init(LED1); BSP_LED_Init(LED2); BSP_LED_Init(LED3); /* Configure the system clock to 72 MHz */ SystemClock_Config(); /* Configure Key push-button */ BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI); /*##-1- Check if the system has resumed from WWDG reset ####################*/ if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET) { /* WWDGRST flag set: Turn LED1 on */ BSP_LED_On(LED1); /* Clear reset flags */ __HAL_RCC_CLEAR_RESET_FLAGS(); } else { /* WWDGRST flag is not set: Turn LED1 off */ BSP_LED_Off(LED1); } /*##-2- Configure the WWDG peripheral ######################################*/ /* WWDG clock counter = (PCLK1 (36MHz)/4096)/8) = 1098 Hz (~910 us) WWDG Window value = 80 means that the WWDG counter should be refreshed only when the counter is below 80 (and greater than 64/0x40) otherwise a reset will be generated. WWDG Counter value = 127, WWDG timeout = ~910 us * 64 = 58.24 ms */ WwdgHandle.Instance = WWDG; WwdgHandle.Init.Prescaler = WWDG_PRESCALER_8; WwdgHandle.Init.Window = 80; WwdgHandle.Init.Counter = 127; if (HAL_WWDG_Init(&WwdgHandle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /*##-3- Start the WWDG #####################################################*/ if (HAL_WWDG_Start(&WwdgHandle) != HAL_OK) { Error_Handler(); } /* Infinite loop */ while (1) { /* Toggle LED2 */ BSP_LED_Toggle(LED2); /* Insert 45 ms delay */ HAL_Delay(45); /* Refresh WWDG: update counter value to 127, the refresh window is: between 42.7ms (~910 * (127-80)) and 58.24 ms (~910 * 64) */ if (HAL_WWDG_Refresh(&WwdgHandle, 127) != HAL_OK) { Error_Handler(); } } }
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)