From 8233bf14d86da791c5dd04fa6d82b7bc82c63b3c Mon Sep 17 00:00:00 2001 From: fize Date: Mon, 12 Dec 2022 15:05:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0imu=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cproject | 4 + ASM330LHH/user_ams330lhh.c | 68 +++++++ ASM330LHH/user_asm330lhh.h | 17 +- Core/Inc/main.h | 10 + Core/Inc/stm32f1xx_hal_conf.h | 2 +- Core/Inc/stm32f1xx_it.h | 5 +- Core/Src/inter_callback.c | 114 +++++------ Core/Src/main.c | 203 ++++++++++++++----- Core/Src/stm32f1xx_hal_msp.c | 106 ++++++++-- Core/Src/stm32f1xx_it.c | 160 +++++++++++++-- IMU_DUAL.ioc | 111 ++++++++--- TDK/iam20680.c | 361 ++++++++++++++++++++++++++++++++++ TDK/iam20680.h | 329 +++++++++++++++++++++++++++++++ TDK/user_iam20680.c | 36 ++++ TDK/user_iam20680.h | 20 ++ nmea/rtkcmn.c | 96 ++++----- 16 files changed, 1422 insertions(+), 220 deletions(-) create mode 100644 TDK/iam20680.c create mode 100644 TDK/iam20680.h create mode 100644 TDK/user_iam20680.c create mode 100644 TDK/user_iam20680.h diff --git a/.cproject b/.cproject index 6082574..9f03025 100644 --- a/.cproject +++ b/.cproject @@ -33,6 +33,7 @@ @@ -46,12 +47,14 @@ @@ -133,6 +136,7 @@ + diff --git a/ASM330LHH/user_ams330lhh.c b/ASM330LHH/user_ams330lhh.c index 109fb34..1aedf9d 100644 --- a/ASM330LHH/user_ams330lhh.c +++ b/ASM330LHH/user_ams330lhh.c @@ -5,6 +5,7 @@ stmdev_ctx_t spi1_dev ; extern SPI_HandleTypeDef hspi1; +asm_value asm330; static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *bufp,uint16_t len) { @@ -47,8 +48,75 @@ static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp,uint16_t l void user_dev_init() { + static uint8_t rst; + uint8_t temp; spi1_dev.handle=&hspi1; spi1_dev.mdelay=HAL_Delay; spi1_dev.write_reg=platform_write; spi1_dev.read_reg=platform_read; + + asm330lhh_device_id_get(&spi1_dev, &temp); + asm330lhh_reset_set(&spi1_dev, PROPERTY_ENABLE); + do { + asm330lhh_reset_get(&spi1_dev, &rst); + } while (rst); + /* Start device configuration. */ + asm330lhh_device_conf_set(&spi1_dev, PROPERTY_ENABLE); + /* Enable Block Data Update */ + asm330lhh_block_data_update_set(&spi1_dev, PROPERTY_ENABLE); + /* Set Output Data Rate */ + asm330lhh_xl_data_rate_set(&spi1_dev, ASM330LHH_XL_ODR_104Hz); + asm330lhh_gy_data_rate_set(&spi1_dev, ASM330LHH_GY_ODR_104Hz); + /* Set full scale */ + asm330lhh_xl_full_scale_set(&spi1_dev, ASM330LHH_2g); + asm330lhh_gy_full_scale_set(&spi1_dev, ASM330LHH_2000dps); + + asm330lhh_data_ready_mode_set(&spi1_dev, ASM330LHH_DRDY_PULSED); + asm330lhh_pin_int1_route_t route_val={0}; + route_val.int1_ctrl.int1_drdy_xl=1; + asm330lhh_pin_int1_route_set(&spi1_dev, &route_val); + + /* Configure filtering chain(No aux interface) + * Accelerometer - LPF1 + LPF2 path + */ +// asm330lhh_xl_hp_path_on_out_set(&spi1_dev, ASM330LHH_LP_ODR_DIV_100); +// asm330lhh_xl_filter_lp2_set(&spi1_dev, PROPERTY_ENABLE); +} + +void asm_sample() +{ + static int16_t data_raw_acceleration[3]; + static int16_t data_raw_angular_rate[3]; + uint8_t reg; + /* Read output only if new xl value is available */ + asm330lhh_gy_flag_data_ready_get(&spi1_dev, ®); + if (reg) { + asm330lhh_angular_rate_raw_get(&spi1_dev, data_raw_angular_rate); + asm330. x_gyro= 0.001*asm330lhh_from_fs2000dps_to_mdps( + data_raw_angular_rate[0]); + asm330. y_gyro = 0.001*asm330lhh_from_fs2000dps_to_mdps( + data_raw_angular_rate[1]); + asm330. z_gyro = 0.001*asm330lhh_from_fs2000dps_to_mdps( + data_raw_angular_rate[2]); +// angular_rate_mdps[0] = asm330lhh_from_fs2000dps_to_mdps( +// data_raw_angular_rate[0]); +// angular_rate_mdps[1] = asm330lhh_from_fs2000dps_to_mdps( +// data_raw_angular_rate[1]); +// angular_rate_mdps[2] = asm330lhh_from_fs2000dps_to_mdps( +// data_raw_angular_rate[2]); + } + + asm330lhh_xl_flag_data_ready_get(&spi1_dev, ®); + if (reg) { + asm330lhh_acceleration_raw_get(&spi1_dev, data_raw_acceleration); + asm330.x_acc = 0.0098*asm330lhh_from_fs2g_to_mg( + data_raw_acceleration[0]); + asm330.y_acc = 0.0098*asm330lhh_from_fs2g_to_mg( + data_raw_acceleration[1]); + asm330.z_acc = 0.0098*asm330lhh_from_fs2g_to_mg( + data_raw_acceleration[2]); + + } + + } diff --git a/ASM330LHH/user_asm330lhh.h b/ASM330LHH/user_asm330lhh.h index fe42b2c..0232643 100644 --- a/ASM330LHH/user_asm330lhh.h +++ b/ASM330LHH/user_asm330lhh.h @@ -14,10 +14,23 @@ #define IMU_NOT_READY 1 #define IMU_LOCK 1 #define IMU_UNLOCK 0 - +typedef struct{ + int16_t x_a; //加速度值原始数据 + int16_t y_a; + int16_t z_a; + int16_t x_g; //角速度值原始数据 + int16_t y_g; + int16_t z_g; + float x_acc; //转换为真实加速度 + float y_acc; + float z_acc; + float x_gyro; //转换为真实角速度 + float y_gyro; + float z_gyro; +}asm_value; +extern asm_value asm330; void user_dev_init(); -extern uint8_t rx_uart2; extern stmdev_ctx_t spi1_dev; diff --git a/Core/Inc/main.h b/Core/Inc/main.h index 503dd4c..37a7452 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -57,6 +57,16 @@ void Error_Handler(void); /* USER CODE END EFP */ /* Private defines -----------------------------------------------------------*/ +#define SPI1_CSN_Pin GPIO_PIN_4 +#define SPI1_CSN_GPIO_Port GPIOA +#define SPI1_INIT1_Pin GPIO_PIN_0 +#define SPI1_INIT1_GPIO_Port GPIOB +#define SPI1_INIT1_EXTI_IRQn EXTI0_IRQn +#define SPI2_CSN_Pin GPIO_PIN_12 +#define SPI2_CSN_GPIO_Port GPIOB +#define SPI2_INIT1_Pin GPIO_PIN_8 +#define SPI2_INIT1_GPIO_Port GPIOA +#define SPI2_INIT1_EXTI_IRQn EXTI9_5_IRQn /* USER CODE BEGIN Private defines */ diff --git a/Core/Inc/stm32f1xx_hal_conf.h b/Core/Inc/stm32f1xx_hal_conf.h index e5ea88b..64200c3 100644 --- a/Core/Inc/stm32f1xx_hal_conf.h +++ b/Core/Inc/stm32f1xx_hal_conf.h @@ -42,7 +42,7 @@ /*#define HAL_CORTEX_MODULE_ENABLED */ /*#define HAL_CRC_MODULE_ENABLED */ /*#define HAL_DAC_MODULE_ENABLED */ -/*#define HAL_DMA_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED /*#define HAL_ETH_MODULE_ENABLED */ /*#define HAL_FLASH_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED diff --git a/Core/Inc/stm32f1xx_it.h b/Core/Inc/stm32f1xx_it.h index 94424fd..0ac340e 100644 --- a/Core/Inc/stm32f1xx_it.h +++ b/Core/Inc/stm32f1xx_it.h @@ -56,7 +56,10 @@ void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); void EXTI0_IRQHandler(void); -void TIM1_BRK_IRQHandler(void); +void EXTI1_IRQHandler(void); +void DMA1_Channel6_IRQHandler(void); +void EXTI9_5_IRQHandler(void); +void TIM3_IRQHandler(void); void USART1_IRQHandler(void); void USART2_IRQHandler(void); /* USER CODE BEGIN EFP */ diff --git a/Core/Src/inter_callback.c b/Core/Src/inter_callback.c index 95a0303..7e1c32a 100644 --- a/Core/Src/inter_callback.c +++ b/Core/Src/inter_callback.c @@ -17,61 +17,61 @@ extern nmea_t nmea; IMU_mng IMU_mng_st={0}; IMU_mng IMU_mng_tdk={0}; -extern void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) -{ - if(htim->Instance == htim1.Instance) - { - if(nmea.sol.utctime.sec+0.0001<1) - { - nmea.sol.utctime.sec+=0.0001; - } - if(nmea.sol.time.sec+0.0001<1) - { - nmea.sol.time.sec+=0.0001; - } - } -} -void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) -{ - if(GPIO_Pin == GPIO_PIN_1) - { - if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)==GPIO_PIN_RESET)//PPS impulse - { - nmea.sol.utctime.sec=0; - nmea.sol.time.sec=0;/* time (GPST) */ - nmea.sol.utctime.time++; - nmea.sol.time.time++;/* time (GPST) */ - } - } - if(GPIO_Pin == GPIO_PIN_0) - { - if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)==GPIO_PIN_RESET)//INI1 from ST IMU - { - if((!IMU_mng_st.lock)&&(!IMU_mng_st.ready)) - { - IMU_mng_st.lock=IMU_LOCK; - IMU_mng_st.time= nmea.sol.time; - IMU_mng_st.utctime= nmea.sol.utctime; - IMU_mng_st.ready=IMU_READY; - IMU_mng_st.lock=IMU_UNLOCK; - } - - } - } -} +//extern void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +//{ +// if(htim->Instance == htim1.Instance) +// { +// if(nmea.sol.utctime.sec+0.0001<1) +// { +// nmea.sol.utctime.sec+=0.0001; +// } +// if(nmea.sol.time.sec+0.0001<1) +// { +// nmea.sol.time.sec+=0.0001; +// } +// } +//} +//void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) +//{ +// if(GPIO_Pin == GPIO_PIN_1) +// { +// if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)==GPIO_PIN_RESET)//PPS impulse +// { +// nmea.sol.utctime.sec=0; +// nmea.sol.time.sec=0;/* time (GPST) */ +// nmea.sol.utctime.time++; +// nmea.sol.time.time++;/* time (GPST) */ +// } +// } +// if(GPIO_Pin == GPIO_PIN_0) +// { +// if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)==GPIO_PIN_RESET)//INI1 from ST IMU +// { +// if((!IMU_mng_st.lock)&&(!IMU_mng_st.ready)) +// { +// IMU_mng_st.lock=IMU_LOCK; +// IMU_mng_st.time= nmea.sol.time; +// IMU_mng_st.utctime= nmea.sol.utctime; +// IMU_mng_st.ready=IMU_READY; +// IMU_mng_st.lock=IMU_UNLOCK; +// } +// +// } +// } +//} uint8_t rx_uart2=0; -void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) -{ - if(huart->Instance==huart2.Instance) - { - if(input_nmea(&nmea, rx_uart2)!=1) - { - HAL_UART_Receive_IT(&huart2, &rx_uart2, 1); - } - else - { - HAL_TIM_Base_Start(&htim1); - } - } - -} +//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +//{ +// if(huart->Instance==huart2.Instance) +// { +// if(input_nmea(&nmea, rx_uart2)!=2) +// { +// HAL_UART_Receive_IT(&huart2, &rx_uart2, 1); +// } +// else +// { +// HAL_TIM_Base_Start(&htim1); +// } +// } +// +//} diff --git a/Core/Src/main.c b/Core/Src/main.c index 773e7cf..047912e 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -23,7 +23,11 @@ /* USER CODE BEGIN Includes */ #include "user_asm330lhh.h" #include "asm330lhh_reg.h" +#include "user_iam20680.h" +#include "iam20680.h" +#include "iam20680.h" #include "rtklib.h" +#include "stdio.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -37,39 +41,58 @@ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ +/* USER CODE BEGIN 1 */ + + +/* USER CODE END 1 */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ SPI_HandleTypeDef hspi1; +SPI_HandleTypeDef hspi2; -TIM_HandleTypeDef htim1; +TIM_HandleTypeDef htim3; UART_HandleTypeDef huart1; UART_HandleTypeDef huart2; +DMA_HandleTypeDef hdma_usart2_rx; /* USER CODE BEGIN PV */ - +uint8_t SPI2_INT_RD=0; +uint8_t SPI1_INT_RD=0; +double time_hh=23,time_mm=59,time_ss=40,time_ms; +uint8_t Rx_Buffer[2500]; +extern int8_t flag; +extern int GPS_week; +extern double GPS_sec; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); +static void MX_DMA_Init(void); static void MX_SPI1_Init(void); static void MX_USART1_UART_Init(void); -static void MX_TIM1_Init(void); static void MX_USART2_UART_Init(void); +static void MX_SPI2_Init(void); +static void MX_TIM3_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ -uint8_t temp[1000]={0}; + uint32_t time_100us=0; nmea_t nmea={0}; extern IMU_mng IMU_mng_st; extern IMU_mng IMU_mng_tdk; +static int16_t data_raw_acceleration[3]; +static int16_t data_raw_angular_rate[3]; +static int16_t data_raw_temperature; +static float acceleration_mg[3]; +static float angular_rate_mdps[3]; /* USER CODE END 0 */ /** @@ -100,32 +123,40 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); + MX_DMA_Init(); MX_SPI1_Init(); MX_USART1_UART_Init(); - MX_TIM1_Init(); MX_USART2_UART_Init(); + MX_SPI2_Init(); + MX_TIM3_Init(); /* USER CODE BEGIN 2 */ + HAL_TIM_Base_Start(&htim3); user_dev_init(); - HAL_Delay(1000); - asm330lhh_device_id_get(&spi1_dev, temp); + user_dev_init1(); +// iam20680_init(&spi2_dev); - HAL_UART_Receive_IT(&huart2, &rx_uart2, 1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { - if(IMU_mng_st.ready) + TIM3_Get_100us(); + if(1 == SPI2_INT_RD) { - //spi read - - - - - IMU_mng_st.ready=IMU_NOT_READY; + SPI2_INT_RD = 0; +// application_task(); } + if(1 == SPI1_INT_RD) + { + SPI1_INT_RD=0; + asm_sample(); + printf("{ GPS_week: %d week_sec: %.3lf \r\n",GPS_week,GPS_sec+time_ms*0.001); + printf("x_a=%.3fm/s2 y_a=%.3fm/s2 z_a=%.3fm/s2\r\n",asm330.x_acc,asm330.y_acc,asm330.z_acc); + printf("x_g=%.3fdeg/s y_g=%.3fdeg/s z_g=%.3fdeg/s }\r\n\r\n\r\n",asm330.x_gyro,asm330.y_gyro,asm330.z_gyro); +// printf("time: %.0lfh:%.0lfm:%.0lfs:%.3fms \r\n",time_hh,time_mm,time_ss,time_ms); + } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ @@ -210,48 +241,85 @@ static void MX_SPI1_Init(void) } /** - * @brief TIM1 Initialization Function + * @brief SPI2 Initialization Function * @param None * @retval None */ -static void MX_TIM1_Init(void) +static void MX_SPI2_Init(void) { - /* USER CODE BEGIN TIM1_Init 0 */ + /* USER CODE BEGIN SPI2_Init 0 */ - /* USER CODE END TIM1_Init 0 */ + /* USER CODE END SPI2_Init 0 */ + + /* USER CODE BEGIN SPI2_Init 1 */ + + /* USER CODE END SPI2_Init 1 */ + /* SPI2 parameter configuration*/ + hspi2.Instance = SPI2; + hspi2.Init.Mode = SPI_MODE_MASTER; + hspi2.Init.Direction = SPI_DIRECTION_2LINES; + hspi2.Init.DataSize = SPI_DATASIZE_8BIT; + hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH; + hspi2.Init.CLKPhase = SPI_PHASE_2EDGE; + hspi2.Init.NSS = SPI_NSS_SOFT; + hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; + hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi2.Init.TIMode = SPI_TIMODE_DISABLE; + hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi2.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&hspi2) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SPI2_Init 2 */ + + /* USER CODE END SPI2_Init 2 */ + +} + +/** + * @brief TIM3 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM3_Init(void) +{ + + /* USER CODE BEGIN TIM3_Init 0 */ + + /* USER CODE END TIM3_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; - /* USER CODE BEGIN TIM1_Init 1 */ + /* USER CODE BEGIN TIM3_Init 1 */ - /* USER CODE END TIM1_Init 1 */ - htim1.Instance = TIM1; - htim1.Init.Prescaler = 0; - htim1.Init.CounterMode = TIM_COUNTERMODE_UP; - htim1.Init.Period = 6400; - htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - htim1.Init.RepetitionCounter = 0; - htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; - if (HAL_TIM_Base_Init(&htim1) != HAL_OK) + /* USER CODE END TIM3_Init 1 */ + htim3.Instance = TIM3; + htim3.Init.Prescaler = 6400-1; + htim3.Init.CounterMode = TIM_COUNTERMODE_UP; + htim3.Init.Period = 65535; + htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim3) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; - if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) + if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; - if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) + if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { Error_Handler(); } - /* USER CODE BEGIN TIM1_Init 2 */ + /* USER CODE BEGIN TIM3_Init 2 */ - /* USER CODE END TIM1_Init 2 */ + /* USER CODE END TIM3_Init 2 */ } @@ -271,7 +339,7 @@ static void MX_USART1_UART_Init(void) /* USER CODE END USART1_Init 1 */ huart1.Instance = USART1; - huart1.Init.BaudRate = 460800; + huart1.Init.BaudRate = 921600; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; @@ -304,7 +372,7 @@ static void MX_USART2_UART_Init(void) /* USER CODE END USART2_Init 1 */ huart2.Instance = USART2; - huart2.Init.BaudRate = 115200; + huart2.Init.BaudRate = 460800; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; @@ -316,11 +384,28 @@ static void MX_USART2_UART_Init(void) Error_Handler(); } /* USER CODE BEGIN USART2_Init 2 */ - + __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE); + HAL_UART_Receive_DMA(&huart2, Rx_Buffer, sizeof(Rx_Buffer)); /* USER CODE END USART2_Init 2 */ } +/** + * Enable DMA controller clock + */ +static void MX_DMA_Init(void) +{ + + /* DMA controller clock enable */ + __HAL_RCC_DMA1_CLK_ENABLE(); + + /* DMA interrupt init */ + /* DMA1_Channel6_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn); + +} + /** * @brief GPIO Initialization Function * @param None @@ -335,35 +420,61 @@ static void MX_GPIO_Init(void) __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); + HAL_GPIO_WritePin(SPI1_CSN_GPIO_Port, SPI1_CSN_Pin, GPIO_PIN_SET); - /*Configure GPIO pin : PA1 */ - GPIO_InitStruct.Pin = GPIO_PIN_1; + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(SPI2_CSN_GPIO_Port, SPI2_CSN_Pin, GPIO_PIN_SET); + + /*Configure GPIO pins : PA1 SPI2_INIT1_Pin */ + GPIO_InitStruct.Pin = GPIO_PIN_1|SPI2_INIT1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - /*Configure GPIO pin : PA4 */ - GPIO_InitStruct.Pin = GPIO_PIN_4; + /*Configure GPIO pin : SPI1_CSN_Pin */ + GPIO_InitStruct.Pin = SPI1_CSN_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + HAL_GPIO_Init(SPI1_CSN_GPIO_Port, &GPIO_InitStruct); - /*Configure GPIO pin : PB0 */ - GPIO_InitStruct.Pin = GPIO_PIN_0; + /*Configure GPIO pin : SPI1_INIT1_Pin */ + GPIO_InitStruct.Pin = SPI1_INIT1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + HAL_GPIO_Init(SPI1_INIT1_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : SPI2_CSN_Pin */ + GPIO_InitStruct.Pin = SPI2_CSN_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(SPI2_CSN_GPIO_Port, &GPIO_InitStruct); /* EXTI interrupt init*/ - HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); + HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); + HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(EXTI1_IRQn); + + HAL_NVIC_SetPriority(EXTI9_5_IRQn, 2, 0); + HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); + } /* USER CODE BEGIN 4 */ +#ifdef __GNUC__ +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) + +PUTCHAR_PROTOTYPE +{ + + HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY); + return ch; +} +#endif /* USER CODE END 4 */ /** diff --git a/Core/Src/stm32f1xx_hal_msp.c b/Core/Src/stm32f1xx_hal_msp.c index 2eaa192..e6aeeaa 100644 --- a/Core/Src/stm32f1xx_hal_msp.c +++ b/Core/Src/stm32f1xx_hal_msp.c @@ -23,6 +23,7 @@ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ +extern DMA_HandleTypeDef hdma_usart2_rx; /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN TD */ @@ -117,6 +118,34 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) /* USER CODE END SPI1_MspInit 1 */ } + else if(hspi->Instance==SPI2) + { + /* USER CODE BEGIN SPI2_MspInit 0 */ + + /* USER CODE END SPI2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI2_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**SPI2 GPIO Configuration + PB13 ------> SPI2_SCK + PB14 ------> SPI2_MISO + PB15 ------> SPI2_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_14; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI2_MspInit 1 */ + + /* USER CODE END SPI2_MspInit 1 */ + } } @@ -147,6 +176,25 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) /* USER CODE END SPI1_MspDeInit 1 */ } + else if(hspi->Instance==SPI2) + { + /* USER CODE BEGIN SPI2_MspDeInit 0 */ + + /* USER CODE END SPI2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI2_CLK_DISABLE(); + + /**SPI2 GPIO Configuration + PB13 ------> SPI2_SCK + PB14 ------> SPI2_MISO + PB15 ------> SPI2_MOSI + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15); + + /* USER CODE BEGIN SPI2_MspDeInit 1 */ + + /* USER CODE END SPI2_MspDeInit 1 */ + } } @@ -158,19 +206,19 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) */ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM1) + if(htim_base->Instance==TIM3) { - /* USER CODE BEGIN TIM1_MspInit 0 */ + /* USER CODE BEGIN TIM3_MspInit 0 */ - /* USER CODE END TIM1_MspInit 0 */ + /* USER CODE END TIM3_MspInit 0 */ /* Peripheral clock enable */ - __HAL_RCC_TIM1_CLK_ENABLE(); - /* TIM1 interrupt Init */ - HAL_NVIC_SetPriority(TIM1_BRK_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TIM1_BRK_IRQn); - /* USER CODE BEGIN TIM1_MspInit 1 */ + __HAL_RCC_TIM3_CLK_ENABLE(); + /* TIM3 interrupt Init */ + HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM3_IRQn); + /* USER CODE BEGIN TIM3_MspInit 1 */ - /* USER CODE END TIM1_MspInit 1 */ + /* USER CODE END TIM3_MspInit 1 */ } } @@ -183,19 +231,19 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) */ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { - if(htim_base->Instance==TIM1) + if(htim_base->Instance==TIM3) { - /* USER CODE BEGIN TIM1_MspDeInit 0 */ + /* USER CODE BEGIN TIM3_MspDeInit 0 */ - /* USER CODE END TIM1_MspDeInit 0 */ + /* USER CODE END TIM3_MspDeInit 0 */ /* Peripheral clock disable */ - __HAL_RCC_TIM1_CLK_DISABLE(); + __HAL_RCC_TIM3_CLK_DISABLE(); - /* TIM1 interrupt DeInit */ - HAL_NVIC_DisableIRQ(TIM1_BRK_IRQn); - /* USER CODE BEGIN TIM1_MspDeInit 1 */ + /* TIM3 interrupt DeInit */ + HAL_NVIC_DisableIRQ(TIM3_IRQn); + /* USER CODE BEGIN TIM3_MspDeInit 1 */ - /* USER CODE END TIM1_MspDeInit 1 */ + /* USER CODE END TIM3_MspDeInit 1 */ } } @@ -233,7 +281,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart) HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART1 interrupt Init */ - HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); + HAL_NVIC_SetPriority(USART1_IRQn, 3, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspInit 1 */ @@ -262,8 +310,25 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart) GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + /* USART2 DMA Init */ + /* USART2_RX Init */ + hdma_usart2_rx.Instance = DMA1_Channel6; + hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart2_rx.Init.Mode = DMA_NORMAL; + hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW; + if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx); + /* USART2 interrupt Init */ - HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); + HAL_NVIC_SetPriority(USART2_IRQn, 1, 0); HAL_NVIC_EnableIRQ(USART2_IRQn); /* USER CODE BEGIN USART2_MspInit 1 */ @@ -314,6 +379,9 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); + /* USART2 DMA DeInit */ + HAL_DMA_DeInit(huart->hdmarx); + /* USART2 interrupt DeInit */ HAL_NVIC_DisableIRQ(USART2_IRQn); /* USER CODE BEGIN USART2_MspDeInit 1 */ diff --git a/Core/Src/stm32f1xx_it.c b/Core/Src/stm32f1xx_it.c index acef5a7..0ce9f73 100644 --- a/Core/Src/stm32f1xx_it.c +++ b/Core/Src/stm32f1xx_it.c @@ -1,4 +1,6 @@ /* USER CODE BEGIN Header */ +#include "stdio.h" +#include "rtklib.h" /** ****************************************************************************** * @file stm32f1xx_it.c @@ -6,12 +8,13 @@ ****************************************************************************** * @attention * - * Copyright (c) 2022 STMicroelectronics. - * All rights reserved. + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

* - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ @@ -41,7 +44,13 @@ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ - +int16_t count=0,temp_count=0; +extern uint8_t Rx_Buffer[2500]; +nmea_t nmea_gpa; +int8_t flag=0,flag_t=-3; +int GPS_week; +double UTC_time[6],GPS_sec; +extern double time_hh,time_mm,time_ss,time_ms; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ @@ -55,7 +64,8 @@ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ -extern TIM_HandleTypeDef htim1; +extern TIM_HandleTypeDef htim3; +extern DMA_HandleTypeDef hdma_usart2_rx; extern UART_HandleTypeDef huart1; extern UART_HandleTypeDef huart2; /* USER CODE BEGIN EV */ @@ -208,24 +218,66 @@ void EXTI0_IRQHandler(void) /* USER CODE BEGIN EXTI0_IRQn 0 */ /* USER CODE END EXTI0_IRQn 0 */ - HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); + HAL_GPIO_EXTI_IRQHandler(SPI1_INIT1_Pin); /* USER CODE BEGIN EXTI0_IRQn 1 */ /* USER CODE END EXTI0_IRQn 1 */ } /** - * @brief This function handles TIM1 break interrupt. + * @brief This function handles EXTI line1 interrupt. */ -void TIM1_BRK_IRQHandler(void) +void EXTI1_IRQHandler(void) { - /* USER CODE BEGIN TIM1_BRK_IRQn 0 */ + /* USER CODE BEGIN EXTI1_IRQn 0 */ - /* USER CODE END TIM1_BRK_IRQn 0 */ - HAL_TIM_IRQHandler(&htim1); - /* USER CODE BEGIN TIM1_BRK_IRQn 1 */ + /* USER CODE END EXTI1_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1); + /* USER CODE BEGIN EXTI1_IRQn 1 */ - /* USER CODE END TIM1_BRK_IRQn 1 */ + /* USER CODE END EXTI1_IRQn 1 */ +} + +/** + * @brief This function handles DMA1 channel6 global interrupt. + */ +void DMA1_Channel6_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Channel6_IRQn 0 */ + + /* USER CODE END DMA1_Channel6_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_usart2_rx); + /* USER CODE BEGIN DMA1_Channel6_IRQn 1 */ + + /* USER CODE END DMA1_Channel6_IRQn 1 */ +} + +/** + * @brief This function handles EXTI line[9:5] interrupts. + */ +void EXTI9_5_IRQHandler(void) +{ + /* USER CODE BEGIN EXTI9_5_IRQn 0 */ + + /* USER CODE END EXTI9_5_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(SPI2_INIT1_Pin); + /* USER CODE BEGIN EXTI9_5_IRQn 1 */ + + /* USER CODE END EXTI9_5_IRQn 1 */ +} + +/** + * @brief This function handles TIM3 global interrupt. + */ +void TIM3_IRQHandler(void) +{ + /* USER CODE BEGIN TIM3_IRQn 0 */ + + /* USER CODE END TIM3_IRQn 0 */ + HAL_TIM_IRQHandler(&htim3); + /* USER CODE BEGIN TIM3_IRQn 1 */ + + /* USER CODE END TIM3_IRQn 1 */ } /** @@ -248,14 +300,92 @@ void USART1_IRQHandler(void) void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ + uint32_t temp,i; + uint8_t ans=1; + nmea_t* p=&nmea_gpa; /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */ + if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE)!=RESET) + __HAL_UART_CLEAR_IDLEFLAG(&huart2); + temp = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx); + HAL_UART_DMAStop(&huart2); + for(i=0;i<2500-temp;i++) + { + ans=input_nmea(p,Rx_Buffer[i]); + } + if(ans==0) + { + +// time2epoch(p->sol.utctime,UTC_time); + if(flag_t==-1 || flag_t==20){ + GPS_sec=time2gpst(p->sol.time,&GPS_week); +// time_hh=UTC_time[3]; +// time_mm=UTC_time[4]; + + flag_t=0; + } + flag_t+=1; + } + +// printf("time: %.0lfh:%.0lfm:%.0lfs \r\n",time_hh,time_mm,time_ss); + HAL_UART_Receive_DMA(&huart2,Rx_Buffer, sizeof(Rx_Buffer)); + /* USER CODE END USART2_IRQn 1 */ } /* USER CODE BEGIN 1 */ +void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) +{ + extern uint8_t SPI2_INT_RD,SPI1_INT_RD; + if(GPIO_Pin == SPI2_INIT1_Pin) + { + SPI2_INT_RD =1; + } + if(GPIO_Pin == SPI1_INIT1_Pin) + { + SPI1_INT_RD=1; + } + if(GPIO_Pin == GPIO_PIN_1) + { + if(time_ss==59) //ʱ�������? + { + time_ss=-1; + time_mm+=1; + if(time_mm==60) + { + time_mm=0; + time_hh+=1; + if(time_hh==24) + { + time_hh=0; + } + } + } + time_ss+=1; + time_ms=0; + GPS_sec+=1; + count=__HAL_TIM_GET_COUNTER(&htim3); + temp_count = __HAL_TIM_GET_COUNTER(&htim3); + + } +} +double TIM3_Get_100us() +{ + extern int16_t count,temp_count; + extern double time_ms,time_ss; + temp_count = __HAL_TIM_GET_COUNTER(&htim3); + if(temp_count >= count) + { + time_ms=(temp_count - count)*0.1; //100ns一次计数 + } + else + { + time_ms=(65535-count+temp_count)*0.1; //计数值溢出的情况 + } + return time_ms; +} /* USER CODE END 1 */ diff --git a/IMU_DUAL.ioc b/IMU_DUAL.ioc index 50a9322..705899b 100644 --- a/IMU_DUAL.ioc +++ b/IMU_DUAL.ioc @@ -2,44 +2,65 @@ CAD.formats= CAD.pinconfig= CAD.provider= +Dma.Request0=USART2_RX +Dma.RequestsNb=1 +Dma.USART2_RX.0.Direction=DMA_PERIPH_TO_MEMORY +Dma.USART2_RX.0.Instance=DMA1_Channel6 +Dma.USART2_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE +Dma.USART2_RX.0.MemInc=DMA_MINC_ENABLE +Dma.USART2_RX.0.Mode=DMA_NORMAL +Dma.USART2_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE +Dma.USART2_RX.0.PeriphInc=DMA_PINC_DISABLE +Dma.USART2_RX.0.Priority=DMA_PRIORITY_LOW +Dma.USART2_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority File.Version=6 GPIO.groupedBy=Group By Peripherals KeepUserPlacement=false Mcu.CPN=STM32F103C8T6 Mcu.Family=STM32F1 -Mcu.IP0=NVIC -Mcu.IP1=RCC -Mcu.IP2=SPI1 -Mcu.IP3=SYS -Mcu.IP4=TIM1 -Mcu.IP5=USART1 -Mcu.IP6=USART2 -Mcu.IPNb=7 +Mcu.IP0=DMA +Mcu.IP1=NVIC +Mcu.IP2=RCC +Mcu.IP3=SPI1 +Mcu.IP4=SPI2 +Mcu.IP5=SYS +Mcu.IP6=TIM3 +Mcu.IP7=USART1 +Mcu.IP8=USART2 +Mcu.IPNb=9 Mcu.Name=STM32F103C(8-B)Tx Mcu.Package=LQFP48 Mcu.Pin0=PA1 Mcu.Pin1=PA2 -Mcu.Pin10=PA13 -Mcu.Pin11=PA14 -Mcu.Pin12=VP_SYS_VS_Systick -Mcu.Pin13=VP_TIM1_VS_ClockSourceINT +Mcu.Pin10=PB14 +Mcu.Pin11=PB15 +Mcu.Pin12=PA8 +Mcu.Pin13=PA9 +Mcu.Pin14=PA10 +Mcu.Pin15=PA13 +Mcu.Pin16=PA14 +Mcu.Pin17=VP_SYS_VS_Systick +Mcu.Pin18=VP_TIM3_VS_ClockSourceINT Mcu.Pin2=PA3 Mcu.Pin3=PA4 Mcu.Pin4=PA5 Mcu.Pin5=PA6 Mcu.Pin6=PA7 Mcu.Pin7=PB0 -Mcu.Pin8=PA9 -Mcu.Pin9=PA10 -Mcu.PinsNb=14 +Mcu.Pin8=PB12 +Mcu.Pin9=PB13 +Mcu.PinsNb=19 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F103C8Tx MxCube.Version=6.7.0 MxDb.Version=DB.6.0.70 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.DMA1_Channel6_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.EXTI0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.EXTI0_IRQn=true\:1\:0\:true\:false\:true\:true\:true\:true +NVIC.EXTI1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.EXTI9_5_IRQn=true\:2\:0\:true\:false\:true\:true\:true\:true NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false @@ -48,9 +69,9 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false -NVIC.TIM1_BRK_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true -NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true -NVIC.USART2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.TIM3_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.USART1_IRQn=true\:3\:0\:true\:false\:true\:true\:true\:true +NVIC.USART2_IRQn=true\:1\:0\:true\:false\:true\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false PA1.GPIOParameters=GPIO_ModeDefaultEXTI PA1.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING @@ -66,7 +87,8 @@ PA2.Mode=Asynchronous PA2.Signal=USART2_TX PA3.Mode=Asynchronous PA3.Signal=USART2_RX -PA4.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd +PA4.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label +PA4.GPIO_Label=SPI1_CSN PA4.GPIO_PuPd=GPIO_PULLUP PA4.GPIO_Speed=GPIO_SPEED_FREQ_HIGH PA4.Locked=true @@ -78,12 +100,31 @@ PA6.Mode=Full_Duplex_Master PA6.Signal=SPI1_MISO PA7.Mode=Full_Duplex_Master PA7.Signal=SPI1_MOSI +PA8.GPIOParameters=GPIO_Label +PA8.GPIO_Label=SPI2_INIT1 +PA8.Locked=true +PA8.Signal=GPXTI8 PA9.Mode=Asynchronous PA9.Signal=USART1_TX -PB0.GPIOParameters=GPIO_ModeDefaultEXTI +PB0.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI +PB0.GPIO_Label=SPI1_INIT1 PB0.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING PB0.Locked=true PB0.Signal=GPXTI0 +PB12.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP +PB12.GPIO_Label=SPI2_CSN +PB12.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP +PB12.GPIO_PuPd=GPIO_PULLUP +PB12.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PB12.Locked=true +PB12.PinState=GPIO_PIN_SET +PB12.Signal=GPIO_Output +PB13.Mode=Full_Duplex_Master +PB13.Signal=SPI2_SCK +PB14.Mode=Full_Duplex_Master +PB14.Signal=SPI2_MISO +PB15.Mode=Full_Duplex_Master +PB15.Signal=SPI2_MOSI PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false @@ -112,7 +153,7 @@ ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=STM32CubeIDE ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=true -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_SPI1_Init-SPI1-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_TIM1_Init-TIM1-false-HAL-true,6-MX_USART2_UART_Init-USART2-false-HAL-true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_SPI1_Init-SPI1-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true,6-MX_USART2_UART_Init-USART2-false-HAL-true,7-MX_SPI2_Init-SPI2-false-HAL-true RCC.ADCFreqValue=32000000 RCC.AHBFreq_Value=64000000 RCC.APB1CLKDivider=RCC_HCLK_DIV2 @@ -136,6 +177,8 @@ SH.GPXTI0.0=GPIO_EXTI0 SH.GPXTI0.ConfNb=1 SH.GPXTI1.0=GPIO_EXTI1 SH.GPXTI1.ConfNb=1 +SH.GPXTI8.0=GPIO_EXTI8 +SH.GPXTI8.ConfNb=1 SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_8 SPI1.CLKPhase=SPI_PHASE_2EDGE SPI1.CLKPolarity=SPI_POLARITY_HIGH @@ -144,19 +187,25 @@ SPI1.Direction=SPI_DIRECTION_2LINES SPI1.IPParameters=VirtualType,Mode,Direction,BaudRatePrescaler,CalculateBaudRate,CLKPolarity,CLKPhase SPI1.Mode=SPI_MODE_MASTER SPI1.VirtualType=VM_MASTER -TIM1.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE -TIM1.ClockDivision=TIM_CLOCKDIVISION_DIV1 -TIM1.IPParameters=ClockDivision,AutoReloadPreload,Prescaler,Period -TIM1.Period=6400 -TIM1.Prescaler=0 -USART1.BaudRate=460800 +SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4 +SPI2.CLKPhase=SPI_PHASE_2EDGE +SPI2.CLKPolarity=SPI_POLARITY_HIGH +SPI2.CalculateBaudRate=8.0 MBits/s +SPI2.Direction=SPI_DIRECTION_2LINES +SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,CLKPolarity,CLKPhase +SPI2.Mode=SPI_MODE_MASTER +SPI2.VirtualType=VM_MASTER +TIM3.IPParameters=Prescaler +TIM3.Prescaler=6400-1 +USART1.BaudRate=921600 USART1.IPParameters=VirtualMode,BaudRate USART1.VirtualMode=VM_ASYNC -USART2.IPParameters=VirtualMode +USART2.BaudRate=460800 +USART2.IPParameters=VirtualMode,BaudRate USART2.VirtualMode=VM_ASYNC VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick -VP_TIM1_VS_ClockSourceINT.Mode=Internal -VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT +VP_TIM3_VS_ClockSourceINT.Mode=Internal +VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT board=custom isbadioc=false diff --git a/TDK/iam20680.c b/TDK/iam20680.c new file mode 100644 index 0000000..7c840dd --- /dev/null +++ b/TDK/iam20680.c @@ -0,0 +1,361 @@ +/** + * @file iam20680.c + * @author Joseph Gillispie + * @date 22Aug2022 + * @brief This is the source file for the TDK IAM-20680 acceleromter/gyrometer. + */ + +/*! @file iam20680.c + * @brief Driver for IAM-20680 sensor + */ +#include "iam20680.h" + +/**\name Internal macros */ + +/**\name Internal APIs */ + +// Ex: power modes, calibration checks, etc + +/*! + * @brief This API must be called before other APIs. It verifies the chip ID of the sensor. + */ +uint8_t iam20680_init(struct iam20680_dev *dev) +{ + uint8_t status; + uint8_t buff; + + // Reset device to defaults. + buff = 0x80; + status = iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + + // Check chip ID to ensure IAM-20680 exists on board. + // I2C:0x68 or 0x69 depending upon the value driven on AD0 pin + status = iam20680_read_regs((uint8_t)IAM20680_WHO_AM_I, &buff, 1, dev); + dev->chip_id = buff; + + // Configure int pin as data ready. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_INT_ENABLE, &buff, 1, dev); + buff &= ~0x01; + buff |= 1 << 0; // DATA_RDY_INT_EN + status |= iam20680_write_regs((uint8_t)IAM20680_INT_ENABLE, &buff, 1, dev); + + + // Set gyro low noise mode. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_LP_MODE_CFG, &buff, 1, dev); + buff &= ~0x80; + buff |= 1 << 7; // GYRO_CYCLE + status |= iam20680_write_regs((uint8_t)IAM20680_LP_MODE_CFG, &buff, 1, dev); + + // Set accel low noise mode. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + buff &= ~0x20; + buff |= 1 << 5; // ACCEL_CYCLE + status |= iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + + // Wait 20 ms. + iam20680_delay_ms(20, dev); + + // Bypass gyro DLPF. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_GYRO_CONFIG, &buff, 1, dev); + buff &= ~0x03; + buff |= 0 << 0; // FCHOICE + status |= iam20680_write_regs((uint8_t)IAM20680_GYRO_CONFIG, &buff, 1, dev); + + // Bypass accel DLPF. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_ACCEL_CONFIG2, &buff, 1, dev); + buff &= ~0x08; + buff |= 0 << 3; // ACCEL_FCHOICE_B + status |= iam20680_write_regs((uint8_t)IAM20680_ACCEL_CONFIG2, &buff, 1, dev); + + // Set DLPF_CFG. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_CONFIG, &buff, 1, dev); + buff &= ~0x07; + buff |= 1 << 0; // DLPF_CFG + status |= iam20680_write_regs((uint8_t)IAM20680_CONFIG, &buff, 1, dev); + + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_ACCEL_CONFIG2, &buff, 1, dev); + buff &= ~0x07; + buff |= 1 << 0; // A_DLPF_CFG + status |= iam20680_write_regs((uint8_t)IAM20680_ACCEL_CONFIG2, &buff, 1, dev); + + // Set averaging filter. + // Gyro + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_LP_MODE_CFG, &buff, 1, dev); + buff &= ~0x70; + buff |= 0 << 4; // G_AVGCFG + status |= iam20680_write_regs((uint8_t)IAM20680_LP_MODE_CFG, &buff, 1, dev); + // Accel + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_ACCEL_CONFIG2, &buff, 1, dev); + buff &= ~0x30; + buff |= 0 << 4; // DEC2_CFG + status |= iam20680_write_regs((uint8_t)IAM20680_ACCEL_CONFIG2, &buff, 1, dev); + + // Set SMPLRT_DIV. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_SMPLRT_DIV, &buff, 1, dev); + buff = 0x09; // 10 ms / 100 Hz + status |= iam20680_write_regs((uint8_t)IAM20680_SMPLRT_DIV, &buff, 1, dev); + + // Disable accel and gyro all axes. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_2, &buff, 1, dev); + buff |= 0x3F; + status |= iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_2, &buff, 1, dev); + + // Set full scale range. + // Gyro + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_GYRO_CONFIG, &buff, 1, dev); + buff &= ~0x18; + buff |= 1 << 3; // FS_SEL + status |= iam20680_write_regs((uint8_t)IAM20680_GYRO_CONFIG, &buff, 1, dev); + // Accel + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_ACCEL_CONFIG, &buff, 1, dev); + buff &= ~0x18; + buff |= 0 << 3; // ACCEL_FS_SEL + status |= iam20680_write_regs((uint8_t)IAM20680_ACCEL_CONFIG, &buff, 1, dev); + + // Enable accel. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_2, &buff, 1, dev); + buff &= ~0x38; + buff |= 0 << 3; // Enable x, y, and z. + status |= iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_2, &buff, 1, dev); + iam20680_delay_ms(20, dev); + + // Enable gyro. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_2, &buff, 1, dev); + buff &= ~0x07; + buff |= 0 << 0; // Enable x, y, and z. + status |= iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_2, &buff, 1, dev); + iam20680_delay_ms(50, dev); + + // Reset and enable FIFO. + // Disable FIFO + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_USER_CTRL, &buff, 1, dev); + buff &= ~0x40; + buff |= 0 << 6; // FIFO_EN + status |= iam20680_write_regs((uint8_t)IAM20680_USER_CTRL, &buff, 1, dev); + // Reset FIFO + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_USER_CTRL, &buff, 1, dev); + buff &= ~0x04; + buff |= 1 << 2; // FIFO_RST + status |= iam20680_write_regs((uint8_t)IAM20680_USER_CTRL, &buff, 1, dev); + // Enable gyro FIFO + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_FIFO_EN, &buff, 1, dev); + buff &= ~0x70; + buff |= 7 << 4; // Write x, y, and z to FIFO at data rate. + status |= iam20680_write_regs((uint8_t)IAM20680_FIFO_EN, &buff, 1, dev); + // Enable accel FIFO + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_FIFO_EN, &buff, 1, dev); + buff &= ~0x08; + buff |= 1 << 3; // Write x, y, and z to FIFO at data rate. + status |= iam20680_write_regs((uint8_t)IAM20680_FIFO_EN, &buff, 1, dev); + // Enable FIFO + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_USER_CTRL, &buff, 1, dev); + buff &= ~0x40; + buff |= 1 << 6; // FIFO_EN + status |= iam20680_write_regs((uint8_t)IAM20680_USER_CTRL, &buff, 1, dev); + + return status; +} + +/*! + * @brief This API must be called before other APIs. It verifies the chip ID of the sensor. + */ +uint8_t iam20680_init2(struct iam20680_dev *dev) +{ + uint8_t status = 0x00; + uint8_t buff; + + // Delay 100 ms from power-up before register read/write. + iam20680_delay_ms(100, dev); + + // Disable I2C. + status |= iam20680_read_regs((uint8_t)IAM20680_USER_CTRL, &buff, 1, dev); + buff |= 0x10; // I2C_IF_DIS + status |= iam20680_write_regs((uint8_t)IAM20680_USER_CTRL, &buff, 1, dev); + + // Check WHO_AM_I register. + status = iam20680_read_regs((uint8_t)IAM20680_WHO_AM_I, &buff, 1, dev); + dev->chip_id = buff; + + // Reset driver states. + status |= iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + buff |= 0x80; // DEVICE_RESET + status |= iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + iam20680_delay_ms(100, dev); + //buff = 0x00; + while ((buff & (0x80)) != 0x00) + { + iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + iam20680_delay_ms(1, dev); + } + + // Disable I2C. + status |= iam20680_read_regs((uint8_t)IAM20680_USER_CTRL, &buff, 1, dev); + buff |= 0x10; // I2C_IF_DIS + status |= iam20680_write_regs((uint8_t)IAM20680_USER_CTRL, &buff, 1, dev); + + // Wake up. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + buff &= ~0x40; // SLEEP + status |= iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + iam20680_delay_ms(5, dev); + + // Set up CLKSEL. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + buff &= ~0x07; // Clear CLKSEL + buff |= 0x01; // Set CLKSEL + status |= iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + + // Disable gyro and accel. + // Set full scale range. + // Set bandwidth. + // Set averaging filter. + // Set sampling rate. + // Disable FIFO. + // Configure FIFO. + // Enable Data Ready interrupt. + + + return status; +} + +/*! + * @brief This API must be called before other APIs. It verifies the chip ID of the sensor. + */ +uint8_t iam20680_init_simple(struct iam20680_dev *dev) +{ + uint8_t buff; + uint8_t status = 0x00; + + // Reset driver states. + status |= iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + buff |= 0x80; // DEVICE_RESET + status |= iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + iam20680_delay_ms(100, dev); + //buff = 0x00; + while ((buff & (0x80)) != 0x00) + { + iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + iam20680_delay_ms(1, dev); + } + + // Let device select best clock source. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + buff &= ~0x07; // Clear CLKSEL + buff |= 0x01; // Set CLKSEL + status |= iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + + // Select ODR. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_SMPLRT_DIV, &buff, 1, dev); + buff = 0x09; // Set ODR = 100 Hz + status |= iam20680_write_regs((uint8_t)IAM20680_PWR_MGMT_1, &buff, 1, dev); + + // Select FS range. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_ACCEL_CONFIG, &buff, 1, dev); + buff &= 0x18; + buff |= 0 << 3; + status |= iam20680_write_regs((uint8_t)IAM20680_ACCEL_CONFIG, &buff, 1, dev); + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_GYRO_CONFIG, &buff, 1, dev); + buff &= 0x18; + buff |= 0 << 3; + status |= iam20680_write_regs((uint8_t)IAM20680_GYRO_CONFIG, &buff, 1, dev); + + // Select filter. + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_ACCEL_CONFIG2, &buff, 1, dev); + buff &= 0x07; + buff |= 5 << 0; + status |= iam20680_write_regs((uint8_t)IAM20680_ACCEL_CONFIG2, &buff, 1, dev); + buff = 0x00; + status |= iam20680_read_regs((uint8_t)IAM20680_CONFIG, &buff, 1, dev); + buff &= 0x07; + buff |= 5 << 0; + status |= iam20680_write_regs((uint8_t)IAM20680_CONFIG, &buff, 1, dev); + + + return status; +} + +/*! + * @brief This API writes the data to the given register address of the sensor. + */ +uint8_t iam20680_write_regs(uint8_t reg_addr, uint8_t *reg_data, uint8_t len, struct iam20680_dev *dev) +{ + // Write the data. + dev->status = dev->write(reg_addr, reg_data, len); + + return dev->status; +} + +/*! + * @brief This api reads the data from the given register address of the sensor. + */ +uint8_t iam20680_read_regs(uint8_t reg_addr, uint8_t *reg_data, uint8_t len, struct iam20680_dev *dev) +{ + // Check if SPI is used. + if (dev->interface == IAM20680_SPI) + { + reg_addr |= 0x80; + } + + // Read the data. + dev->status = dev->read(reg_addr, reg_data, len); + + return dev->status; +} + +/*! + * @brief This api provides and blocking ms delay function. + */ +uint8_t iam20680_delay_ms(uint32_t delay, struct iam20680_dev *dev) +{ + dev->status = 1; + dev->delay(delay); + dev->status = 0; + + return dev->status; +} + +/*! + * @brief This api gets acceleromter, temperature, and gyrometer data. + */ +uint8_t iam20680_get_data(struct iam20680_data *data, struct iam20680_dev *dev) +{ + uint8_t buff[14] = {0}; // Accel, temp, and gyro two bytes each. + + dev->status = iam20680_read_regs((uint8_t)IAM20680_ACCEL_XOUT_H, &buff[0], sizeof(buff), dev); + data->accel_x = (buff[0] << 8) | buff[1]; + data->accel_y = (buff[2] << 8) | buff[3]; + data->accel_z = (buff[4] << 8) | buff[5]; + data->temp = (buff[6] << 8) | buff[7]; + data->gyro_x = (buff[8] << 8) | buff[9]; + data->gyro_y = (buff[10] << 8) | buff[11]; + data->gyro_z = (buff[12] << 8) | buff[13]; + + return dev->status; +} diff --git a/TDK/iam20680.h b/TDK/iam20680.h new file mode 100644 index 0000000..7d56997 --- /dev/null +++ b/TDK/iam20680.h @@ -0,0 +1,329 @@ +/** + * @file iam20680.h + * @author Joseph Gillispie + * @date 22Aug2022 + * @brief This is the header file for the TDK IAM-20680 acceleromter/gyrometer. + */ + +#ifndef __IAM20680_H +#define __IAM20680_H + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************** + * INCLUDES + ****************************************************************************/ +/** + * @brief Required includes + */ +#include +#include + +/***************************************************************************** + * MACROS AND DEFINES + ****************************************************************************/ +/** + * @brief Register addresses + */ +#define IAM20680_SELF_TEST_X_GYRO 0x00 +#define IAM20680_SELF_TEST_Y_GYRO 0x01 +#define IAM20680_SELF_TEST_Z_GYRO 0x02 +#define IAM20680_SELF_TEST_X_ACCEL 0x0D +#define IAM20680_SELF_TEST_Y_ACCEL 0x0E +#define IAM20680_SELF_TEST_Z_ACCEL 0x0F +#define IAM20680_XG_OFFS_USRH 0x13 +#define IAM20680_XG_OFFS_USRL 0x14 +#define IAM20680_YG_OFFS_USRH 0x15 +#define IAM20680_YG_OFFS_USRL 0x16 +#define IAM20680_ZG_OFFS_USRH 0x17 +#define IAM20680_ZG_OFFS_USRL 0x18 +#define IAM20680_SMPLRT_DIV 0x19 +#define IAM20680_CONFIG 0x1A +#define IAM20680_GYRO_CONFIG 0x1B +#define IAM20680_ACCEL_CONFIG 0x1C +#define IAM20680_ACCEL_CONFIG2 0x1D +#define IAM20680_LP_MODE_CFG 0x1E +#define IAM20680_ACCEL_WOM_THR 0x1F +#define IAM20680_FIFO_EN 0x23 +#define IAM20680_FSYNC_INT 0x36 +#define IAM20680_INT_PIN_CFG 0x37 +#define IAM20680_INT_ENABLE 0x38 +#define IAM20680_INT_STATUS 0x3A +#define IAM20680_ACCEL_XOUT_H 0x3B +#define IAM20680_ACCEL_XOUT_L 0x3C +#define IAM20680_ACCEL_YOUT_H 0x3D +#define IAM20680_ACCEL_YOUT_L 0x3E +#define IAM20680_ACCEL_ZOUT_H 0x3F +#define IAM20680_ACCEL_ZOUT_L 0x40 +#define IAM20680_TEMP_OUT_H 0x41 +#define IAM20680_TEMP_OUT_L 0x42 +#define IAM20680_GYRO_XOUT_H 0x43 +#define IAM20680_GYRO_XOUT_L 0x44 +#define IAM20680_GYRO_YOUT_H 0x45 +#define IAM20680_GYRO_YOUT_L 0x46 +#define IAM20680_GYRO_ZOUT_H 0x47 +#define IAM20680_GYRO_ZOUT_L 0x48 +#define IAM20680_SIGNAL_PATH_RESET 0x68 +#define IAM20680_ACCEL_INTEL_CTRL 0x69 +#define IAM20680_USER_CTRL 0x6A +#define IAM20680_PWR_MGMT_1 0x6B +#define IAM20680_PWR_MGMT_2 0x6C +#define IAM20680_FIFO_COUNTH 0x72 +#define IAM20680_FIFO_COUNTL 0x73 +#define IAM20680_FIFO_R_W 0x74 +#define IAM20680_WHO_AM_I 0x75 +#define IAM20680_XA_OFFSET_H 0x77 +#define IAM20680_XA_OFFSET_L 0x78 +#define IAM20680_YA_OFFSET_H 0x7A +#define IAM20680_YA_OFFSET_L 0x7B +#define IAM20680_ZA_OFFSET_H 0x7D +#define IAM20680_ZA_OFFSET_L 0x7E + +/**\name Status */ +#define IAM20680_OK 0x00 /*< OK */ +#define IAM20680_ERR 0x01 /*< ERROR */ + +/**\name Who Am I */ +#define IAM20680_CHIP_ID 0xA9 + +/**\name Interface */ +#define IAM20680_SPI 0x00 +#define IAM20680_I2C 0x01 + +/***************************************************************************** + * TYPEDEFS + ****************************************************************************/ +/** + * @brief Type definitions + */ + +/** + * @brief Bus communication read function pointer. This should be mapped to + * the platform-specific read function of the user application. + * + * @param[in] reg_addr : Register address from which data is read. + * @param[in] reg_data : Pointer to data buffer where read data is stored. + * @param[in] len : Number of bytes of data to be read. + * + * @retval 0 -> Success. + * @retval Non-zero -> Fail. + */ +typedef uint8_t (*iam20680_read_fptr_typedef)(uint8_t reg_addr, uint8_t *reg_data, uint16_t len); + + +/** + * @brief Bus communication write function pointer. Should be mapped to + * the platform-specific write function of the user application. + * + * @param[in] reg_addr : Register address to which data is written. + * @param[in] reg_data : Pointer to data buffer in which data to be written is stored. + * @param[in] len : Number of bytes of data to write. + * + * @retval 0 -> Success. + * @retval Non-zero -> Fail. + */ +typedef uint8_t (*iam20680_write_fptr_typedef)(uint8_t reg_addr, uint8_t *reg_data, uint16_t len); + +/** + * @brief Timer delay function pointer. This function should be mapped to a platform-specific + * hardware timer. + * + * @param[in] delay : Desired delay in ms. + * + * @retval 0 -> Success. + * @retval Non-zero -> Fail. + */ +typedef void (*iam20680_delay_fptr_typedef)(uint32_t delay); + +/** + * @brief IAM-20680 accelerometer and gyrometer data. + */ +struct iam20680_data { + + int16_t accel_x; /*< Acclerometer x data */ + int16_t accel_y; /*< Acclerometer y data */ + int16_t accel_z; /*< Acclerometer z data */ + int16_t temp; /*< Temperature data */ + int16_t gyro_x; /*< Gyrometer x data */ + int16_t gyro_y; /*< Gyrometer y data */ + int16_t gyro_z; /*< Gyrometer z data */ +}; + +/** + * @brief IAM-20680 register settings. + */ +struct iam20680_settings { + +}; + +/** + * @brief IAM-20680 device parameters. + */ +struct iam20680_dev { + iam20680_read_fptr_typedef read; /*< Read function pointer */ + iam20680_write_fptr_typedef write; /*< Write function pointer */ + iam20680_delay_fptr_typedef delay; /*< Delay function pointer */ + uint8_t interface; /*< Interface type (I2C, SPI) */ + struct iam20680_settings settings; /*< Sensor settings */ + uint8_t status; /*< Returned status of read/write functions */ + uint8_t chip_id; /*< Chip ID */ +}; + + +/***************************************************************************** + * GLOBAL FUNCTION PROTOTYPES + ****************************************************************************/ +/** + * \ingroup iam20680 + * \defgroup iam20680ApiInit Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup iam20680ApiInit + * \page iam20680_api_iam20680_init iam20680_init + * \code + * uint8_t iam20680_init(struct iam20680_dev *dev); + * \endcode + * @details This API must be called before other APIs. It verifies the chip ID of the sensor. + * + * @param[in, out] dev : Structure Instance of iam20680_dev + * @return Result of API execution status. + * + * @retval 0 -> Success + * @retval Non-zero -> Fail + */ +uint8_t iam20680_init(struct iam20680_dev *dev); + +/** + * \ingroup iam20680 + * \defgroup iam20680ApiInit2 Initialization + * @brief Initialize the sensor and device structure + */ + +/*! + * \ingroup iam20680ApiInit2 + * \page iam20680_api_iam20680_init2 iam20680_init2 + * \code + * uint8_t iam20680_init2(struct iam20680_dev *dev); + * \endcode + * @details This API must be called before other APIs. It verifies the chip ID of the sensor. + * + * @param[in, out] dev : Structure Instance of iam20680_dev + * @return Result of API execution status. + * + * @retval 0 -> Success + * @retval Non-zero -> Fail + */ +uint8_t iam20680_init2(struct iam20680_dev *dev); + +/*! + * \ingroup iam20680ApiInit2 + * \page iam20680_api_iam20680_init_simple iam20680_init_simple + * \code + * uint8_t iam20680_init_simple(struct iam20680_dev *dev); + * \endcode + * @details This API must be called before other APIs. It verifies the chip ID of the sensor. + * + * @param[in, out] dev : Structure Instance of iam20680_dev + * @return Result of API execution status. + * + * @retval 0 -> Success + * @retval Non-zero -> Fail + */ +uint8_t iam20680_init_simple(struct iam20680_dev *dev); + +/** + * \ingroup iam20680 + * \defgroup iam20680ApiRegister Registers + * @brief Generic API for accessing sensor registers + */ + +/*! + * \ingroup iam20680ApiRegister + * \page iam20680_api_iam20680_write_regs iam20680_write_regs + * \code + * uint8_t iam20680_write_regs(uint8_t reg_addr, uint8_t *reg_data, uint8_t len, struct iam20680_dev *dev); + * \endcode + * @details This API writes the given data to the register address of the sensor + * + * @param[in] reg_addr : Register address to where the data is to be written. + * @param[in] reg_data : Pointer to data buffer which is to be written in the reg_addr of sensor. + * @param[in] len : Number of bytes of data to write. + * @param[in, out] : Structure instance of iam20680_dev. + * + * @regurn Result of API execution status. + * + * @retval 0 -> Success. + * @retvan Non-zero -> Fail. + * + */ +uint8_t iam20680_write_regs(uint8_t reg_addr, uint8_t *reg_data, uint8_t len, struct iam20680_dev *dev); + +/*! + * \ingroup iam20680ApiRegister + * \page iam20680_api_iam20680_read_regs iam20680_read_regs + * \code + * uint8_t iam20680_read_regs(uint8_t reg_addr, uint8_t *reg_data, uint8_t len, struct iam20680_dev *dev); + * \endcode + * @details This API writes the given data to the register address of the sensor + * + * @param[in] reg_addr : Register address from where the data is to be read. + * @param[in] reg_data : Pointer to data buffer to store the read data. + * @param[in] len : Number of bytes of data to be read. + * @param[in, out] : Structure instance of iam20680_dev. + * + * @regurn Result of API execution status. + * + * @retval 0 -> Success. + * @retvan Non-zero -> Fail. + * + */ +uint8_t iam20680_read_regs(uint8_t reg_addr, uint8_t *reg_data, uint8_t len, struct iam20680_dev *dev); + +/*! + * \ingroup iam20680ApiRegister + * \page iam20680_api_iam20680_delay iam20680_delay + * \code + * uint8_t iam20680_delay(uint32_t delay, iam20680_dev *dev); + * \endcode + * @details This API provides a blocking delay with one ms resolution + * + * @param[in] delay : Delay in ms. + * @param[in, out] : Structure instance of iam20680_dev. + * + * @regurn Result of API execution status. + * + * @retval 0 -> Success. + * @retvan Non-zero -> Fail. + * + */ +uint8_t iam20680_delay_ms(uint32_t delay, struct iam20680_dev *dev); + +/*! + * \ingroup iam20680ApiRegister + * \page iam20680_api_iam20680_get_data iam20680_delay + * \code + * uint8_t iam20680_get_data(struct iam20680_data *data, iam20680_dev *dev); + * \endcode + * @details This API gets accelerometer, temperature, and gyrometer data + * + * @param[in] data : Data structure to store sensor readings. + * @param[in, out] : Structure instance of iam20680_dev. + * + * @regurn Result of API execution status. + * + * @retval 0 -> Success. + * @retvan Non-zero -> Fail. + * + */ +uint8_t iam20680_get_data(struct iam20680_data *data, struct iam20680_dev *dev); + + +#ifdef __cplusplus +} +#endif + +#endif /* __IAM20680_H */ diff --git a/TDK/user_iam20680.c b/TDK/user_iam20680.c new file mode 100644 index 0000000..cbffe0f --- /dev/null +++ b/TDK/user_iam20680.c @@ -0,0 +1,36 @@ +#include "user_iam20680.h" + + +struct iam20680_dev spi2_dev; + + +extern SPI_HandleTypeDef hspi2; + +uint8_t iam_read(uint8_t reg_addr, uint8_t *reg_data, uint16_t len) +{ + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); + HAL_SPI_Transmit(&hspi2, ®_addr, 1, 1000); + HAL_SPI_Receive(&hspi2,reg_data, len, 1000); + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); + return 0; + +} + +uint8_t iam_write(uint8_t reg_addr, uint8_t *reg_data, uint16_t len) +{ + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); + HAL_SPI_Transmit(&hspi2, ®_addr, 1, 1000); + HAL_SPI_Transmit(&hspi2, reg_data, len, 1000); + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET); + return 0; +} + +void user_dev_init1() +{ + spi2_dev.delay=HAL_Delay; + spi2_dev.interface = IAM20680_SPI; + spi2_dev.read=iam_read; + spi2_dev.write=iam_write; + + iam20680_init(&spi2_dev); +} diff --git a/TDK/user_iam20680.h b/TDK/user_iam20680.h new file mode 100644 index 0000000..fa01186 --- /dev/null +++ b/TDK/user_iam20680.h @@ -0,0 +1,20 @@ +/* + * user_iam20680.h + * + * Created on: Dec 7, 2022 + * Author: FizeC + */ + +#ifndef USER_IAM20680_H_ +#define USER_IAM20680_H_ +#include +#include +#include "rtklib.h" +#include "iam20680.h" +#include "stm32f1xx_hal.h" + +void user_dev_init1(); + +extern struct iam20680_dev spi2_dev; + +#endif /* USER_IAM20680_H_ */ diff --git a/nmea/rtkcmn.c b/nmea/rtkcmn.c index a9b317d..aa18157 100644 --- a/nmea/rtkcmn.c +++ b/nmea/rtkcmn.c @@ -15,7 +15,7 @@ //#define SQR(x) ((x) * (x)) //#define MAX_VAR_EPH SQR(300.0) /* max variance eph to reject satellite (m^2) */ // -//static const double gpst0[] = {1980, 1, 6, 0, 0, 0}; /* gps time reference */ +static const double gpst0[] = {1980, 1, 6, 0, 0, 0}; /* gps time reference */ //static const double gst0[] = {1999, 8, 22, 0, 0, 0}; /* galileo system time reference */ //static const double bdt0[] = {2006, 1, 1, 0, 0, 0}; /* beidou time reference */ // @@ -1615,37 +1615,37 @@ static double leaps[MAXLEAPS + 1][7] = {/* leap seconds (y,m,d,h,m,s,utc-gpst) * //// time.sec = ep[5] - sec; //// return time; ////} -///* time to calendar day/time --------------------------------------------------- -// * convert gtime_t struct to calendar day/time -// * args : gtime_t t I gtime_t struct -// * double *ep O day/time {year,month,day,hour,min,sec} -// * return : none -// * notes : proper in 1970-2037 or 1970-2099 (64bit time_t) -// *-----------------------------------------------------------------------------*/ -//extern void time2epoch(gtime_t t, double *ep) -//{ -// const int mday[] = {/* # of days in a month */ -// 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, -// 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -// int days, sec, mon, day; -// -// /* leap year if year%4==0 in 1901-2099 */ -// days = (int)(t.time / 86400); -// sec = (int)(t.time - (time_t)days * 86400); -// for (day = days % 1461, mon = 0; mon < 48; mon++) -// { -// if (day >= mday[mon]) -// day -= mday[mon]; -// else -// break; -// } -// ep[0] = 1970 + days / 1461 * 4 + mon / 12; -// ep[1] = mon % 12 + 1; -// ep[2] = day + 1; -// ep[3] = sec / 3600; -// ep[4] = sec % 3600 / 60; -// ep[5] = sec % 60 + t.sec; -//} +/* time to calendar day/time --------------------------------------------------- + * convert gtime_t struct to calendar day/time + * args : gtime_t t I gtime_t struct + * double *ep O day/time {year,month,day,hour,min,sec} + * return : none + * notes : proper in 1970-2037 or 1970-2099 (64bit time_t) + *-----------------------------------------------------------------------------*/ +extern void time2epoch(gtime_t t, double *ep) +{ + const int mday[] = {/* # of days in a month */ + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, + 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int days, sec, mon, day; + + /* leap year if year%4==0 in 1901-2099 */ + days = (int)(t.time / 86400); + sec = (int)(t.time - (time_t)days * 86400); + for (day = days % 1461, mon = 0; mon < 48; mon++) + { + if (day >= mday[mon]) + day -= mday[mon]; + else + break; + } + ep[0] = 1970 + days / 1461 * 4 + mon / 12; + ep[1] = mon % 12 + 1; + ep[2] = day + 1; + ep[3] = sec / 3600; + ep[4] = sec % 3600 / 60; + ep[5] = sec % 60 + t.sec; +} ///* same as above but output limited to n decimals for formatted output */ //extern void time2epoch_n(gtime_t t, double *ep, int n) //{ @@ -1676,22 +1676,22 @@ static double leaps[MAXLEAPS + 1][7] = {/* leap seconds (y,m,d,h,m,s,utc-gpst) * // t.sec = sec - (int)sec; // return t; //} -///* time to gps time ------------------------------------------------------------ -// * convert gtime_t struct to week and tow in gps time -// * args : gtime_t t I gtime_t struct -// * int *week IO week number in gps time (NULL: no output) -// * return : time of week in gps time (s) -// *-----------------------------------------------------------------------------*/ -//extern double time2gpst(gtime_t t, int *week) -//{ -// gtime_t t0 = epoch2time(gpst0); -// time_t sec = t.time - t0.time; -// int w = (int)(sec / (86400 * 7)); -// -// if (week) -// *week = w; -// return (double)(sec - (double)w * 86400 * 7) + t.sec; -//} +/* time to gps time ------------------------------------------------------------ + * convert gtime_t struct to week and tow in gps time + * args : gtime_t t I gtime_t struct + * int *week IO week number in gps time (NULL: no output) + * return : time of week in gps time (s) + *-----------------------------------------------------------------------------*/ +extern double time2gpst(gtime_t t, int *week) +{ + gtime_t t0 = epoch2time(gpst0); + time_t sec = t.time - t0.time; + int w = (int)(sec / (86400 * 7)); + + if (week) + *week = w; + return (double)(sec - (double)w * 86400 * 7) + t.sec; +} ///* galileo system time to time ------------------------------------------------- // * convert week and tow in galileo system time (gst) to gtime_t struct // * args : int week I week number in gst