Compare commits
2 Commits
02517fe9ae
...
2b5ade4bec
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b5ade4bec | |||
| 41ec35233d |
@@ -3,66 +3,99 @@
|
|||||||
#include "fatfs.h"
|
#include "fatfs.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
#include "usbd_cdc_if.h"
|
#include "usbd_cdc_if.h"
|
||||||
|
#include "tim.h"
|
||||||
#include "packet.hpp"
|
#include "packet.hpp"
|
||||||
|
|
||||||
extern uint8_t databank1[1024];
|
void sd_send(uint8_t data[], uint32_t len);
|
||||||
extern uint8_t databank2[1024];
|
void usb_send(uint8_t data[], uint32_t len);
|
||||||
extern uint16_t pos;
|
void uart_send(uint8_t data[], uint32_t len);
|
||||||
|
|
||||||
volatile extern bool usb_ready;
|
template<int N, void (*send_fn)(uint8_t data[], uint32_t len)>
|
||||||
volatile extern bool wb1mmc_ready;
|
struct dbl_buff {
|
||||||
volatile extern bool sd_ready;
|
uint32_t last_write;
|
||||||
extern FIL file;
|
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;
|
||||||
|
|
||||||
// Every time we get a reading add to the active databank if it fits,
|
dbl_buff() : databank1(send_buffer1 + 4), databank2(send_buffer2 + 4) {};
|
||||||
// if not we switch banks and write out the now unactive databank
|
|
||||||
template<typename packet_type>
|
|
||||||
void write(packet_type packet) {
|
|
||||||
if (pos + sizeof(packet) + 2 < sizeof(databank1)) {
|
|
||||||
*(uint16_t*)(&databank1[pos]) = typecode<packet_type>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (wb1mmc_ready) {
|
|
||||||
HAL_UART_Transmit_DMA(&huart1, databank1, sizeof(databank1));
|
|
||||||
wb1mmc_ready = false;
|
|
||||||
}
|
|
||||||
if (sd_ready) {
|
|
||||||
UINT bytes_written;
|
|
||||||
FRESULT res = f_write(&file, databank1, sizeof(databank1), &bytes_written);
|
|
||||||
if (res != FR_OK || bytes_written != sizeof(databank1)) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(databank2, 0, sizeof(databank2));
|
// Every time we get a reading add to the active databank if it fits,
|
||||||
pos = sizeof(databank1);
|
// if not we switch banks and write out the now unactive databank
|
||||||
return write(packet);
|
template<typename packet_type> void write(const packet_type& packet) {
|
||||||
} else if (pos + sizeof(packet) + 2 <
|
if (pos + sizeof(packet_type) + 1 < N) {
|
||||||
sizeof(databank1) + sizeof(databank2)) {
|
databank1[pos] = typecode<packet_type>();
|
||||||
*(uint16_t*)(&databank2[pos - sizeof(databank1)]) = typecode<packet_type>();
|
memcpy(databank1 + pos + 1, &packet, sizeof(packet_type));
|
||||||
memcpy(databank2 + pos + 2 - sizeof(databank1), &packet, sizeof(packet));
|
pos += sizeof(packet_type) + 1;
|
||||||
pos += sizeof(packet) + 2;
|
return;
|
||||||
return;
|
} else if (pos < N) {
|
||||||
} else {
|
send();
|
||||||
if (usb_ready) {
|
return this->write(packet);
|
||||||
CDC_Transmit_FS(databank2, sizeof(databank2));
|
} else if (pos + sizeof(packet_type) + 1 < 2 * N) {
|
||||||
usb_ready = false;
|
databank2[pos - N] = typecode<packet_type>();
|
||||||
|
memcpy(databank2 + pos + 1 - N, &packet, sizeof(packet_type));
|
||||||
|
pos += sizeof(packet_type) + 1;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
send();
|
||||||
|
return this->write(packet);
|
||||||
}
|
}
|
||||||
if (wb1mmc_ready) {
|
};
|
||||||
HAL_UART_Transmit_DMA(&huart1, databank2, sizeof(databank2));
|
|
||||||
wb1mmc_ready = false;
|
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;
|
||||||
}
|
}
|
||||||
if (sd_ready) {
|
last_write = total_tim6();
|
||||||
UINT bytes_written;
|
|
||||||
FRESULT res = f_write(&file, databank2, sizeof(databank2), &bytes_written);
|
|
||||||
if (res != FR_OK || bytes_written != sizeof(databank2)) {}
|
|
||||||
}
|
|
||||||
memset(databank1, 0, sizeof(databank1));
|
|
||||||
pos = 0;
|
|
||||||
return write(packet);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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<typename packet_type>
|
||||||
|
void write(packet_type packet) {
|
||||||
|
sd_buff.write(packet);
|
||||||
|
if (typecode<packet_type>() == typecode<packet_imu>()) {
|
||||||
|
if (send_imu_usb) {
|
||||||
|
usb_buff.write(packet);
|
||||||
|
}
|
||||||
|
if (send_imu_ble) {
|
||||||
|
ble_buff.write(packet);
|
||||||
|
}
|
||||||
|
} else if (typecode<packet_type>() == typecode<packet_adc>()) {
|
||||||
|
if (send_adc_usb) {
|
||||||
|
usb_buff.write(packet);
|
||||||
|
}
|
||||||
|
if (send_adc_ble) {
|
||||||
|
ble_buff.write(packet);
|
||||||
|
}
|
||||||
|
} else if (typecode<packet_type>() == typecode<packet_spo2>()) {
|
||||||
|
if (send_ppg_usb) {
|
||||||
|
usb_buff.write(packet);
|
||||||
|
}
|
||||||
|
if (send_ppg_ble) {
|
||||||
|
ble_buff.write(packet);
|
||||||
|
}
|
||||||
|
} else { // Send other types unconditionally
|
||||||
|
usb_buff.write(packet);
|
||||||
|
ble_buff.write(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,7 +37,10 @@ extern TIM_HandleTypeDef htim2;
|
|||||||
extern TIM_HandleTypeDef htim6;
|
extern TIM_HandleTypeDef htim6;
|
||||||
|
|
||||||
/* USER CODE BEGIN Private defines */
|
/* 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 */
|
/* USER CODE END Private defines */
|
||||||
|
|
||||||
void MX_TIM2_Init(void);
|
void MX_TIM2_Init(void);
|
||||||
|
|||||||
@@ -10,9 +10,14 @@ void initialize_ads131(SPI_HandleTypeDef *hspi1) {
|
|||||||
uint8_t cmd[6] = {0x00, 0x11, 0x00};
|
uint8_t cmd[6] = {0x00, 0x11, 0x00};
|
||||||
uint8_t rx_buff[18];
|
uint8_t rx_buff[18];
|
||||||
|
|
||||||
HAL_SPI_DeInit(hspi1);
|
while (__HAL_SPI_GET_FLAG(hspi1, SPI_FLAG_BSY));
|
||||||
hspi1->Init.CLKPolarity = SPI_POLARITY_LOW;
|
__HAL_SPI_DISABLE(hspi1);
|
||||||
HAL_SPI_Init(hspi1);
|
|
||||||
|
MODIFY_REG(hspi1->Instance->CR1,
|
||||||
|
SPI_CR1_CPOL | SPI_CR1_CPHA,
|
||||||
|
SPI_POLARITY_LOW | SPI_PHASE_2EDGE);
|
||||||
|
|
||||||
|
__HAL_SPI_ENABLE(hspi1);
|
||||||
|
|
||||||
// reset
|
// reset
|
||||||
HAL_GPIO_WritePin(GPIOA, ADC_CS_Pin, GPIO_PIN_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;
|
struct packet_adc p_adc;
|
||||||
|
|
||||||
extern volatile uint16_t tim6_reloads;
|
|
||||||
|
|
||||||
void read_ads131(SPI_HandleTypeDef *hspi1) {
|
void read_ads131(SPI_HandleTypeDef *hspi1) {
|
||||||
|
|
||||||
if (HAL_GPIO_ReadPin(GPIOA, ADC_DRDY_Pin) != GPIO_PIN_RESET) {
|
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 cmd[6] = {0x0};
|
||||||
uint8_t rx_buff[16] = {0x0};
|
uint8_t rx_buff[16] = {0x0};
|
||||||
|
|
||||||
HAL_SPI_DeInit(hspi1);
|
while (__HAL_SPI_GET_FLAG(hspi1, SPI_FLAG_BSY));
|
||||||
hspi1->Init.CLKPolarity = SPI_POLARITY_LOW;
|
__HAL_SPI_DISABLE(hspi1);
|
||||||
HAL_SPI_Init(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_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_SPI_TransmitReceive(hspi1, (uint8_t*) cmd, (uint8_t*) rx_buff, 18, HAL_MAX_DELAY);
|
||||||
HAL_GPIO_WritePin(GPIOA, ADC_CS_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(GPIOA, ADC_CS_Pin, GPIO_PIN_SET);
|
||||||
|
|
||||||
if (p_adc.index == 0) {
|
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]);
|
p_adc.ekg_readings_cnts[p_adc.index] = to_signed_24(&rx_buff[3]);
|
||||||
|
|||||||
@@ -1,6 +1,32 @@
|
|||||||
//#include "buff.hpp"
|
#include "buff.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
alignas(32) uint8_t databank1[1024];
|
void sd_send(uint8_t data[], uint32_t len) {
|
||||||
alignas(32) uint8_t databank2[1024];
|
extern bool sd_ready;
|
||||||
uint16_t pos = 0;
|
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;
|
||||||
|
|||||||
@@ -4,80 +4,64 @@
|
|||||||
#include "tim.h"
|
#include "tim.h"
|
||||||
#include "buff.hpp"
|
#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) {
|
void initialize_lsm6dsv(SPI_HandleTypeDef *hspi1) {
|
||||||
|
|
||||||
uint8_t tx_buff[8] = {0};
|
uint8_t tx_buff[2] = {0};
|
||||||
uint8_t rx_buff[8] = {0};
|
uint8_t rx_buff[2] = {0};
|
||||||
|
|
||||||
HAL_SPI_DeInit(hspi1);
|
while (__HAL_SPI_GET_FLAG(hspi1, SPI_FLAG_BSY));
|
||||||
hspi1->Init.CLKPolarity = SPI_POLARITY_HIGH;
|
__HAL_SPI_DISABLE(hspi1);
|
||||||
HAL_SPI_Init(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[0] = 0x01; // Reset
|
||||||
tx_buff[1] = 0x04;
|
tx_buff[1] = 0x04;
|
||||||
HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET);
|
send_receive_lsm6dsv(tx_buff, rx_buff, 2);
|
||||||
HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY);
|
HAL_Delay(100);
|
||||||
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);
|
|
||||||
|
|
||||||
tx_buff[0] = 0x0A; // Set bypass mode for fifo
|
tx_buff[0] = 0x0A; // Set bypass mode for fifo
|
||||||
tx_buff[1] = 0b00000000; // to clear fifo
|
tx_buff[1] = 0b00000000; // to clear fifo
|
||||||
HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET);
|
send_receive_lsm6dsv(tx_buff, rx_buff, 2);
|
||||||
HAL_SPI_TransmitReceive(hspi1, tx_buff, rx_buff, 2, HAL_MAX_DELAY);
|
|
||||||
HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET);
|
tx_buff[0] = 0x03; // active high pushpull interrupt
|
||||||
HAL_Delay(30);
|
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[0] = 0x0A; // Set continuous mode for fifo
|
||||||
tx_buff[1] = 0b00000110;
|
tx_buff[1] = 0b00000110;
|
||||||
HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET);
|
send_receive_lsm6dsv(tx_buff, rx_buff, 2);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct packet_imu p_imu;
|
struct packet_imu p_imu;
|
||||||
@@ -88,17 +72,20 @@ void read_lsm6dsv(SPI_HandleTypeDef *hspi1) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HAL_SPI_DeInit(hspi1);
|
while (__HAL_SPI_GET_FLAG(hspi1, SPI_FLAG_BSY));
|
||||||
hspi1->Init.CLKPolarity = SPI_POLARITY_HIGH;
|
__HAL_SPI_DISABLE(hspi1);
|
||||||
HAL_SPI_Init(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
|
uint8_t tx_buff[141] = {0b10000000 + 0x78}; // FIFO addr
|
||||||
|
|
||||||
// Watermark set for 21 samples, read 20
|
// Watermark set for 21 samples, read 20
|
||||||
tx_buff[0] = 0b10000000 + 0x78; // FIFO addr
|
tx_buff[0] = 0b10000000 + 0x78; // FIFO addr
|
||||||
p_imu.t = ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT;
|
p_imu.t = total_tim6();
|
||||||
HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_RESET);
|
send_receive_lsm6dsv(tx_buff, p_imu.data, 141);
|
||||||
HAL_SPI_TransmitReceive(hspi1, tx_buff, p_imu.data, 141, HAL_MAX_DELAY);
|
|
||||||
HAL_GPIO_WritePin(GPIOC, IMU_CS_Pin, GPIO_PIN_SET);
|
|
||||||
write(p_imu);
|
write(p_imu);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,26 @@
|
|||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
|
||||||
/* USER CODE BEGIN PV */
|
/* 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 */
|
/* USER CODE END PV */
|
||||||
|
|
||||||
@@ -73,32 +93,17 @@ void PeriphCommonClock_Config(void);
|
|||||||
|
|
||||||
/* Private user code ---------------------------------------------------------*/
|
/* Private user code ---------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN 0 */
|
/* 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) {
|
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
|
||||||
if (hadc->Instance == ADC1) {
|
if (hadc->Instance == ADC1) {
|
||||||
adc_value = HAL_ADC_GetValue(hadc);
|
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) {
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
||||||
if (htim->Instance == TIM6) {
|
if (htim->Instance == TIM6) {
|
||||||
tim6_reloads += 1;
|
tim6_reloads += 1;
|
||||||
@@ -107,34 +112,63 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile bool to_turn_on_sd = false;
|
volatile bool to_open_sd = false;
|
||||||
volatile bool to_turn_off_sd = false;
|
volatile bool to_close_sd = false;
|
||||||
void USB_CDC_RxHandler(uint8_t* Buf, uint32_t Len) {
|
void comm_handler(uint8_t ch) {
|
||||||
if (memcmp(Buf, "R", Len) == 0) {
|
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;
|
usb_ready = true;
|
||||||
}
|
break;
|
||||||
if (memcmp(Buf, "S", Len) == 0) {
|
case 'R':
|
||||||
to_turn_off_sd = true;
|
wb1mmc_ready = true;
|
||||||
}
|
break;
|
||||||
if (memcmp(Buf, "T", Len) == 0) {
|
case 'S':
|
||||||
to_turn_on_sd = true;
|
to_close_sd = true;
|
||||||
}
|
break;
|
||||||
if (memcmp(Buf, "?", Len) == 0) {
|
case 'T':
|
||||||
|
to_open_sd = true;
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
print_desc = true;
|
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) {
|
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
|
||||||
if (uart_rx_data[0] == 'R') {
|
comm_handler(uart_rx_data[0]);
|
||||||
wb1mmc_ready = true;
|
|
||||||
}
|
|
||||||
HAL_UART_Receive_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data));
|
HAL_UART_Receive_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {}
|
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {}
|
||||||
|
|
||||||
void turn_on_sd(void) {
|
void open_sd(void) {
|
||||||
to_turn_on_sd = false;
|
to_open_sd = false;
|
||||||
if (BSP_SD_IsDetected() != SD_PRESENT) {
|
if (BSP_SD_IsDetected() != SD_PRESENT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -159,13 +193,14 @@ void turn_on_sd(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void turn_off_sd(void) {
|
void close_sd(void) {
|
||||||
to_turn_off_sd = false;
|
sd_ready = false;
|
||||||
|
to_close_sd = false;
|
||||||
if (sd_ready) {
|
if (sd_ready) {
|
||||||
f_sync(&file);
|
f_sync(&file);
|
||||||
f_close(&file);
|
f_close(&file);
|
||||||
res = f_mount(NULL, "", 1);
|
res = f_mount(NULL, "", 1);
|
||||||
sd_ready = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* USER CODE END 0 */
|
/* USER CODE END 0 */
|
||||||
@@ -214,44 +249,41 @@ int main(void)
|
|||||||
MX_USB_DEVICE_Init();
|
MX_USB_DEVICE_Init();
|
||||||
MX_FATFS_Init();
|
MX_FATFS_Init();
|
||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
|
struct packet_vbatt p_vbatt;
|
||||||
|
struct packet_rtc p_rtc;
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
/* USER CODE BEGIN WHILE */
|
/* USER CODE BEGIN WHILE */
|
||||||
HAL_TIM_Base_Start_IT(&htim6);
|
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)
|
while (1)
|
||||||
{
|
{
|
||||||
read_lsm6dsv(&hspi1);
|
read_lsm6dsv(&hspi1);
|
||||||
//read_max30101(&hi2c1);
|
read_ads131(&hspi1);
|
||||||
//read_ads131(&hspi1);
|
read_max30101(&hi2c1);
|
||||||
HAL_Delay(1);
|
|
||||||
continue;
|
|
||||||
// if (to_turn_on_sd) {
|
|
||||||
// turn_on_sd();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (to_turn_off_sd) {
|
if (to_open_sd) {
|
||||||
// turn_off_sd();
|
open_sd();
|
||||||
// }
|
}
|
||||||
// continue;
|
|
||||||
/* USER CODE END WHILE */
|
if (to_close_sd) {
|
||||||
|
close_sd();
|
||||||
|
}
|
||||||
|
|
||||||
/* USER CODE BEGIN 3 */
|
|
||||||
if (print_desc) {
|
if (print_desc) {
|
||||||
data_description(true, false);
|
data_description(true, false);
|
||||||
print_desc = false;
|
print_desc = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_recordTime) {
|
if (to_recordTime) {
|
||||||
struct packet_rtc p_rtc;
|
p_rtc.t = total_tim6();
|
||||||
p_rtc.t = ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT;
|
|
||||||
HAL_RTC_GetTime(&hrtc, &p_rtc.sTime, RTC_FORMAT_BCD);
|
HAL_RTC_GetTime(&hrtc, &p_rtc.sTime, RTC_FORMAT_BCD);
|
||||||
HAL_RTC_GetDate(&hrtc, &p_rtc.sDate, RTC_FORMAT_BCD);
|
HAL_RTC_GetDate(&hrtc, &p_rtc.sDate, RTC_FORMAT_BCD);
|
||||||
write(p_rtc);
|
write(p_rtc);
|
||||||
@@ -259,25 +291,27 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (to_recordVbatt) {
|
if (to_recordVbatt) {
|
||||||
adc_ready = 0;
|
adc_ready = false;
|
||||||
HAL_ADC_Start_IT(&hadc1);
|
HAL_ADC_Start_IT(&hadc1);
|
||||||
to_recordVbatt = false;
|
to_recordVbatt = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adc_ready) {
|
if (adc_ready) {
|
||||||
adc_ready = 0;
|
adc_ready = false;
|
||||||
struct packet_vbatt p_vbatt;
|
p_vbatt.t = total_tim6();
|
||||||
p_vbatt.t = ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT;
|
p_vbatt.vbatt_cnts = adc_value;
|
||||||
p_vbatt.vbatt_cnts = HAL_ADC_GetValue(&hadc1);
|
|
||||||
write(p_vbatt);
|
write(p_vbatt);
|
||||||
}
|
}
|
||||||
|
|
||||||
read_ads131(&hspi1);
|
if (usb_ready and total_tim6() - usb_buff.last_write > 4000) {
|
||||||
read_lsm6dsv(&hspi1);
|
extern dbl_buff<1024, usb_send> usb_buff;
|
||||||
// HAL_GPIO_WritePin(GPIOB, LED1_Pin|LED2_Pin|LED3_Pin, GPIO_PIN_SET);
|
usb_buff.send();
|
||||||
// HAL_Delay(100);
|
}
|
||||||
// HAL_GPIO_WritePin(GPIOB, LED1_Pin|LED2_Pin|LED3_Pin, GPIO_PIN_RESET);
|
|
||||||
// HAL_Delay(100);
|
if (wb1mmc_ready and total_tim6() - ble_buff.last_write > 4000) {
|
||||||
|
extern dbl_buff<1024, uart_send> ble_buff;
|
||||||
|
ble_buff.send();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* USER CODE END 3 */
|
/* USER CODE END 3 */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "packet.hpp"
|
#include "packet.hpp"
|
||||||
#include "buff.hpp"
|
#include "buff.hpp"
|
||||||
|
|
||||||
extern uint16_t tim6_reloads;
|
|
||||||
struct packet_spo2 p_spo2;
|
struct packet_spo2 p_spo2;
|
||||||
uint8_t data[4];
|
uint8_t data[4];
|
||||||
|
|
||||||
@@ -61,7 +60,7 @@ void initialize_max30101(I2C_HandleTypeDef *hi2c1) {
|
|||||||
|
|
||||||
void read_max30101(I2C_HandleTypeDef *hi2c1) {
|
void read_max30101(I2C_HandleTypeDef *hi2c1) {
|
||||||
if (print_ready) {
|
if (print_ready) {
|
||||||
p_spo2.t = ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT;
|
p_spo2.t = total_tim6();
|
||||||
write(p_spo2);
|
write(p_spo2);
|
||||||
print_ready = false;
|
print_ready = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ void MX_SPI1_Init(void)
|
|||||||
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
|
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||||
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
|
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
|
||||||
hspi1.Init.NSS = SPI_NSS_SOFT;
|
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.FirstBit = SPI_FIRSTBIT_MSB;
|
||||||
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
|
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||||
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
#include "tim.h"
|
#include "tim.h"
|
||||||
|
|
||||||
/* USER CODE BEGIN 0 */
|
/* USER CODE BEGIN 0 */
|
||||||
|
volatile uint16_t tim6_reloads = 0;
|
||||||
/* USER CODE END 0 */
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
TIM_HandleTypeDef htim2;
|
TIM_HandleTypeDef htim2;
|
||||||
|
|||||||
@@ -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]
|
||||||
##########################################################################################################################
|
##########################################################################################################################
|
||||||
|
|
||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
|
|||||||
@@ -362,9 +362,9 @@ SH.GPXTI5.0=GPIO_EXTI5
|
|||||||
SH.GPXTI5.ConfNb=1
|
SH.GPXTI5.ConfNb=1
|
||||||
SH.S_TIM2_ETR.0=TIM2_ETR,ClockSourceETR_Mode2
|
SH.S_TIM2_ETR.0=TIM2_ETR,ClockSourceETR_Mode2
|
||||||
SH.S_TIM2_ETR.ConfNb=1
|
SH.S_TIM2_ETR.ConfNb=1
|
||||||
SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_64
|
SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16
|
||||||
SPI1.CLKPhase=SPI_PHASE_2EDGE
|
SPI1.CLKPhase=SPI_PHASE_2EDGE
|
||||||
SPI1.CalculateBaudRate=1.25 MBits/s
|
SPI1.CalculateBaudRate=5.0 MBits/s
|
||||||
SPI1.DataSize=SPI_DATASIZE_8BIT
|
SPI1.DataSize=SPI_DATASIZE_8BIT
|
||||||
SPI1.Direction=SPI_DIRECTION_2LINES
|
SPI1.Direction=SPI_DIRECTION_2LINES
|
||||||
SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPhase
|
SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPhase
|
||||||
|
|||||||
@@ -4,47 +4,31 @@ from scipy import signal
|
|||||||
import time
|
import time
|
||||||
import serial
|
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):
|
def arr_sizes(s):
|
||||||
if s[-1:] != b']' or b'[' not in s:
|
if s[-1:] != b']' or b'[' not in s:
|
||||||
return 1
|
return 1
|
||||||
v = int(s[s.rindex(b'[') + 1:-1])
|
v = int(s[s.rindex(b'[') + 1:-1])
|
||||||
return v
|
return v
|
||||||
|
|
||||||
for line in format_string.split(b"\n"):
|
def get_type_list(ser):
|
||||||
line = line.strip(b'\n').strip(b'\r')
|
ser.write(b'?')
|
||||||
if line != b'':
|
|
||||||
L = line.split(b" ")
|
types = []
|
||||||
types.append({'type_name' : L[0],
|
|
||||||
'type_code' : int(L[1]),
|
for i in range(13):
|
||||||
'size' : int(L[2]),
|
line = ser.readline().strip(b'\n').strip(b'\r')
|
||||||
'elements' : []
|
if line != b'':
|
||||||
})
|
L = line.split(b" ")
|
||||||
i = 3
|
types.append({'type_name' : L[0],
|
||||||
while i < len(L):
|
'type_code' : int(L[1]),
|
||||||
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' : []})
|
'size' : int(L[2]),
|
||||||
i += 4
|
'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):
|
def my_filter(arr):
|
||||||
inds = np.where(np.abs(np.diff(arr)) > 0.005)[0]
|
inds = np.where(np.abs(np.diff(arr)) > 0.005)[0]
|
||||||
@@ -58,80 +42,125 @@ def my_filter(arr):
|
|||||||
arr[ind] = 0.5 * arr[prev_ind] + 0.5 * arr[next_ind]
|
arr[ind] = 0.5 * arr[prev_ind] + 0.5 * arr[next_ind]
|
||||||
return arr
|
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)
|
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()
|
||||||
|
|
||||||
adcs = []
|
|
||||||
accs = []
|
|
||||||
gyros = []
|
|
||||||
|
|
||||||
ser = serial.Serial(port = '/dev/ttyACM1', timeout = 10.0)
|
def update_with_data(ser, types):
|
||||||
|
|
||||||
|
ser.timeout = 3
|
||||||
ser.reset_input_buffer()
|
ser.reset_input_buffer()
|
||||||
start = time.time()
|
start = time.time()
|
||||||
while(True):
|
while(True):
|
||||||
ser.write(b'R')
|
ser.write(b'r')
|
||||||
cons = ser.read(1024)
|
size = int.from_bytes(ser.read(4), byteorder = 'little', signed = False)
|
||||||
if True:
|
cons = ser.read(size)
|
||||||
index = 0
|
index = 0
|
||||||
while (index < 1024):
|
while (index < size):
|
||||||
#print(index, len(cons))
|
packet_type = cons[index]
|
||||||
packet_type = (cons[index + 1]<<8) + cons[index]
|
t = [t for t in types if t['type_code'] == packet_type][0]
|
||||||
print(index, packet_type)
|
print(index, packet_type, t['type_name'])
|
||||||
ind = [i for i,t in enumerate(types) if t['type_code'] == packet_type]
|
d = cons[index + 1 : index + 1 + t['size']]
|
||||||
if len(ind) != 1:
|
if t['type_name'] == b'packet_imu':
|
||||||
break
|
pass
|
||||||
t = types[ind[0]]
|
#process_imu(d, t)
|
||||||
d = cons[index + 2 : index + 2 + t['size']]
|
if t['type_name'] == b'packet_msg':
|
||||||
for e in t['elements']:
|
print(d)
|
||||||
block = d[e['offset']:e['offset'] + e['size']]
|
index += 1 + t['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 = '--')
|
# if t['type_name'] == b'packet_ekg' and e['name'] == b'readings_cnts[50]':
|
||||||
axs[0].plot(filtered_dat, 'k.', linestyle = '--')
|
# 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)]
|
||||||
#axs[0].set_ylim(center - range_, center + range_)
|
# adcs += chunked
|
||||||
_fft = np.log(np.abs(np.fft.fft(filtered_dat)[1:]))
|
# if len(adcs) > 500:
|
||||||
axs[1].plot(250 * np.fft.fftfreq(dat.shape[-1])[1:], _fft, 'k.')
|
# dat = np.array(adcs[-2048:])
|
||||||
axs[1].axvline(x = 60)
|
# if len(adcs) > 2048:
|
||||||
plt.savefig("image.png")
|
# 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():
|
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()
|
main()
|
||||||
|
|||||||
@@ -65,19 +65,18 @@ void PeriphCommonClock_Config(void);
|
|||||||
/* Private user code ---------------------------------------------------------*/
|
/* Private user code ---------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN 0 */
|
/* USER CODE BEGIN 0 */
|
||||||
|
|
||||||
uint8_t uart_rx_data[1024];
|
uint8_t uart_rx_data[1028];
|
||||||
uint8_t uart_tx_data[1] = {'R'};
|
uint8_t uart_tx_data[1] = {'R'};
|
||||||
bool ready_for_data = false;
|
bool ready_for_data = false;
|
||||||
|
|
||||||
uint8_t notify_buffer[128];
|
volatile uint32_t xfer_len;
|
||||||
|
|
||||||
volatile bool do_notify = false;
|
volatile bool do_notify = false;
|
||||||
void SendNotifyTask(void) {
|
void SendNotifyTask(void) {
|
||||||
if (!do_notify) {
|
if (!do_notify) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; 128 * i < xfer_len; ++i) {
|
||||||
//memcpy(notify_buffer, uart_rx_data, sizeof(notify_buffer));
|
|
||||||
Custom_STM_App_Update_Char(
|
Custom_STM_App_Update_Char(
|
||||||
CUSTOM_STM_ARRREAD,
|
CUSTOM_STM_ARRREAD,
|
||||||
uart_rx_data + i * 128
|
uart_rx_data + i * 128
|
||||||
@@ -85,19 +84,23 @@ void SendNotifyTask(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
|
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
|
||||||
HAL_GPIO_TogglePin(GPIOA, LED4_Pin);
|
HAL_GPIO_TogglePin(GPIOA, LED5_Pin);
|
||||||
//memcpy(notify_buffer, uart_rx_data, sizeof(notify_buffer));// do second half later
|
|
||||||
UTIL_SEQ_SetTask(1<<CFG_TASK_SEND_NOTIFY, UTIL_SEQ_RFU);
|
UTIL_SEQ_SetTask(1<<CFG_TASK_SEND_NOTIFY, UTIL_SEQ_RFU);
|
||||||
// Process data here or something
|
// Process data here or something
|
||||||
HAL_UART_Receive_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data));
|
if (huart->gState == HAL_UART_STATE_READY) {
|
||||||
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
|
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
|
||||||
|
}
|
||||||
|
xfer_len = Size;
|
||||||
|
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_UART_TXCpltCallback(UART_HandleTypeDef *huart) {}
|
void HAL_UART_TXCpltCallback(UART_HandleTypeDef *huart) {}
|
||||||
|
|
||||||
|
// tim2 is 1kHz, callback is 1Hz
|
||||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
|
||||||
if (htim->Instance == TIM2) {
|
if (htim->Instance == TIM2) {
|
||||||
|
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* USER CODE END 0 */
|
/* USER CODE END 0 */
|
||||||
@@ -155,8 +158,13 @@ int main(void)
|
|||||||
/* USER CODE BEGIN WHILE */
|
/* USER CODE BEGIN WHILE */
|
||||||
HAL_TIM_Base_Start_IT(&htim2);
|
HAL_TIM_Base_Start_IT(&htim2);
|
||||||
UTIL_SEQ_RegTask(1<<CFG_TASK_SEND_NOTIFY, UTIL_SEQ_RFU, SendNotifyTask);
|
UTIL_SEQ_RegTask(1<<CFG_TASK_SEND_NOTIFY, UTIL_SEQ_RFU, SendNotifyTask);
|
||||||
|
HAL_GPIO_WritePin(GPIOA, LED4_Pin, GPIO_PIN_SET);
|
||||||
|
HAL_GPIO_WritePin(GPIOA, LED5_Pin, GPIO_PIN_RESET);
|
||||||
HAL_Delay(1000); // Give the l452 time to start up
|
HAL_Delay(1000); // Give the l452 time to start up
|
||||||
HAL_UART_Receive_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data));
|
HAL_GPIO_WritePin(GPIOA, LED4_Pin, GPIO_PIN_RESET);
|
||||||
|
HAL_GPIO_WritePin(GPIOA, LED5_Pin, GPIO_PIN_SET);
|
||||||
|
__HAL_DMA_DISABLE_IT(huart1.hdmarx, DMA_IT_HT);
|
||||||
|
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data));
|
||||||
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
|
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "gpio.h"
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "custom_stm.h"
|
#include "custom_stm.h"
|
||||||
|
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
|
#include "usart.h"
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
@@ -39,7 +39,7 @@ typedef struct{
|
|||||||
|
|
||||||
extern uint16_t Connection_Handle;
|
extern uint16_t Connection_Handle;
|
||||||
/* USER CODE BEGIN PTD */
|
/* USER CODE BEGIN PTD */
|
||||||
|
uint8_t uart_to_l452_data[1];
|
||||||
/* USER CODE END PTD */
|
/* USER CODE END PTD */
|
||||||
|
|
||||||
/* Private defines -----------------------------------------------------------*/
|
/* Private defines -----------------------------------------------------------*/
|
||||||
@@ -192,7 +192,10 @@ static SVCCTL_EvtAckStatus_t Custom_STM_Event_Handler(void *Event)
|
|||||||
{
|
{
|
||||||
return_value = SVCCTL_EvtAckFlowEnable;
|
return_value = SVCCTL_EvtAckFlowEnable;
|
||||||
/* USER CODE BEGIN CUSTOM_STM_Service_1_Char_1_ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE */
|
/* USER CODE BEGIN CUSTOM_STM_Service_1_Char_1_ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE */
|
||||||
|
if (attribute_modified->Attr_Data[0] != 'R') {
|
||||||
|
uart_to_l452_data[0] = attribute_modified->Attr_Data[0];
|
||||||
|
HAL_UART_Transmit_DMA(&huart1, uart_to_l452_data, 1);
|
||||||
|
}
|
||||||
/* USER CODE END CUSTOM_STM_Service_1_Char_1_ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE */
|
/* USER CODE END CUSTOM_STM_Service_1_Char_1_ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE */
|
||||||
} /* if (attribute_modified->Attr_Handle == (CustomContext.CustomArrwriteHdle + CHARACTERISTIC_VALUE_ATTRIBUTE_OFFSET))*/
|
} /* if (attribute_modified->Attr_Handle == (CustomContext.CustomArrwriteHdle + CHARACTERISTIC_VALUE_ATTRIBUTE_OFFSET))*/
|
||||||
/* USER CODE BEGIN EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_END */
|
/* USER CODE BEGIN EVT_BLUE_GATT_ATTRIBUTE_MODIFIED_END */
|
||||||
|
|||||||
Reference in New Issue
Block a user