// This routine reads back two timers and combines the result into one 32 bit value // ticked at 1uS. Using ReadHighPrecisionCounter and ClearHighPrecisionCounter the combination // of these timers create a 32 bit hardware counter being ticked at 1uS. These are used for // delays in the code. The reality is a counter which wraps at 1hr 11mins. uint32_t ReadHighPrecisionCounter(void) { uint32_t uCountResult = 0; uCountResult = __HAL_TIM_GetCounter(&htim3) << 16; uCountResult = uCountResult | __HAL_TIM_GetCounter(&htim2); return uCountResult; }
void timer_irq_handler(void) { // Channel 1 for mbed timeout if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) { if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC1) == SET) { __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1); us_ticker_irq_handler(); } } // Channel 2 for HAL tick if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC2) == SET) { if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC2) == SET) { __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC2); uint32_t val = __HAL_TIM_GetCounter(&TimMasterHandle); if ((val - PreviousVal) >= HAL_TICK_DELAY) { // Increment HAL variable HAL_IncTick(); // Prepare next interrupt __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, val + HAL_TICK_DELAY); PreviousVal = val; #if 0 // For DEBUG only HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6); #endif } } } }
// Reconfigure the HAL tick using a standard timer instead of systick. HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { RCC_ClkInitTypeDef RCC_ClkInitStruct; uint32_t PclkFreq; // Get clock configuration // Note: PclkFreq contains here the Latency (not used after) HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &PclkFreq); // Get TIM5 clock value PclkFreq = HAL_RCC_GetPCLK1Freq(); // Enable timer clock TIM_MST_RCC; // Reset timer TIM_MST_RESET_ON; TIM_MST_RESET_OFF; // Configure time base TimMasterHandle.Instance = TIM_MST; TimMasterHandle.Init.Period = 0xFFFFFFFF; // TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx if (RCC_ClkInitStruct.APB1CLKDivider == RCC_HCLK_DIV1) TimMasterHandle.Init.Prescaler = (uint16_t)((PclkFreq) / 1000000) - 1; // 1 us tick else TimMasterHandle.Init.Prescaler = (uint16_t)((PclkFreq * 2) / 1000000) - 1; // 1 us tick TimMasterHandle.Init.ClockDivision = 0; TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimMasterHandle.Init.RepetitionCounter = 0; HAL_TIM_OC_Init(&TimMasterHandle); NVIC_SetVector(TIM_MST_IRQ, (uint32_t)timer_irq_handler); NVIC_EnableIRQ(TIM_MST_IRQ); // Channel 1 for mbed timeout HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1); // Channel 2 for HAL tick HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_2); PreviousVal = __HAL_TIM_GetCounter(&TimMasterHandle); __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, PreviousVal + HAL_TICK_DELAY); __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2); #if 0 // For DEBUG only __GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); #endif return HAL_OK; }
// Reconfigure the HAL tick using a standard timer instead of systick. HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { // Enable timer clock TIM_MST_RCC; // Reset timer TIM_MST_RESET_ON; TIM_MST_RESET_OFF; // Update the SystemCoreClock variable SystemCoreClockUpdate(); // Configure time base TimMasterHandle.Instance = TIM_MST; TimMasterHandle.Init.Period = 0xFFFF; TimMasterHandle.Init.Prescaler = (uint32_t)(SystemCoreClock / 1000000) - 1; // 1 us tick TimMasterHandle.Init.ClockDivision = 0; TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP; HAL_TIM_Base_Init(&TimMasterHandle); // Configure output compare channel 1 for mbed timeout (enabled later when used) HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1); // Configure output compare channel 2 for HAL tick HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_2); PreviousVal = __HAL_TIM_GetCounter(&TimMasterHandle); __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, PreviousVal + HAL_TICK_DELAY); // Configure interrupts // Update interrupt used for 32-bit counter // Output compare channel 1 interrupt for mbed timeout // Output compare channel 2 interrupt for HAL tick NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)timer_update_irq_handler); NVIC_EnableIRQ(TIM_MST_UP_IRQ); NVIC_SetPriority(TIM_MST_UP_IRQ, 0); NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)timer_oc_irq_handler); NVIC_EnableIRQ(TIM_MST_OC_IRQ); NVIC_SetPriority(TIM_MST_OC_IRQ, 1); // Enable interrupts __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE); // For 32-bit counter __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2); // For HAL tick // Enable timer HAL_TIM_Base_Start(&TimMasterHandle); #if 0 // For DEBUG only __GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); #endif return HAL_OK; }
void prvExtCtrlHandler(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { GPIO_PinState xPinState = HAL_GPIO_ReadPin(GPIOx, GPIO_Pin); switch(xPinState) { case GPIO_PIN_SET: /* Rising edge */ if(GPIO_Pin == GPIO_PIN_0) xPitchTickTmp = __HAL_TIM_GetCounter(&xTimeBaseHandle); else if(GPIO_Pin == GPIO_PIN_1) xRollTickTmp = __HAL_TIM_GetCounter(&xTimeBaseHandle); else if(GPIO_Pin == GPIO_PIN_3) xYawTickTmp = __HAL_TIM_GetCounter(&xTimeBaseHandle); break; case GPIO_PIN_RESET: /* Falling edge */ if(GPIO_Pin == GPIO_PIN_0) xPitchTick = __HAL_TIM_GetCounter(&xTimeBaseHandle) - xPitchTickTmp; else if(GPIO_Pin == GPIO_PIN_1) xRollTick = __HAL_TIM_GetCounter(&xTimeBaseHandle) - xRollTickTmp; else if(GPIO_Pin == GPIO_PIN_3) xYawTick = __HAL_TIM_GetCounter(&xTimeBaseHandle) - xYawTickTmp; break; default: break; } __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); }
uint32_t HAL_QuadEncoder_Get_Count(int channel) { #ifdef ENABLE_QUAD_DECODERS uint32_t curr_count; if (channel < (sizeof(p_quad_encoder_channels)/sizeof(p_quad_encoder_channels[0]))){ curr_count = __HAL_TIM_GetCounter(p_quad_encoder_channels[channel]); } else { curr_count = 0; } return curr_count; #else return 0; #endif }
void test_Encoders(void) { ssd1306Init(0); ssd1306ClearScreen(); ssd1306Refresh(); Encoders_Init(); while(1) { ssd1306ClearScreen(); // ssd1306PrintInt(0, 6, "REV = ", toto, &Font_3x6); // ssd1306PrintInt(0, 13, "CNT = ", (&htim1)->Instance->CNT, &Font_3x6); ssd1306PrintInt(0, 7, "L_REV = ", left_encoder.nb_revolutions, &Font_3x6); ssd1306PrintInt(0, 14, "L_CNT = ", __HAL_TIM_GetCounter(&htim1), &Font_3x6); ssd1306PrintInt(0, 21, "L_DIR = ", __HAL_TIM_DIRECTION_STATUS(&htim1), &Font_3x6); ssd1306PrintInt(0, 35, "R_REV = ", right_encoder.nb_revolutions, &Font_3x6); ssd1306PrintInt(0, 42, "R_CNT = ", __HAL_TIM_GetCounter(&htim3), &Font_3x6); ssd1306PrintInt(0, 49, "R_DIR = ", __HAL_TIM_DIRECTION_STATUS(&htim3), &Font_3x6); ssd1306Refresh(); HAL_Delay(10); } }
/** * @brief Read encoder counter. */ int32_t encoder_read(void) { static uint32_t prev = 0x7FFFFFFF; uint32_t cur; int32_t result; cur = __HAL_TIM_GetCounter(&htim2); if ((cur - prev) < 0x7FFFFFFF) result = (int32_t)(cur - prev); else result = -(int32_t)(prev - cur); prev = cur; return -result; }
void timer_irq_handler(void) { uint16_t cnt_val = TIM_MST->CNT; TimMasterHandle.Instance = TIM_MST; // Clear Update interrupt flag if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) { if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_UPDATE) == SET) { __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_UPDATE); SlaveCounter++; } } // Channel 1 for mbed timeout if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) { if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC1) == SET) { __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1); if (oc_rem_part > 0) { set_compare(oc_rem_part); // Finish the remaining time left oc_rem_part = 0; } else { if (oc_int_part > 0) { set_compare(0xFFFF); oc_rem_part = cnt_val; // To finish the counter loop the next time oc_int_part--; } else { us_ticker_irq_handler(); } } } } // Channel 2 for HAL tick if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC2) == SET) { if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC2) == SET) { __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC2); uint32_t val = __HAL_TIM_GetCounter(&TimMasterHandle); if ((val - PreviousVal) >= HAL_TICK_DELAY) { // Increment HAL variable HAL_IncTick(); // Prepare next interrupt __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, val + HAL_TICK_DELAY); PreviousVal = val; } } } }
// Reconfigure the HAL tick using a standard timer instead of systick. HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { // Enable timer clock TIM_MST_RCC; // Reset timer TIM_MST_RESET_ON; TIM_MST_RESET_OFF; // Configure time base TimMasterHandle.Instance = TIM_MST; TimMasterHandle.Init.Period = 0xFFFFFFFF; if ( SystemCoreClock == 16000000 ) { TimMasterHandle.Init.Prescaler = (uint32_t)( SystemCoreClock / 1000000) - 1; // 1 µs tick } else { TimMasterHandle.Init.Prescaler = (uint32_t)( SystemCoreClock / 2 / 1000000) - 1; // 1 µs tick } TimMasterHandle.Init.ClockDivision = 0; TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimMasterHandle.Init.RepetitionCounter = 0; HAL_TIM_OC_Init(&TimMasterHandle); NVIC_SetVector(TIM_MST_IRQ, (uint32_t)timer_irq_handler); NVIC_EnableIRQ(TIM_MST_IRQ); // Channel 1 for mbed timeout HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1); // Channel 2 for HAL tick HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_2); PreviousVal = __HAL_TIM_GetCounter(&TimMasterHandle); __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, PreviousVal + HAL_TICK_DELAY); __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2); #if 0 // For DEBUG only __GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); #endif return HAL_OK; }
// Reconfigure the HAL tick using a standard timer instead of systick. HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { // Enable timer clock TIM_MST_RCC; // Reset timer TIM_MST_RESET_ON; TIM_MST_RESET_OFF; // Update the SystemCoreClock variable SystemCoreClockUpdate(); // Configure time base TimMasterHandle.Instance = TIM_MST; TimMasterHandle.Init.Period = 0xFFFFFFFF; TimMasterHandle.Init.Prescaler = (uint32_t)(SystemCoreClock / 1000000) - 1; // 1 us tick TimMasterHandle.Init.ClockDivision = 0; TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP; HAL_TIM_Base_Init(&TimMasterHandle); // Configure output compare channel 1 for mbed timeout (enabled later when used) HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1); // Configure output compare channel 2 for HAL tick HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_2); PreviousVal = __HAL_TIM_GetCounter(&TimMasterHandle); __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, PreviousVal + HAL_TICK_DELAY); // Configure interrupts // Update interrupt used for 32-bit counter // Output compare channel 1 interrupt for mbed timeout // Output compare channel 2 interrupt for HAL tick NVIC_SetVector(TIM_MST_IRQ, (uint32_t)timer_irq_handler); NVIC_EnableIRQ(TIM_MST_IRQ); // Enable interrupts __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_UPDATE); // For 32-bit counter __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC2); // For HAL tick // Enable timer HAL_TIM_Base_Start(&TimMasterHandle); return HAL_OK; }
// Used for mbed timeout (channel 1) and HAL tick (channel 2) void timer_oc_irq_handler(void) { uint16_t cval = TIM_MST->CNT; TimMasterHandle.Instance = TIM_MST; // Channel 1 for mbed timeout if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) { __HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1); if (oc_rem_part > 0) { set_compare(oc_rem_part); // Finish the remaining time left oc_rem_part = 0; } else { if (oc_int_part > 0) { set_compare(0xFFFF); oc_rem_part = cval; // To finish the counter loop the next time oc_int_part--; } else { us_ticker_irq_handler(); } } } // Channel 2 for HAL tick if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC2) == SET) { __HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC2); uint32_t val = __HAL_TIM_GetCounter(&TimMasterHandle); if ((val - PreviousVal) >= HAL_TICK_DELAY) { // Increment HAL variable HAL_IncTick(); // Prepare next interrupt __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_2, val + HAL_TICK_DELAY); PreviousVal = val; #if 0 // For DEBUG only HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6); #endif } } }
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)
// return microseconds since timer starts uint32_t timer_get_us(hacs_timer_t tim) { // In the current implementation, each tick count is equivalent to 1 us. return __HAL_TIM_GetCounter(&tim_handles[tim]); }
uint32_t CMX7262TimerCounter(void) { return __HAL_TIM_GetCounter(&htim5); }
U32 TIMER5_Get(void) { return __HAL_TIM_GetCounter(&timer_hd); }
uint32_t TickTock_Get(void){ uint32_t TockValue; TockValue=__HAL_TIM_GetCounter(&TIM_Handle); return TockValue; }
void TickTock_Stop(void) { uint32_t TockValue; TockValue=__HAL_TIM_GetCounter(&TIM_Handle); printf("Tiempo transcurrido: %u uS\n",TockValue); }