diff --git a/code/l452_code/Core/Inc/buff.hpp b/code/l452_code/Core/Inc/buff.hpp index 7cb421f..07871c7 100644 --- a/code/l452_code/Core/Inc/buff.hpp +++ b/code/l452_code/Core/Inc/buff.hpp @@ -3,66 +3,99 @@ #include "fatfs.h" #include "usart.h" #include "usbd_cdc_if.h" +#include "tim.h" #include "packet.hpp" -extern uint8_t databank1[1024]; -extern uint8_t databank2[1024]; -extern uint16_t pos; +void sd_send(uint8_t data[], uint32_t len); +void usb_send(uint8_t data[], uint32_t len); +void uart_send(uint8_t data[], uint32_t len); -volatile extern bool usb_ready; -volatile extern bool wb1mmc_ready; -volatile extern bool sd_ready; -extern FIL file; +template +struct dbl_buff { + uint32_t last_write; + uint32_t pos; + alignas(4) uint8_t send_buffer1[N + 4]; + alignas(4) uint8_t send_buffer2[N + 4]; + uint8_t* const databank1; + uint8_t* const databank2; + + dbl_buff() : databank1(send_buffer1 + 4), databank2(send_buffer2 + 4) {}; + + // Every time we get a reading add to the active databank if it fits, + // if not we switch banks and write out the now unactive databank + template void write(const packet_type& packet) { + if (pos + sizeof(packet_type) + 1 < N) { + databank1[pos] = typecode(); + memcpy(databank1 + pos + 1, &packet, sizeof(packet_type)); + pos += sizeof(packet_type) + 1; + return; + } else if (pos < N) { + send(); + return this->write(packet); + } else if (pos + sizeof(packet_type) + 1 < 2 * N) { + databank2[pos - N] = typecode(); + memcpy(databank2 + pos + 1 - N, &packet, sizeof(packet_type)); + pos += sizeof(packet_type) + 1; + return; + } else { + send(); + return this->write(packet); + } + }; -// Every time we get a reading add to the active databank if it fits, -// if not we switch banks and write out the now unactive databank + void send() { + if (pos < N) { + ((uint32_t*)send_buffer1)[0] = pos; + send_fn(send_buffer1, pos + 4); + pos = N; + } else { + ((uint32_t*)send_buffer2)[0] = pos - N; + send_fn(send_buffer2, pos - N + 4); + pos = 0; + } + last_write = total_tim6(); + } +}; + +extern struct dbl_buff<1024, usb_send> usb_buff; +extern struct dbl_buff<1024, uart_send> ble_buff; +extern struct dbl_buff<1024, sd_send> sd_buff; + +volatile extern bool send_imu_usb; +volatile extern bool send_imu_ble; +volatile extern bool send_adc_usb; +volatile extern bool send_adc_ble; +volatile extern bool send_ppg_usb; +volatile extern bool send_ppg_ble; + +// Log all packets to SD card, only log big packets to +// other things if required template void write(packet_type packet) { - if (pos + sizeof(packet) + 2 < sizeof(databank1)) { - *(uint16_t*)(&databank1[pos]) = typecode(); - memcpy(databank1 + pos + 2, &packet, sizeof(packet)); - pos += sizeof(packet) + 2; - return; - } else if (pos < sizeof(databank1)) { - if (usb_ready) { - CDC_Transmit_FS(databank1, sizeof(databank1)); - usb_ready = false; + sd_buff.write(packet); + if (typecode() == typecode()) { + if (send_imu_usb) { + usb_buff.write(packet); } - if (wb1mmc_ready) { - HAL_UART_Transmit_DMA(&huart1, databank1, sizeof(databank1)); - wb1mmc_ready = false; + if (send_imu_ble) { + ble_buff.write(packet); } - if (sd_ready) { - UINT bytes_written; - FRESULT res = f_write(&file, databank1, sizeof(databank1), &bytes_written); - if (res != FR_OK || bytes_written != sizeof(databank1)) {} + } else if (typecode() == typecode()) { + if (send_adc_usb) { + usb_buff.write(packet); } - - memset(databank2, 0, sizeof(databank2)); - pos = sizeof(databank1); - return write(packet); - } else if (pos + sizeof(packet) + 2 < - sizeof(databank1) + sizeof(databank2)) { - *(uint16_t*)(&databank2[pos - sizeof(databank1)]) = typecode(); - memcpy(databank2 + pos + 2 - sizeof(databank1), &packet, sizeof(packet)); - pos += sizeof(packet) + 2; - return; - } else { - if (usb_ready) { - CDC_Transmit_FS(databank2, sizeof(databank2)); - usb_ready = false; + if (send_adc_ble) { + ble_buff.write(packet); } - if (wb1mmc_ready) { - HAL_UART_Transmit_DMA(&huart1, databank2, sizeof(databank2)); - wb1mmc_ready = false; + } else if (typecode() == typecode()) { + if (send_ppg_usb) { + usb_buff.write(packet); } - if (sd_ready) { - UINT bytes_written; - FRESULT res = f_write(&file, databank2, sizeof(databank2), &bytes_written); - if (res != FR_OK || bytes_written != sizeof(databank2)) {} + if (send_ppg_ble) { + ble_buff.write(packet); } - memset(databank1, 0, sizeof(databank1)); - pos = 0; - return write(packet); - } -}; + } else { // Send other types unconditionally + usb_buff.write(packet); + ble_buff.write(packet); + } +} diff --git a/code/l452_code/Core/Inc/tim.h b/code/l452_code/Core/Inc/tim.h index ab5eec0..5f39ea0 100644 --- a/code/l452_code/Core/Inc/tim.h +++ b/code/l452_code/Core/Inc/tim.h @@ -37,7 +37,10 @@ extern TIM_HandleTypeDef htim2; extern TIM_HandleTypeDef htim6; /* USER CODE BEGIN Private defines */ - +extern volatile uint16_t tim6_reloads; +__inline__ uint32_t total_tim6() { + return ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT; +} /* USER CODE END Private defines */ void MX_TIM2_Init(void); diff --git a/code/l452_code/Core/Src/ads131.cpp b/code/l452_code/Core/Src/ads131.cpp index 38cf449..2386ce5 100644 --- a/code/l452_code/Core/Src/ads131.cpp +++ b/code/l452_code/Core/Src/ads131.cpp @@ -10,9 +10,14 @@ void initialize_ads131(SPI_HandleTypeDef *hspi1) { uint8_t cmd[6] = {0x00, 0x11, 0x00}; uint8_t rx_buff[18]; - HAL_SPI_DeInit(hspi1); - hspi1->Init.CLKPolarity = SPI_POLARITY_LOW; - HAL_SPI_Init(hspi1); + while (__HAL_SPI_GET_FLAG(hspi1, SPI_FLAG_BSY)); + __HAL_SPI_DISABLE(hspi1); + + MODIFY_REG(hspi1->Instance->CR1, + SPI_CR1_CPOL | SPI_CR1_CPHA, + SPI_POLARITY_LOW | SPI_PHASE_2EDGE); + + __HAL_SPI_ENABLE(hspi1); // reset HAL_GPIO_WritePin(GPIOA, ADC_CS_Pin, GPIO_PIN_RESET); @@ -62,8 +67,6 @@ void initialize_ads131(SPI_HandleTypeDef *hspi1) { struct packet_adc p_adc; -extern volatile uint16_t tim6_reloads; - void read_ads131(SPI_HandleTypeDef *hspi1) { if (HAL_GPIO_ReadPin(GPIOA, ADC_DRDY_Pin) != GPIO_PIN_RESET) { @@ -73,16 +76,22 @@ void read_ads131(SPI_HandleTypeDef *hspi1) { uint8_t cmd[6] = {0x0}; uint8_t rx_buff[16] = {0x0}; - HAL_SPI_DeInit(hspi1); - hspi1->Init.CLKPolarity = SPI_POLARITY_LOW; - HAL_SPI_Init(hspi1); + while (__HAL_SPI_GET_FLAG(hspi1, SPI_FLAG_BSY)); + __HAL_SPI_DISABLE(hspi1); + + MODIFY_REG(hspi1->Instance->CR1, + SPI_CR1_CPOL | SPI_CR1_CPHA, + SPI_POLARITY_LOW | SPI_PHASE_2EDGE); + + __HAL_SPI_ENABLE(hspi1); + HAL_GPIO_WritePin(GPIOA, ADC_CS_Pin, GPIO_PIN_RESET); HAL_SPI_TransmitReceive(hspi1, (uint8_t*) cmd, (uint8_t*) rx_buff, 18, HAL_MAX_DELAY); HAL_GPIO_WritePin(GPIOA, ADC_CS_Pin, GPIO_PIN_SET); if (p_adc.index == 0) { - p_adc.t = ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT; + p_adc.t = total_tim6(); } p_adc.ekg_readings_cnts[p_adc.index] = to_signed_24(&rx_buff[3]); diff --git a/code/l452_code/Core/Src/buff.cpp b/code/l452_code/Core/Src/buff.cpp index ec322d7..333c805 100644 --- a/code/l452_code/Core/Src/buff.cpp +++ b/code/l452_code/Core/Src/buff.cpp @@ -1,6 +1,32 @@ -//#include "buff.hpp" +#include "buff.hpp" #include -alignas(32) uint8_t databank1[1024]; -alignas(32) uint8_t databank2[1024]; -uint16_t pos = 0; +void sd_send(uint8_t data[], uint32_t len) { + extern bool sd_ready; + extern FIL file; + if (sd_ready) { + UINT bytes_written; + FRESULT res = f_write(&file, data, len, &bytes_written); + //if (res != FR_OK || bytes_written != db_size)) {} + } +} + +void usb_send(uint8_t data[], uint32_t len) { + extern bool usb_ready; + if (usb_ready) { + CDC_Transmit_FS(data, len); + usb_ready = false; + } +} + +void uart_send(uint8_t data[], uint32_t len) { + extern bool wb1mmc_ready; + if (wb1mmc_ready) { + HAL_UART_Transmit_DMA(&huart1, data, len); + wb1mmc_ready = false; + } +} + +struct dbl_buff<1024, usb_send> usb_buff; +struct dbl_buff<1024, uart_send> ble_buff; +struct dbl_buff<1024, sd_send> sd_buff; diff --git a/code/l452_code/Core/Src/lsm6dsv.cpp b/code/l452_code/Core/Src/lsm6dsv.cpp index ddefd6a..e2098c5 100644 --- a/code/l452_code/Core/Src/lsm6dsv.cpp +++ b/code/l452_code/Core/Src/lsm6dsv.cpp @@ -4,101 +4,88 @@ #include "tim.h" #include "buff.hpp" -extern volatile uint16_t tim6_reloads; +extern SPI_HandleTypeDef hspi1; + +void send_receive_lsm6dsv(uint8_t *tx_buff, uint8_t *rx_buff, uint32_t len) { + HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); + HAL_SPI_TransmitReceive(&hspi1, tx_buff, rx_buff, len, HAL_MAX_DELAY); + HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); +} void initialize_lsm6dsv(SPI_HandleTypeDef *hspi1) { - uint8_t tx_buff[8] = {0}; - uint8_t rx_buff[8] = {0}; - - HAL_SPI_DeInit(hspi1); - hspi1->Init.CLKPolarity = SPI_POLARITY_HIGH; - HAL_SPI_Init(hspi1); + uint8_t tx_buff[2] = {0}; + uint8_t rx_buff[2] = {0}; + while (__HAL_SPI_GET_FLAG(hspi1, SPI_FLAG_BSY)); + __HAL_SPI_DISABLE(hspi1); + + MODIFY_REG(hspi1->Instance->CR1, + SPI_CR1_CPOL | SPI_CR1_CPHA, + SPI_POLARITY_HIGH | SPI_PHASE_2EDGE); + + __HAL_SPI_ENABLE(hspi1); + tx_buff[0] = 0x01; // Reset tx_buff[1] = 0x04; - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); - HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY); - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); - HAL_Delay(30); - - tx_buff[0] = 0x03; // active high pushpull interrupt - tx_buff[1] = 0x01; // I2C and I3C disabled - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); - HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY); - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); - HAL_Delay(30); - - tx_buff[0] = 0x09; // Set 60Hz data rate for fifo - tx_buff[1] = 0b01010101; - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); - HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY); - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); - HAL_Delay(30); - - tx_buff[0] = 0x0D; // Set drdy based on fifo - tx_buff[1] = 0b00111000; - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); - HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY); - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); - HAL_Delay(30); - - tx_buff[0] = 0x10; // Set 60Hz accelerometer high performance - tx_buff[1] = 0b00000101; - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); - HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY); - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); - HAL_Delay(30); - - tx_buff[0] = 0x11; // Set 60Hz gyro high performance - tx_buff[1] = 0b00000101; - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); - HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY); - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); - HAL_Delay(30); - - // todo: get watermark working - tx_buff[0] = 0x07; - tx_buff[1] = 21; // 21 samples - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); - HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY); - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); - HAL_Delay(30); + send_receive_lsm6dsv(tx_buff, rx_buff, 2); + HAL_Delay(100); tx_buff[0] = 0x0A; // Set bypass mode for fifo tx_buff[1] = 0b00000000; // to clear fifo - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); - HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY); - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); - HAL_Delay(30); + send_receive_lsm6dsv(tx_buff, rx_buff, 2); + + tx_buff[0] = 0x03; // active high pushpull interrupt + tx_buff[1] = 0x01; // I2C and I3C disabled + send_receive_lsm6dsv(tx_buff, rx_buff, 2); + + tx_buff[0] = 0x09; // Set 120Hz data rate for fifo + tx_buff[1] = 0b01100110; + send_receive_lsm6dsv(tx_buff, rx_buff, 2); + + tx_buff[0] = 0x0D; // Set drdy based on fifo + tx_buff[1] = 0b00111000; + send_receive_lsm6dsv(tx_buff, rx_buff, 2); + + tx_buff[0] = 0x10; // Set 120Hz accelerometer high performance + tx_buff[1] = 0b00000111; + send_receive_lsm6dsv(tx_buff, rx_buff, 2); + + tx_buff[0] = 0x11; // Set 120Hz gyro high performance + tx_buff[1] = 0b00000110; + send_receive_lsm6dsv(tx_buff, rx_buff, 2); + + tx_buff[0] = 0x07; + tx_buff[1] = 21; // 21 samples + send_receive_lsm6dsv(tx_buff, rx_buff, 2); tx_buff[0] = 0x0A; // Set continuous mode for fifo tx_buff[1] = 0b00000110; - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); - HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY); - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); - HAL_Delay(30); + send_receive_lsm6dsv(tx_buff, rx_buff, 2); } struct packet_imu p_imu; void read_lsm6dsv(SPI_HandleTypeDef *hspi1) { - + if (HAL_GPIO_ReadPin(GPIOC, IMU_DRDY_Pin) == GPIO_PIN_RESET) { return; } - - HAL_SPI_DeInit(hspi1); - hspi1->Init.CLKPolarity = SPI_POLARITY_HIGH; - HAL_SPI_Init(hspi1); + + while (__HAL_SPI_GET_FLAG(hspi1, SPI_FLAG_BSY)); + __HAL_SPI_DISABLE(hspi1); + + MODIFY_REG(hspi1->Instance->CR1, + SPI_CR1_CPOL | SPI_CR1_CPHA, + SPI_POLARITY_HIGH | SPI_PHASE_2EDGE); + + __HAL_SPI_ENABLE(hspi1); uint8_t tx_buff[141] = {0b10000000 + 0x78}; // FIFO addr // Watermark set for 21 samples, read 20 tx_buff[0] = 0b10000000 + 0x78; // FIFO addr - p_imu.t = ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT; - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET); - HAL_SPI_TransmitReceive(hspi1, tx_buff, p_imu.data, 141, HAL_MAX_DELAY); - HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET); + p_imu.t = total_tim6(); + send_receive_lsm6dsv(tx_buff, p_imu.data, 141); write(p_imu); } diff --git a/code/l452_code/Core/Src/main.cpp b/code/l452_code/Core/Src/main.cpp index 884ccc0..51a0c42 100644 --- a/code/l452_code/Core/Src/main.cpp +++ b/code/l452_code/Core/Src/main.cpp @@ -61,6 +61,26 @@ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ +volatile bool send_imu_usb = false; +volatile bool send_imu_ble = false; +volatile bool send_adc_usb = false; +volatile bool send_adc_ble = false; +volatile bool send_ppg_usb = false; +volatile bool send_ppg_ble = false; + +volatile uint16_t adc_value = 0; +volatile bool adc_ready = false; + +volatile bool usb_ready = false; +volatile bool wb1mmc_ready = false; +volatile bool print_desc = false; +volatile bool sd_ready = false; + +FATFS fs; +FIL file; +FRESULT res; + +uint8_t uart_rx_data[1]; /* USER CODE END PV */ @@ -73,32 +93,17 @@ void PeriphCommonClock_Config(void); /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ - -volatile bool to_recordVbatt = false; -volatile bool to_recordTime = false; - -volatile uint16_t adc_value = 0; -volatile uint8_t adc_ready = 0; -volatile uint16_t tim6_reloads = 0; -volatile bool usb_ready = false; -volatile bool wb1mmc_ready = false; -volatile bool print_desc = false; -volatile bool sd_ready = false; - -FATFS fs; -FIL file; -FRESULT res; - -uint8_t uart_rx_data[1]; - void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { if (hadc->Instance == ADC1) { adc_value = HAL_ADC_GetValue(hadc); - adc_ready = 1; + adc_ready = true; } } -// 80MHz clock, 39999 prescaler and 19999 period for 0.1Hz +volatile bool to_recordVbatt = false; +volatile bool to_recordTime = false; +// 80MHz clock, 39999 prescaler and 1999 period +// 2000Hz TIM6 increment, and 1Hz reloads void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM6) { tim6_reloads += 1; @@ -107,34 +112,63 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { } } -volatile bool to_turn_on_sd = false; -volatile bool to_turn_off_sd = false; -void USB_CDC_RxHandler(uint8_t* Buf, uint32_t Len) { - if (memcmp(Buf, "R", Len) == 0) { +volatile bool to_open_sd = false; +volatile bool to_close_sd = false; +void comm_handler(uint8_t ch) { + switch (ch) { + + case '1': + send_imu_usb = !send_imu_usb; + break; + case '2': + send_imu_ble = !send_imu_ble; + break; + case '3': + send_adc_usb = !send_adc_usb; + break; + case '4': + send_adc_ble = !send_adc_ble; + break; + case '5': + send_ppg_usb = !send_ppg_usb; + break; + case '6': + send_ppg_ble = !send_ppg_ble; + break; + + case 'r': usb_ready = true; - } - if (memcmp(Buf, "S", Len) == 0) { - to_turn_off_sd = true; - } - if (memcmp(Buf, "T", Len) == 0) { - to_turn_on_sd = true; - } - if (memcmp(Buf, "?", Len) == 0) { + break; + case 'R': + wb1mmc_ready = true; + break; + case 'S': + to_close_sd = true; + break; + case 'T': + to_open_sd = true; + break; + case '?': print_desc = true; + break; + } +} + +void USB_CDC_RxHandler(uint8_t* Buf, uint32_t Len) { + if (Len == 1) { + comm_handler(Buf[0]); } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { - if (uart_rx_data[0] == 'R') { - wb1mmc_ready = true; - } + comm_handler(uart_rx_data[0]); HAL_UART_Receive_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data)); } void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {} -void turn_on_sd(void) { - to_turn_on_sd = false; +void open_sd(void) { + to_open_sd = false; if (BSP_SD_IsDetected() != SD_PRESENT) { return; } @@ -159,13 +193,14 @@ void turn_on_sd(void) { } } -void turn_off_sd(void) { - to_turn_off_sd = false; +void close_sd(void) { + sd_ready = false; + to_close_sd = false; if (sd_ready) { f_sync(&file); f_close(&file); res = f_mount(NULL, "", 1); - sd_ready = false; + } } /* USER CODE END 0 */ @@ -214,44 +249,41 @@ int main(void) MX_USB_DEVICE_Init(); MX_FATFS_Init(); /* USER CODE BEGIN 2 */ - + struct packet_vbatt p_vbatt; + struct packet_rtc p_rtc; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ HAL_TIM_Base_Start_IT(&htim6); - //HAL_UART_Receive_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data)); - // For some reason initializing the ads131 first breaks the lsm6dsv gyro readings - initialize_lsm6dsv(&hspi1); - //initialize_ads131(&hspi1); - //initialize_max30101(&hi2c1); + initialize_lsm6dsv(&hspi1); + initialize_ads131(&hspi1); + initialize_max30101(&hi2c1); + + HAL_UART_Receive_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data)); + usb_buff.last_write = total_tim6(); while (1) { read_lsm6dsv(&hspi1); - //read_max30101(&hi2c1); - //read_ads131(&hspi1); - HAL_Delay(1); - continue; - // if (to_turn_on_sd) { - // turn_on_sd(); - // } + read_ads131(&hspi1); + read_max30101(&hi2c1); - // if (to_turn_off_sd) { - // turn_off_sd(); - // } - // continue; - /* USER CODE END WHILE */ + if (to_open_sd) { + open_sd(); + } + + if (to_close_sd) { + close_sd(); + } - /* USER CODE BEGIN 3 */ if (print_desc) { data_description(true, false); print_desc = false; } if (to_recordTime) { - struct packet_rtc p_rtc; - p_rtc.t = ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT; + p_rtc.t = total_tim6(); HAL_RTC_GetTime(&hrtc, &p_rtc.sTime, RTC_FORMAT_BCD); HAL_RTC_GetDate(&hrtc, &p_rtc.sDate, RTC_FORMAT_BCD); write(p_rtc); @@ -259,25 +291,24 @@ int main(void) } if (to_recordVbatt) { - adc_ready = 0; + adc_ready = false; HAL_ADC_Start_IT(&hadc1); to_recordVbatt = false; } if (adc_ready) { - adc_ready = 0; - struct packet_vbatt p_vbatt; - p_vbatt.t = ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT; - p_vbatt.vbatt_cnts = HAL_ADC_GetValue(&hadc1); + adc_ready = false; + p_vbatt.t = total_tim6(); + p_vbatt.vbatt_cnts = adc_value; write(p_vbatt); } - read_ads131(&hspi1); - read_lsm6dsv(&hspi1); - // HAL_GPIO_WritePin(GPIOB, LED1_Pin|LED2_Pin|LED3_Pin, GPIO_PIN_SET); - // HAL_Delay(100); - // HAL_GPIO_WritePin(GPIOB, LED1_Pin|LED2_Pin|LED3_Pin, GPIO_PIN_RESET); - // HAL_Delay(100); + if (usb_ready and total_tim6() - usb_buff.last_write > 4000) { + extern dbl_buff<1024, usb_send> usb_buff; + extern dbl_buff<1024, uart_send> ble_buff; + usb_buff.send(); + ble_buff.send(); + } } /* USER CODE END 3 */ } diff --git a/code/l452_code/Core/Src/max30101.cpp b/code/l452_code/Core/Src/max30101.cpp index 71cf4e8..fc746c2 100644 --- a/code/l452_code/Core/Src/max30101.cpp +++ b/code/l452_code/Core/Src/max30101.cpp @@ -8,7 +8,6 @@ #include "packet.hpp" #include "buff.hpp" -extern uint16_t tim6_reloads; struct packet_spo2 p_spo2; uint8_t data[4]; @@ -61,7 +60,7 @@ void initialize_max30101(I2C_HandleTypeDef *hi2c1) { void read_max30101(I2C_HandleTypeDef *hi2c1) { if (print_ready) { - p_spo2.t = ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT; + p_spo2.t = total_tim6(); write(p_spo2); print_ready = false; } diff --git a/code/l452_code/Core/Src/spi.c b/code/l452_code/Core/Src/spi.c index fb65223..2d988f6 100644 --- a/code/l452_code/Core/Src/spi.c +++ b/code/l452_code/Core/Src/spi.c @@ -44,7 +44,7 @@ void MX_SPI1_Init(void) hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; - hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; diff --git a/code/l452_code/Core/Src/tim.c b/code/l452_code/Core/Src/tim.c index e551993..b508496 100644 --- a/code/l452_code/Core/Src/tim.c +++ b/code/l452_code/Core/Src/tim.c @@ -21,7 +21,7 @@ #include "tim.h" /* USER CODE BEGIN 0 */ - +volatile uint16_t tim6_reloads = 0; /* USER CODE END 0 */ TIM_HandleTypeDef htim2; diff --git a/code/l452_code/Makefile b/code/l452_code/Makefile index 06ae779..6c966f1 100644 --- a/code/l452_code/Makefile +++ b/code/l452_code/Makefile @@ -1,5 +1,5 @@ ########################################################################################################################## -# File automatically-generated by tool: [projectgenerator] version: [4.9.0-B19] date: [Thu May 07 13:29:52 CDT 2026] +# File automatically-generated by tool: [projectgenerator] version: [4.9.0-B19] date: [Fri May 08 12:05:31 CDT 2026] ########################################################################################################################## # ------------------------------------------------ diff --git a/code/l452_code/l452_code.ioc b/code/l452_code/l452_code.ioc index 2588b9d..3d2277a 100644 --- a/code/l452_code/l452_code.ioc +++ b/code/l452_code/l452_code.ioc @@ -362,9 +362,9 @@ SH.GPXTI5.0=GPIO_EXTI5 SH.GPXTI5.ConfNb=1 SH.S_TIM2_ETR.0=TIM2_ETR,ClockSourceETR_Mode2 SH.S_TIM2_ETR.ConfNb=1 -SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_64 +SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16 SPI1.CLKPhase=SPI_PHASE_2EDGE -SPI1.CalculateBaudRate=1.25 MBits/s +SPI1.CalculateBaudRate=5.0 MBits/s SPI1.DataSize=SPI_DATASIZE_8BIT SPI1.Direction=SPI_DIRECTION_2LINES SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPhase diff --git a/code/l452_code/packet_parser_serial.py b/code/l452_code/packet_parser_serial.py index e1187bb..eef7e34 100644 --- a/code/l452_code/packet_parser_serial.py +++ b/code/l452_code/packet_parser_serial.py @@ -4,47 +4,31 @@ from scipy import signal import time import serial -ser = serial.Serial(port = '/dev/ttyACM1', timeout = 10.0) -ser.reset_input_buffer() -start = time.time() -for i in range(50): - ser.write(b'R') - cons = ser.read(1024) -print(1024 * 50 / (time.time() - start)) -quit() - -format_string=( - b"""packet_rtc 1 28 uint32_t t 0 4 RTC_TimeTypeDef sTime 4 20 RTC_DateTypeDef sDate 24 4 -packet_vbatt 2 8 uint32_t t 0 4 uint16_t vbatt_cnts 4 2 -packet_imu 9 12 uint32_t t 0 4 uint16_t readings_cnts[4] 4 2 -packet_ekg 3 208 uint32_t t 0 4 uint8_t index 4 1 int32_t readings_cnts[50] 8 4 -packet_strain 4 28 uint32_t t 0 4 uint8_t index 4 1 int32_t readings_cnts[5] 8 4 -packet_outsideT 5 28 uint32_t t 0 4 uint8_t index 4 1 int32_t readings_cnts[5] 8 4 -packet_insideT 6 28 uint32_t t 0 4 uint8_t index 4 1 int32_t readings_cnts[5] 8 4 -packet_button 7 8 uint32_t t 0 4 uint8_t button_vec 4 1 -packet_spo2 8 304 uint32_t t 0 4 uint32_t green_cnts[25] 4 4 uint32_t red_cnts[25] 104 4 uint32_t ir_cnts[25] 204 4""") - -types = [] - def arr_sizes(s): if s[-1:] != b']' or b'[' not in s: return 1 v = int(s[s.rindex(b'[') + 1:-1]) return v -for line in format_string.split(b"\n"): - line = line.strip(b'\n').strip(b'\r') - if line != b'': - L = line.split(b" ") - types.append({'type_name' : L[0], - 'type_code' : int(L[1]), - 'size' : int(L[2]), - 'elements' : [] - }) - i = 3 - while i < len(L): - types[-1]['elements'].append({'type_name' : L[i], 'name' : L[i + 1], 'offset' : int(L[i + 2]), 'n_elements' : arr_sizes(L[i + 1]), 'size' : int(L[i + 3]) * arr_sizes(L[i + 1]), 'readings' : []}) - i += 4 +def get_type_list(ser): + ser.write(b'?') + + types = [] + + for i in range(13): + line = ser.readline().strip(b'\n').strip(b'\r') + if line != b'': + L = line.split(b" ") + types.append({'type_name' : L[0], + 'type_code' : int(L[1]), + 'size' : int(L[2]), + 'elements' : [] + }) + i = 3 + while i < len(L): + types[-1]['elements'].append({'type_name' : L[i], 'name' : L[i + 1], 'offset' : int(L[i + 2]), 'n_elements' : arr_sizes(L[i + 1]), 'size' : int(L[i + 3]) * arr_sizes(L[i + 1])}) + i += 4 + return types def my_filter(arr): inds = np.where(np.abs(np.diff(arr)) > 0.005)[0] @@ -57,81 +41,125 @@ def my_filter(arr): next_ind += 1 arr[ind] = 0.5 * arr[prev_ind] + 0.5 * arr[next_ind] return arr - -def update_with_data(): - nyquist = 0.5 * 250 - b, a = signal.butter(2, 100 / nyquist, btype='low', analog = False) - - fig, axs = plt.subplots(2) - adcs = [] - accs = [] - gyros = [] + +accs = [] +gyros = [] +def process_imu(d, t): + global accs + global gyros + for e in t['elements']: + block = d[e['offset']:e['offset'] + e['size']] + element_size = int(len(block) / e['n_elements']) + if e['name'] == b'data[141]': + for i in range(20): + reading = block[1 + 7 * i : 8 + 7 * i] + #print(reading) + imu_reading_type = reading[0] >> 3 + imu_reading_tag_cnt = (reading[0] >> 1) & 3 + data = np.array([int.from_bytes(reading[2 * i + 1 : 2 * i + 3], byteorder = 'little', signed = True) for i in range(3)]) + if imu_reading_type == 1: + gyros.append(250 / (1<<16) * data) + elif imu_reading_type == 2: + accs.append(4 / (1<<16) * data) + else: + assert False + if len(gyros) > 400: + gyros = gyros[-400:] + if len(accs) > 400: + accs = accs[-400:] + fig, axs = plt.subplots(2) + g = np.array(gyros) + a = np.array(accs) + axs[0].set_ylabel("dps") + axs[0].plot(g[:,0]) + axs[0].plot(g[:,1]) + axs[0].plot(g[:,2]) + axs[1].set_ylabel("g") + axs[1].plot(a[:,0]) + axs[1].plot(a[:,1]) + axs[1].plot(a[:,2]) + plt.savefig("acc_gyro.png") + plt.close() + + +def update_with_data(ser, types): - ser = serial.Serial(port = '/dev/ttyACM1', timeout = 10.0) + ser.timeout = 3 ser.reset_input_buffer() start = time.time() while(True): - ser.write(b'R') - cons = ser.read(1024) - if True: - index = 0 - while (index < 1024): - #print(index, len(cons)) - packet_type = (cons[index + 1]<<8) + cons[index] - print(index, packet_type) - ind = [i for i,t in enumerate(types) if t['type_code'] == packet_type] - if len(ind) != 1: - break - t = types[ind[0]] - d = cons[index + 2 : index + 2 + t['size']] - for e in t['elements']: - block = d[e['offset']:e['offset'] + e['size']] - element_size = int(len(block) / e['n_elements']) - if t['type_name'] == b'packet_ekg' and e['name'] == b'readings_cnts[50]': - chunked = [(2.4 / (1<<24)) * int.from_bytes(block[i:i + element_size], byteorder='little', signed = True) for i in range(0, len(block), element_size)] - adcs += chunked - if len(adcs) > 500: - dat = np.array(adcs[-2048:]) - if len(adcs) > 2048: - adcs = adcs[-2048:] - #filtered_dat = my_filter(dat) - filtered_dat = dat - filtered_dat = signal.filtfilt(b, a, filtered_dat) - dd = np.sort(dat) - center = 0.5 * (dd[-100] + dd[100]) - range_ = dd[-100] - dd[100] - if len(dat) == 2048: - print("Freq:", 2048 / (time.time() - start)) - axs[0].cla() - axs[1].cla() - axs[0].set_title("ADC {:3.3f}mV".format(1000 * (range_))) - - #axs[0].plot(dat, 'r.', linestyle = '--') - axs[0].plot(filtered_dat, 'k.', linestyle = '--') - #axs[0].set_ylim(center - range_, center + range_) - _fft = np.log(np.abs(np.fft.fft(filtered_dat)[1:])) - axs[1].plot(250 * np.fft.fftfreq(dat.shape[-1])[1:], _fft, 'k.') - axs[1].axvline(x = 60) - plt.savefig("image.png") + ser.write(b'r') + size = int.from_bytes(ser.read(4), byteorder = 'little', signed = False) + cons = ser.read(size) + index = 0 + while (index < size): + packet_type = cons[index] + t = [t for t in types if t['type_code'] == packet_type][0] + #print(index, packet_type, t['type_name']) + d = cons[index + 1 : index + 1 + t['size']] + if t['type_name'] == b'packet_imu': + process_imu(d, t) + if t['type_name'] == b'packet_msg': + print(d) + index += 1 + t['size'] + + # if t['type_name'] == b'packet_ekg' and e['name'] == b'readings_cnts[50]': + # chunked = [(2.4 / (1<<24)) * int.from_bytes(block[i:i + element_size], byteorder='little', signed = True) for i in range(0, len(block), element_size)] + # adcs += chunked + # if len(adcs) > 500: + # dat = np.array(adcs[-2048:]) + # if len(adcs) > 2048: + # adcs = adcs[-2048:] + # #filtered_dat = my_filter(dat) + # filtered_dat = dat + # filtered_dat = signal.filtfilt(b, a, filtered_dat) + # dd = np.sort(dat) + # center = 0.5 * (dd[-100] + dd[100]) + # range_ = dd[-100] - dd[100] + # if len(dat) == 2048: + # print("Freq:", 2048 / (time.time() - start)) + # axs[0].cla() + # axs[1].cla() + # axs[0].set_title("ADC {:3.3f}mV".format(1000 * (range_))) + + # #axs[0].plot(dat, 'r.', linestyle = '--') + # axs[0].plot(filtered_dat, 'k.', linestyle = '--') + # #axs[0].set_ylim(center - range_, center + range_) + # _fft = np.log(np.abs(np.fft.fft(filtered_dat)[1:])) + # axs[1].plot(250 * np.fft.fftfreq(dat.shape[-1])[1:], _fft, 'k.') + # axs[1].axvline(x = 60) + # plt.savefig("image.png") + + # if t['type_name'] == b'packet_imu' and e['name'] == b'readings_cnts[4]': + # imu_reading_type = block[0] >> 3 + # imu_reading_tag_cnt = (block[0] >> 1) & 3 + # reading_xyz = [int.from_bytes(block[2:4], byteorder = 'big', signed = True), + # int.from_bytes(block[4:6], byteorder = 'big', signed = True), + # int.from_bytes(block[6:8], byteorder = 'big', signed = True)] + # if imu_reading_type == 1: + # #print("{:02x} {:d}".format(imu_reading_type, imu_reading_tag_cnt)) + # gyros.append([250 * e / (1<<16) for e in reading_xyz]) + # elif imu_reading_type == 2: + # accs.append([4 * e / (1<<16) for e in reading_xyz]) + # else: + # print("ERR") - if t['type_name'] == b'packet_imu' and e['name'] == b'readings_cnts[4]': - imu_reading_type = block[0] >> 3 - imu_reading_tag_cnt = (block[0] >> 1) & 3 - reading_xyz = [int.from_bytes(block[2:4], byteorder = 'big', signed = True), - int.from_bytes(block[4:6], byteorder = 'big', signed = True), - int.from_bytes(block[6:8], byteorder = 'big', signed = True)] - if imu_reading_type == 1: - #print("{:02x} {:d}".format(imu_reading_type, imu_reading_tag_cnt)) - gyros.append([250 * e / (1<<16) for e in reading_xyz]) - elif imu_reading_type == 2: - accs.append([4 * e / (1<<16) for e in reading_xyz]) - else: - print("ERR") - index += 2 + t['size'] def main(): - update_with_data() + + ser = serial.Serial(port = '/dev/ttyACM1', timeout = 0.5) + ser.flush() + ser.reset_input_buffer() + + types = get_type_list(ser) + + # ser.write(b'1') + # ser.write(b'3') + # ser.write(b'5') + ser.flush() + + update_with_data(ser, types) main() diff --git a/code/wb1mmc_code/Core/Src/main.c b/code/wb1mmc_code/Core/Src/main.c index 3212f03..7aee45f 100644 --- a/code/wb1mmc_code/Core/Src/main.c +++ b/code/wb1mmc_code/Core/Src/main.c @@ -77,7 +77,6 @@ void SendNotifyTask(void) { return; } for (int i = 0; i < 8; ++i) { - //memcpy(notify_buffer, uart_rx_data, sizeof(notify_buffer)); Custom_STM_App_Update_Char( CUSTOM_STM_ARRREAD, uart_rx_data + i * 128 @@ -85,19 +84,20 @@ void SendNotifyTask(void) { } } -void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { - HAL_GPIO_TogglePin(GPIOA, LED4_Pin); - //memcpy(notify_buffer, uart_rx_data, sizeof(notify_buffer));// do second half later +void HAL_UARTEx_RxEventCpltCallback(UART_HandleTypeDef *huart, uint16_t Size) { + //HAL_GPIO_TogglePin(GPIOA, LED4_Pin); UTIL_SEQ_SetTask(1<Instance == TIM2) { + HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data)); } } /* USER CODE END 0 */ @@ -155,8 +155,13 @@ int main(void) /* USER CODE BEGIN WHILE */ HAL_TIM_Base_Start_IT(&htim2); UTIL_SEQ_RegTask(1<Attr_Handle == (CustomContext.CustomArrwriteHdle + CHARACTERISTIC_VALUE_ATTRIBUTE_OFFSET))*/ /* USER CODE BEGIN EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_END */