Merge branch 'devel' into control-loop-refactor

This commit is contained in:
Samuel Sadok
2020-11-05 13:43:57 +01:00
24 changed files with 365 additions and 150 deletions
+1
View File
@@ -3,6 +3,7 @@ Please add a note of your changes below this heading if you make a Pull Request.
### Added
* [Mechanical brake support](docs/mechanical-brakes.md)
* Added periodic sending of encoder position on CAN
* Support for UART1 on GPIO3 and GPIO4. UART0 (on GPIO1/2) and UART1 can currently not be enabled at the same time.
### Changed
* Modified encoder offset calibration to work correctly when calib_scan_distance is not a multiple of 4pi
+7 -7
View File
@@ -43,8 +43,8 @@
#define DEFAULT_GPIO_MODES \
ODriveIntf::GPIO_MODE_DIGITAL, \
ODriveIntf::GPIO_MODE_UART0, \
ODriveIntf::GPIO_MODE_UART0, \
ODriveIntf::GPIO_MODE_UART_A, \
ODriveIntf::GPIO_MODE_UART_A, \
ODriveIntf::GPIO_MODE_ANALOG_IN, \
ODriveIntf::GPIO_MODE_ANALOG_IN, \
ODriveIntf::GPIO_MODE_ANALOG_IN, \
@@ -57,8 +57,8 @@
ODriveIntf::GPIO_MODE_ENC1, \
ODriveIntf::GPIO_MODE_ENC1, \
ODriveIntf::GPIO_MODE_DIGITAL_PULL_DOWN, \
ODriveIntf::GPIO_MODE_CAN0, \
ODriveIntf::GPIO_MODE_CAN0,
ODriveIntf::GPIO_MODE_CAN_A, \
ODriveIntf::GPIO_MODE_CAN_A,
#define TIM_TIME_BASE TIM14
@@ -97,9 +97,9 @@ extern USBD_HandleTypeDef& usb_dev_handle;
extern Stm32SpiArbiter& ext_spi_arbiter;
extern UART_HandleTypeDef* uart0;
extern UART_HandleTypeDef* uart1;
extern UART_HandleTypeDef* uart2;
extern UART_HandleTypeDef* uart_a;
extern UART_HandleTypeDef* uart_b;
extern UART_HandleTypeDef* uart_c;
extern PwmInput pwm0_input;
#endif
+3
View File
@@ -58,11 +58,14 @@ void DMA1_Stream0_IRQHandler(void);
void DMA1_Stream2_IRQHandler(void);
void DMA1_Stream4_IRQHandler(void);
void DMA1_Stream5_IRQHandler(void);
void DMA1_Stream6_IRQHandler(void);
void DMA1_Stream7_IRQHandler(void);
//void ADC_IRQHandler(void);
void CAN1_TX_IRQHandler(void);
void CAN1_RX0_IRQHandler(void);
void CAN1_RX1_IRQHandler(void);
void CAN1_SCE_IRQHandler(void);
void USART2_IRQHandler(void);
void TIM8_TRG_COM_TIM14_IRQHandler(void);
void TIM5_IRQHandler(void);
void SPI3_IRQHandler(void);
+2
View File
@@ -62,6 +62,7 @@
/* USER CODE END Includes */
extern UART_HandleTypeDef huart4;
extern UART_HandleTypeDef huart2;
/* USER CODE BEGIN Private defines */
@@ -70,6 +71,7 @@ extern UART_HandleTypeDef huart4;
extern void _Error_Handler(char *, int);
void MX_UART4_Init(void);
void MX_USART2_UART_Init(void);
/* USER CODE BEGIN Prototypes */
+7 -1
View File
@@ -82,9 +82,15 @@ void MX_DMA_Init(void)
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
/* DMA1_Stream5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 3, 0); // SPI TX - must have higher priority than SPI RX
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 10, 0); // SPI TX - must have higher priority than SPI RX
// and higher priority than the control loop handler
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* DMA1_Stream6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
/* DMA1_Stream7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn);
/* DMA2_Stream0_IRQn interrupt configuration */
// Dear STM, no we _don't_ want to fire an interrupt for this DMA
// (it's not possible to deselect this in CubeMX)
+1 -1
View File
@@ -110,7 +110,7 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
/* SPI3 DMA Init */
/* SPI3_TX Init */
hdma_spi3_tx.Instance = DMA1_Stream5;
hdma_spi3_tx.Instance = DMA1_Stream7;
hdma_spi3_tx.Init.Channel = DMA_CHANNEL_0;
hdma_spi3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
+46 -1
View File
@@ -54,7 +54,10 @@ extern TIM_HandleTypeDef htim5;
extern TIM_HandleTypeDef htim8;
extern DMA_HandleTypeDef hdma_uart4_rx;
extern DMA_HandleTypeDef hdma_uart4_tx;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern DMA_HandleTypeDef hdma_usart2_tx;
extern UART_HandleTypeDef huart4;
extern UART_HandleTypeDef huart2;
extern TIM_HandleTypeDef htim14;
@@ -251,12 +254,40 @@ void DMA1_Stream5_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream5_IRQn 0 */
COUNT_IRQ(DMA1_Stream5_IRQn);
/* USER CODE END DMA1_Stream5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi3_tx);
HAL_DMA_IRQHandler(&hdma_usart2_rx);
/* USER CODE BEGIN DMA1_Stream5_IRQn 1 */
/* USER CODE END DMA1_Stream5_IRQn 1 */
}
/**
* @brief This function handles DMA1 stream6 global interrupt.
*/
void DMA1_Stream6_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream6_IRQn 0 */
COUNT_IRQ(DMA1_Stream6_IRQn);
/* USER CODE END DMA1_Stream6_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_tx);
/* USER CODE BEGIN DMA1_Stream6_IRQn 1 */
/* USER CODE END DMA1_Stream6_IRQn 1 */
}
/**
* @brief This function handles DMA1 stream7 global interrupt.
*/
void DMA1_Stream7_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream7_IRQn 0 */
COUNT_IRQ(DMA1_Stream7_IRQn);
/* USER CODE END DMA1_Stream7_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi3_tx);
/* USER CODE BEGIN DMA1_Stream7_IRQn 1 */
/* USER CODE END DMA1_Stream7_IRQn 1 */
}
/**
* @brief This function handles CAN1 TX interrupts.
*/
@@ -313,6 +344,20 @@ void CAN1_SCE_IRQHandler(void)
/* USER CODE END CAN1_SCE_IRQn 1 */
}
/**
* @brief This function handles USART2 global interrupt.
*/
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
/**
* @brief This function handles TIM8 trigger and commutation interrupts and TIM14 global interrupt.
*/
+93 -7
View File
@@ -58,15 +58,18 @@
/* USER CODE END 0 */
UART_HandleTypeDef huart4;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_uart4_rx;
DMA_HandleTypeDef hdma_uart4_tx;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;
/* UART4 init function */
void MX_UART4_Init(void)
{
huart4.Instance = UART4;
huart4.Init.BaudRate = 115200; // Provisionally this can be changed to 921600 for faster transfers, the low power Arduinos will not keep up.
//huart4.Init.BaudRate = 115200; // Provisionally this can be changed to 921600 for faster transfers, the low power Arduinos will not keep up.
huart4.Init.WordLength = UART_WORDLENGTH_8B;
huart4.Init.StopBits = UART_STOPBITS_1;
huart4.Init.Parity = UART_PARITY_NONE;
@@ -78,6 +81,25 @@ void MX_UART4_Init(void)
_Error_Handler(__FILE__, __LINE__);
}
}
/* USART2 init function */
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
//huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
@@ -135,6 +157,58 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
/* USER CODE END UART4_MspInit 1 */
}
else if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
/* USART2 DMA Init */
/* USART2_RX Init */
hdma_usart2_rx.Instance = DMA1_Stream5;
hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4;
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_CIRCULAR;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);
/* USART2_TX Init */
hdma_usart2_tx.Instance = DMA1_Stream6;
hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
@@ -147,12 +221,6 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
/* USER CODE END UART4_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_UART4_CLK_DISABLE();
/**UART4 GPIO Configuration
PA0-WKUP ------> UART4_TX
PA1 ------> UART4_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_1_Pin|GPIO_2_Pin);
/* UART4 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
@@ -164,6 +232,24 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
/* USER CODE END UART4_MspDeInit 1 */
}
else if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspDeInit 0 */
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/* UART4 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* USART2 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspDeInit 1 */
/* USER CODE END USART2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
+23 -18
View File
@@ -26,9 +26,9 @@ extern "C" void SystemClock_Config(void); // defined in main.c generated by Cube
Stm32SpiArbiter spi3_arbiter{&hspi3};
Stm32SpiArbiter& ext_spi_arbiter = spi3_arbiter;
UART_HandleTypeDef* uart0 = &huart4;
UART_HandleTypeDef* uart1 = nullptr; // TODO: this could be supported in ODrive v3.6 (or similar) using STM32's USART2
UART_HandleTypeDef* uart2 = nullptr;
UART_HandleTypeDef* uart_a = &huart4;
UART_HandleTypeDef* uart_b = &huart2; // TODO: this could be supported in ODrive v3.6 (or similar) using STM32's USART2
UART_HandleTypeDef* uart_c = nullptr;
Drv8301 m0_gate_driver{
&spi3_arbiter,
@@ -224,16 +224,16 @@ std::array<GpioFunction, 3> alternate_functions[GPIO_COUNT] = {
/* GPIO0 (inexistent): */ {{}},
#if HW_VERSION_MINOR >= 3
/* GPIO1: */ {{{ODrive::GPIO_MODE_UART0, GPIO_AF8_UART4}, {ODrive::GPIO_MODE_PWM0, GPIO_AF2_TIM5}}},
/* GPIO2: */ {{{ODrive::GPIO_MODE_UART0, GPIO_AF8_UART4}, {ODrive::GPIO_MODE_PWM0, GPIO_AF2_TIM5}}},
/* GPIO3: */ {{{ODrive::GPIO_MODE_PWM0, GPIO_AF2_TIM5}}},
/* GPIO1: */ {{{ODrive::GPIO_MODE_UART_A, GPIO_AF8_UART4}, {ODrive::GPIO_MODE_PWM, GPIO_AF2_TIM5}}},
/* GPIO2: */ {{{ODrive::GPIO_MODE_UART_A, GPIO_AF8_UART4}, {ODrive::GPIO_MODE_PWM, GPIO_AF2_TIM5}}},
/* GPIO3: */ {{{ODrive::GPIO_MODE_UART_B, GPIO_AF7_USART2}, {ODrive::GPIO_MODE_PWM, GPIO_AF2_TIM5}}},
#else
/* GPIO1: */ {{}},
/* GPIO2: */ {{}},
/* GPIO3: */ {{}},
#endif
/* GPIO4: */ {{{ODrive::GPIO_MODE_PWM0, GPIO_AF2_TIM5}}},
/* GPIO4: */ {{{ODrive::GPIO_MODE_UART_B, GPIO_AF7_USART2}, {ODrive::GPIO_MODE_PWM, GPIO_AF2_TIM5}}},
/* GPIO5: */ {{}},
/* GPIO6: */ {{}},
/* GPIO7: */ {{}},
@@ -241,11 +241,11 @@ std::array<GpioFunction, 3> alternate_functions[GPIO_COUNT] = {
/* ENC0_A: */ {{{ODrive::GPIO_MODE_ENC0, GPIO_AF2_TIM3}}},
/* ENC0_B: */ {{{ODrive::GPIO_MODE_ENC0, GPIO_AF2_TIM3}}},
/* ENC0_Z: */ {{}},
/* ENC1_A: */ {{{ODrive::GPIO_MODE_I2C0, GPIO_AF4_I2C1}, {ODrive::GPIO_MODE_ENC1, GPIO_AF2_TIM4}}},
/* ENC1_B: */ {{{ODrive::GPIO_MODE_I2C0, GPIO_AF4_I2C1}, {ODrive::GPIO_MODE_ENC1, GPIO_AF2_TIM4}}},
/* ENC1_A: */ {{{ODrive::GPIO_MODE_I2C_A, GPIO_AF4_I2C1}, {ODrive::GPIO_MODE_ENC1, GPIO_AF2_TIM4}}},
/* ENC1_B: */ {{{ODrive::GPIO_MODE_I2C_A, GPIO_AF4_I2C1}, {ODrive::GPIO_MODE_ENC1, GPIO_AF2_TIM4}}},
/* ENC1_Z: */ {{}},
/* CAN_R: */ {{{ODrive::GPIO_MODE_CAN0, GPIO_AF9_CAN1}, {ODrive::GPIO_MODE_I2C0, GPIO_AF4_I2C1}}},
/* CAN_D: */ {{{ODrive::GPIO_MODE_CAN0, GPIO_AF9_CAN1}, {ODrive::GPIO_MODE_I2C0, GPIO_AF4_I2C1}}},
/* CAN_R: */ {{{ODrive::GPIO_MODE_CAN_A, GPIO_AF9_CAN1}, {ODrive::GPIO_MODE_I2C_A, GPIO_AF4_I2C1}}},
/* CAN_D: */ {{{ODrive::GPIO_MODE_CAN_A, GPIO_AF9_CAN1}, {ODrive::GPIO_MODE_I2C_A, GPIO_AF4_I2C1}}},
};
#if HW_VERSION_MINOR <= 2
@@ -278,7 +278,6 @@ bool board_init() {
MX_SPI3_Init();
MX_ADC3_Init();
MX_TIM2_Init();
MX_UART4_Init();
MX_TIM5_Init();
MX_TIM13_Init();
@@ -304,11 +303,17 @@ bool board_init() {
HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
HAL_UART_DeInit(uart0);
uart0->Init.BaudRate = odrv.config_.uart0_baudrate;
HAL_UART_Init(uart0);
if (odrv.config_.enable_uart_a) {
uart_a->Init.BaudRate = odrv.config_.uart_a_baudrate;
MX_UART4_Init();
}
if (odrv.config_.enable_i2c0) {
if (odrv.config_.enable_uart_b) {
uart_b->Init.BaudRate = odrv.config_.uart_b_baudrate;
MX_USART2_UART_Init();
}
if (odrv.config_.enable_i2c_a) {
// Set up the direction GPIO as input
get_gpio(3).config(GPIO_MODE_INPUT, GPIO_PULLUP);
get_gpio(4).config(GPIO_MODE_INPUT, GPIO_PULLUP);
@@ -322,11 +327,11 @@ bool board_init() {
MX_I2C1_Init(i2c_stats_.addr);
}
if (odrv.config_.enable_can0) {
if (odrv.config_.enable_can_a) {
// The CAN initialization will (and must) init its own GPIOs before the
// GPIO modes are initialized. Therefore we ensure that the later GPIO
// mode initialization won't override the CAN mode.
if (odrv.config_.gpio_modes[15] != ODriveIntf::GPIO_MODE_CAN0 || odrv.config_.gpio_modes[16] != ODriveIntf::GPIO_MODE_CAN0) {
if (odrv.config_.gpio_modes[15] != ODriveIntf::GPIO_MODE_CAN_A || odrv.config_.gpio_modes[16] != ODriveIntf::GPIO_MODE_CAN_A) {
odrv.misconfigured_ = true;
} else {
MX_CAN1_Init();
+15 -15
View File
@@ -551,9 +551,9 @@ extern "C" int main(void) {
}
odrv.misconfigured_ = odrv.misconfigured_
|| (odrv.config_.enable_uart0 && !uart0)
|| (odrv.config_.enable_uart1 && !uart1)
|| (odrv.config_.enable_uart2 && !uart2);
|| (odrv.config_.enable_uart_a && !uart_a)
|| (odrv.config_.enable_uart_b && !uart_b)
|| (odrv.config_.enable_uart_c && !uart_c);
// Init board-specific peripherals
if (!board_init()) {
@@ -611,49 +611,49 @@ extern "C" int main(void) {
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
} break;
case ODriveIntf::GPIO_MODE_UART0: {
case ODriveIntf::GPIO_MODE_UART_A: {
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = (i == 0) ? GPIO_PULLDOWN : GPIO_PULLUP; // this is probably swapped but imitates old behavior
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
if (!odrv.config_.enable_uart0) {
if (!odrv.config_.enable_uart_a) {
odrv.misconfigured_ = true;
}
} break;
case ODriveIntf::GPIO_MODE_UART1: {
case ODriveIntf::GPIO_MODE_UART_B: {
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = (i == 0) ? GPIO_PULLDOWN : GPIO_PULLUP; // this is probably swapped but imitates old behavior
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
if (!odrv.config_.enable_uart1) {
if (!odrv.config_.enable_uart_b) {
odrv.misconfigured_ = true;
}
} break;
case ODriveIntf::GPIO_MODE_UART2: {
case ODriveIntf::GPIO_MODE_UART_C: {
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = (i == 0) ? GPIO_PULLDOWN : GPIO_PULLUP; // this is probably swapped but imitates old behavior
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
if (!odrv.config_.enable_uart2) {
if (!odrv.config_.enable_uart_c) {
odrv.misconfigured_ = true;
}
} break;
case ODriveIntf::GPIO_MODE_CAN0: {
case ODriveIntf::GPIO_MODE_CAN_A: {
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
if (!odrv.config_.enable_can0) {
if (!odrv.config_.enable_can_a) {
odrv.misconfigured_ = true;
}
} break;
case ODriveIntf::GPIO_MODE_I2C0: {
case ODriveIntf::GPIO_MODE_I2C_A: {
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
if (!odrv.config_.enable_i2c0) {
if (!odrv.config_.enable_i2c_a) {
odrv.misconfigured_ = true;
}
} break;
//case ODriveIntf::GPIO_MODE_SPI0: { // TODO
//case ODriveIntf::GPIO_MODE_SPI_A: { // TODO
//} break;
case ODriveIntf::GPIO_MODE_PWM0: {
case ODriveIntf::GPIO_MODE_PWM: {
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+8 -8
View File
@@ -63,14 +63,14 @@ struct BoardConfig_t {
DEFAULT_GPIO_MODES
};
bool enable_uart0 = true;
bool enable_uart1 = false;
bool enable_uart2 = false;
uint32_t uart0_baudrate = 115200;
uint32_t uart1_baudrate = 115200;
uint32_t uart2_baudrate = 115200;
bool enable_can0 = true;
bool enable_i2c0 = false;
bool enable_uart_a = true;
bool enable_uart_b = false;
bool enable_uart_c = false;
uint32_t uart_a_baudrate = 115200;
uint32_t uart_b_baudrate = 115200;
uint32_t uart_c_baudrate = 115200;
bool enable_can_a = true;
bool enable_i2c_a = false;
bool enable_ascii_protocol_on_usb = true;
float max_regen_current = 0.0f;
float brake_resistance = DEFAULT_BRAKE_RESISTANCE;
+11 -4
View File
@@ -38,17 +38,24 @@ char serial_number_str[13]; // 12 digits + null termination
void init_communication(void) {
printf("hi!\r\n");
if (odrv.config_.enable_uart0 && uart0) {
start_uart_server();
// Dual UART operation not supported yet
if (odrv.config_.enable_uart_a && odrv.config_.enable_uart_b) {
odrv.misconfigured_ = true;
}
if (odrv.config_.enable_uart_a && uart_a) {
start_uart_server(uart_a);
} else if (odrv.config_.enable_uart_b && uart_b) {
start_uart_server(uart_b);
}
start_usb_server();
if (odrv.config_.enable_i2c0) {
if (odrv.config_.enable_i2c_a) {
start_i2c_server();
}
if (odrv.config_.enable_can0) {
if (odrv.config_.enable_can_a) {
odCAN->start_can_server();
}
}
+4 -3
View File
@@ -19,8 +19,7 @@ static uint8_t dma_rx_buffer[UART_RX_BUFFER_SIZE];
static uint32_t dma_last_rcv_idx;
osThreadId uart_thread = 0;
extern UART_HandleTypeDef* uart0;
static UART_HandleTypeDef* huart_ = uart0; // defined in board.cpp.
static UART_HandleTypeDef* huart_ = nullptr;
const uint32_t stack_size_uart_thread = 4096; // Bytes
@@ -97,7 +96,9 @@ static void uart_server_thread(void * ctx) {
}
// TODO: allow multiple UART server instances
void start_uart_server() {
void start_uart_server(UART_HandleTypeDef* huart) {
huart_ = huart;
// DMA is set up to receive in a circular buffer forever.
// We dont use interrupts to fetch the data, instead we periodically read
// data out of the circular buffer into a parse buffer, controlled by a state machine
+2 -1
View File
@@ -9,11 +9,12 @@ extern "C" {
#endif
#include <cmsis_os.h>
#include "usart.h"
extern osThreadId uart_thread;
extern const uint32_t stack_size_uart_thread;
void start_uart_server(void);
void start_uart_server(UART_HandleTypeDef* huart);
void uart_poll(void);
#ifdef __cplusplus
@@ -93,6 +93,8 @@ properties:
additionalProperties: false
"""))
# TODO: detect duplicate keys in yaml dictionaries
# Source: https://stackoverflow.com/a/53647080/3621512
class SafeLineLoader(yaml.SafeLoader):
pass
+42 -27
View File
@@ -176,15 +176,26 @@ interfaces:
gpio15_mode: {type: GpioMode, doc: Mode of GPIO15 (changes take effect after reboot), c_name: 'gpio_modes[15]'}
gpio16_mode: {type: GpioMode, doc: Mode of GPIO16 (changes take effect after reboot), c_name: 'gpio_modes[16]'}
enable_uart0:
enable_uart_a:
type: bool
doc: Enables/disables UART0. You also need to set the corresponding GPIOs to GPIO_MODE_UART0. Changing this requires a reboot.
enable_uart1: {type: bool, doc: Not supported on ODrive v3.x.}
enable_uart2: {type: bool, doc: Not supported on ODrive v3.x.}
uart0_baudrate:
type: uint32
brief: Enables/disables UART_A.
doc: |
You also need to set the corresponding GPIOs to GPIO_MODE_UART_A.
Refer to [interfaces](interfaces.md) to see which pins support UART_A.
Changing this requires a reboot.
enable_uart_b:
type: bool
brief: Enables/disables UART_B.
doc: |
You also need to set the corresponding GPIOs to GPIO_MODE_UART_B.
Refer to [interfaces](interfaces.md) to see which pins support UART_B.
Changing this requires a reboot.
enable_uart_c: {type: bool, doc: Not supported on ODrive v3.x.}
uart_a_baudrate:
type: uint32
unit: baud/s
brief: Defines the baudrate used on the UART interface.
doc: |
Defines the baudrate used on the UART interface.
Some baudrates will have a small timing error due to hardware limitations.
Here's an (incomplete) list of baudrates for ODrive v3.x:
@@ -206,17 +217,21 @@ interfaces:
For more information refer to Section 30.3.4 and Table 142 (the column with f_PCLK = 42 MHz) in the
[STM datasheet](https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf).
uart1_baudrate: {type: uint32, doc: Not supported on ODrive v3.x.}
uart2_baudrate: {type: uint32, doc: Not supported on ODrive v3.x.}
enable_can0:
uart_b_baudrate:
type: uint32
unit: baud/s
brief: Defines the baudrate used on the UART interface.
doc: See `uart_a_baudrate` for details.
uart_c_baudrate: {type: uint32, doc: Not supported on ODrive v3.x.}
enable_can_a:
type: bool
doc: |
Enables CAN. Changing this setting requires a reboot.
enable_i2c0:
enable_i2c_a:
type: bool
doc: |
Enables I2C. The I2C pins on ODrive v3.x are in conflict with CAN.
This setting has no effect if `enable_can0` is also true.
This setting has no effect if `enable_can_a` is also true.
This setting has no effect on ODrive v3.2 or earlier.
Changing this setting requires a reboot.
enable_ascii_protocol_on_usb: bool
@@ -280,10 +295,10 @@ interfaces:
brief: Max current the power supply can sink.
doc: You most likely want a non-positive value here. Set to -INFINITY to disable.
gpio1_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[0]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM0`.}
gpio2_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[1]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM0`.}
gpio3_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[2]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM0`.}
gpio4_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[3]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM0`.}
gpio1_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[0]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM`.}
gpio2_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[1]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM`.}
gpio3_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[2]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM`.}
gpio4_pwm_mapping: {type: Endpoint, c_name: 'pwm_mappings[3]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_PWM`.}
gpio3_analog_mapping: {type: Endpoint, c_name: 'analog_mappings[3]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_ANALOG_IN`.}
gpio4_analog_mapping: {type: Endpoint, c_name: 'analog_mappings[4]', doc: Make sure the corresponding GPIO is in `GPIO_MODE_ANALOG_IN`.}
user_config_loaded: readonly uint32
@@ -299,10 +314,10 @@ interfaces:
Possible causes:
- A GPIO was set to a mode that it doesn't support
- A GPIO was set to a mode for which the corresponding feature was
not enabled. Example: `GPIO_MODE_UART0` was used without enabling
`config.enable_uart0`.
not enabled. Example: `GPIO_MODE_UART_A` was used without enabling
`config.enable_uart_a`.
- A feature was enabled which is not supported on this hardware.
Example: `config.enable_uart2` set to true on ODrive v3.x.
Example: `config.enable_uart_c` set to true on ODrive v3.x.
- A GPIO was used as an interrupt input for two internal components
or two GPIOs that are mutually exclusive in their interrupt
capability were both used as interrupt input.
@@ -1078,15 +1093,15 @@ valuetypes:
doc: |
The pin can be used for one or more of these functions:
Sin/cos encoders, analog input, `get_adc_voltage`.
Uart0: {doc: See `config.enable_uart0`.}
Uart1: {doc: This mode is not supported on ODrive v3.x.}
Uart2: {doc: This mode is not supported on ODrive v3.x.}
Can0: {doc: See `config.enable_can0`.}
I2c0: {doc: See `config.enable_i2c0`.}
Spi0: {doc: Note that the SPI pins on ODrive v3.x are hardwired so they
cannot be configured through software. Consequently, even though SPI0
UartA: {doc: See `config.enable_uart_a`.}
UartB: {doc: This mode is not supported on ODrive v3.x.}
UartC: {doc: This mode is not supported on ODrive v3.x.}
CanA: {doc: See `config.enable_can_a`.}
I2cA: {doc: See `config.enable_i2c_a`.}
SpiA: {doc: Note that the SPI pins on ODrive v3.x are hardwired so they
cannot be configured through software. Consequently, even though SPI_A
is exposed, this mode is of no use on ODrive v3.x.}
Pwm0: {doc: See `config.gpio0_pwm_mapping`.}
Pwm: {doc: See `config.gpio0_pwm_mapping`.}
Enc0: {doc: The pin is used by quadrature encoder 0.}
Enc1: {doc: The pin is used by quadrature encoder 1.}
Enc2: {doc: This mode is not supported on ODrive v3.x.}
+21 -20
View File
@@ -1,24 +1,24 @@
# Pinout
| # | Label | `GPIO_MODE_DIGITAL` | `GPIO_MODE_ANALOG_IN` | `GPIO_MODE_UART0` | `GPIO_MODE_PWM0` | `GPIO_MODE_CAN0` | `GPIO_MODE_I2C0` | `GPIO_MODE_ENC0` | `GPIO_MODE_ENC1` | `GPIO_MODE_MECH_BRAKE` |
|----|---------------|------------------------|-----------------------|-------------------|------------------|------------------|------------------|------------------|------------------|------------------------|
| 0 | _not a pin_ | | | | | | | | | |
| 1 | GPIO1 (+) | general purpose | analog input | **UART0.TX** | PWM0.0 | | | | | mechanical brake |
| 2 | GPIO2 (+) | general purpose | analog input | **UART0.RX** | PWM0.1 | | | | | mechanical brake |
| 3 | GPIO3 | general purpose | **analog input** | | PWM0.2 | | | | | mechanical brake |
| 4 | GPIO4 | general purpose | **analog input** | | PWM0.3 | | | | | mechanical brake |
| 5 | GPIO5 | general purpose | **analog input** (*) | | | | | | | mechanical brake |
| 6 | GPIO6 (*) (+) | **general purpose** | | | | | | | | mechanical brake |
| 7 | GPIO7 (*) (+) | **general purpose** | | | | | | | | mechanical brake |
| 8 | GPIO8 (*) (+) | **general purpose** | | | | | | | | mechanical brake |
| 9 | M0.A | general purpose | | | | | | **ENC0.A** | | |
| 10 | M0.B | general purpose | | | | | | **ENC0.B** | | |
| 11 | M0.Z | **general purpose** | | | | | | | | |
| 12 | M1.A | general purpose | | | | | I2C.SCL | | **ENC1.A** | |
| 13 | M1.B | general purpose | | | | | I2C.SDA | | **ENC1.B** | |
| 14 | M1.Z | **general purpose** | | | | | | | | |
| 15 | _not exposed_ | general purpose | | | | **CAN0.RX** | I2C.SCL | | | |
| 16 | _not exposed_ | general purpose | | | | **CAN0.TX** | I2C.SDA | | | |
| # | Label | `GPIO_MODE_DIGITAL` | `GPIO_MODE_ANALOG_IN` | `GPIO_MODE_UART_A` | `GPIO_MODE_UART_B` | `GPIO_MODE_PWM` | `GPIO_MODE_CAN_A` | `GPIO_MODE_I2C_A` | `GPIO_MODE_ENC0` | `GPIO_MODE_ENC1` | `GPIO_MODE_MECH_BRAKE` |
|----|---------------|------------------------|-----------------------|--------------------|--------------------|-----------------|------------------|-------------------|------------------|------------------|------------------------|
| 0 | _not a pin_ | | | | | | | | | | |
| 1 | GPIO1 (+) | general purpose | analog input | **UART_A.TX** | | PWM0.0 | | | | | mechanical brake |
| 2 | GPIO2 (+) | general purpose | analog input | **UART_A.RX** | | PWM0.1 | | | | | mechanical brake |
| 3 | GPIO3 | general purpose | **analog input** | | **UART_B.TX** | PWM0.2 | | | | | mechanical brake |
| 4 | GPIO4 | general purpose | **analog input** | | **UART_B.RX** | PWM0.3 | | | | | mechanical brake |
| 5 | GPIO5 | general purpose | **analog input** (*) | | | | | | | | mechanical brake |
| 6 | GPIO6 (*) (+) | **general purpose** | | | | | | | | | mechanical brake |
| 7 | GPIO7 (*) (+) | **general purpose** | | | | | | | | | mechanical brake |
| 8 | GPIO8 (*) (+) | **general purpose** | | | | | | | | | mechanical brake |
| 9 | M0.A | general purpose | | | | | | | **ENC0.A** | | |
| 10 | M0.B | general purpose | | | | | | | **ENC0.B** | | |
| 11 | M0.Z | **general purpose** | | | | | | | | | |
| 12 | M1.A | general purpose | | | | | | I2C.SCL | | **ENC1.A** | |
| 13 | M1.B | general purpose | | | | | | I2C.SDA | | **ENC1.B** | |
| 14 | M1.Z | **general purpose** | | | | | | | | | |
| 15 | _not exposed_ | general purpose | | | | | **CAN_A.RX** | I2C.SCL | | | |
| 16 | _not exposed_ | general purpose | | | | | **CAN_A.TX** | I2C.SDA | | | |
(*) ODrive v3.5 and later <br>
@@ -28,7 +28,8 @@ Notes:
* Changes to the pin configuration only take effect after `odrv0.save_configuration()` and `odrv0.reboot()`
* Bold font marks the default configuration.
* If a GPIO is set to an unsupported mode it will be left uninitialized.
* When setting a GPIO to a special purpose mode (e.g. `GPIO_MODE_UART0`) you must also enable the corresponding feature (e.g. `<odrv>.config.enable_uart`).
* When setting a GPIO to a special purpose mode (e.g. `GPIO_MODE_UART_A`) you must also enable the corresponding feature (e.g. `<odrv>.config.enable_uart_a`).
* Digital mode is a general purpose mode that can be used for these functions: step, dir, enable, encoder index, hall effect encoder, SPI encoder nCS.
* You must also connect GND between ODrive and your other board.
* ODrive v3.3 and onward have 5V tolerant GPIO pins.
* Simultaneous operation of UART_A and UART_B is currently not supported.
+1 -1
View File
@@ -7,7 +7,7 @@ Any of the numerical parameters that are writable from the ODrive Tool can be ho
2. If you want to control your ODrive with the PWM input without using anything else to activate the ODrive, you can configure the ODrive such that axis 0 automatically goes operational at startup. See [here](commands.md#startup-procedure) for more information.
3. In ODrive Tool, configure the PWM input mapping
```
odrv0.config.gpio4_mode = GPIO_MODE_PWM0
odrv0.config.gpio4_mode = GPIO_MODE_PWM
odrv0.config.gpio4_pwm_mapping.min = -2
odrv0.config.gpio4_pwm_mapping.max = 2
odrv0.config.gpio4_pwm_mapping.endpoint = odrv0.axis0.controller._remote_attributes['input_pos']
+9 -5
View File
@@ -27,7 +27,8 @@ Take this info with a grain of salt as we might forget to update it from time to
| 11 | DMA1_Stream0_IRQn | 4 |
| 13 | DMA1_Stream2_IRQn | 10 |
| 15 | DMA1_Stream4_IRQn | 10 |
| 16 | DMA1_Stream5_IRQn | 3 |
| 16 | DMA1_Stream5_IRQn | 10 |
| 17 | DMA1_Stream6_IRQn | 10 |
| 19 | CAN1_TX_IRQn | 9 |
| 20 | CAN1_RX0_IRQn | 9 |
| 21 | CAN1_RX1_IRQn | 9 |
@@ -36,6 +37,7 @@ Take this info with a grain of salt as we might forget to update it from time to
| 40 | EXTI15_10_IRQn | 1 |
| 44 | TIM8_UP_TIM13_IRQn | 0 |
| 45 | TIM8_TRG_COM_TIM14_IRQn | 6 |
| 47 | DMA1_Stream7_IRQn | 3 |
| 50 | TIM5_IRQn | 1 |
| 52 | UART4_IRQn | 10 |
| 67 | OTG_FS_IRQn | 6 |
@@ -49,10 +51,12 @@ Take this info with a grain of salt as we might forget to update it from time to
| Name | Prio | Channel | High Level Func |
|--------------|------|----------------------------------|-----------------|
| DMA1_Stream0 | 1 | 0 (SPI3_RX) | SPI |
| DMA1_Stream2 | 0 | 4 (UART4_RX) | UART0 |
| DMA1_Stream4 | 0 | 4 (UART4_TX) | UART0 |
| DMA1_Stream5 | 2 | 0 (SPI3_TX) | SPI |
| DMA1_Stream0 | 1 | 0 (SPI3_RX) | SPI_A |
| DMA1_Stream2 | 0 | 4 (UART4_RX) | UART_A |
| DMA1_Stream4 | 0 | 4 (UART4_TX) | UART_A |
| DMA1_Stream5 | 0 | 4 (USART2_RX) | UART_B |
| DMA1_Stream6 | 0 | 4 (USART2_TX) | UART_B |
| DMA1_Stream7 | 2 | 0 (SPI3_TX) | SPI_A |
| DMA2_Stream0 | 0 | 0 (ADC1) | freerunning ADC |
+14 -2
View File
@@ -1,6 +1,6 @@
# UART Interface
The ODrive's UART0 interface is enabled by default with a baudrate of 115200 on the pins as shown in [Pinout](pinout).
The ODrive's UART_A interface is enabled by default with a baudrate of 115200 on the pins as shown in [Pinout](pinout).
To use UART connect it like this:
@@ -10,4 +10,16 @@ To use UART connect it like this:
The logic level of the ODrive is 3.3V. The GPIOs are 5V tolerant.
You can use `odrv0.config.uart0_baudrate` to change the baudrate and `odrv0.config.enable_uart0` to disable/reenable UART0. Currently the UART port runs both the [Native Protocol](native-protocol) and the [ASCII Protocol](ascii-protocol) at the same time.
You can use `odrv0.config.uart_a_baudrate` to change the baudrate and `odrv0.config.enable_uart_a` to disable/reenable UART_A. Currently the UART port runs both the [Native Protocol](native-protocol) and the [ASCII Protocol](ascii-protocol) at the same time.
### How to use UART on GPIO3/4
If you need GPIO1/2 for some function other than UART you can disable UART_A and instead use UART_B on GPIO3/4. Here's how you do it:
odrv0.config.enable_uart_a = False
odrv0.config.gpio1_mode = GPIO_MODE_DIGITAL
odrv0.config.gpio2_mode = GPIO_MODE_DIGITAL
odrv0.config.enable_uart_b = True
odrv0.config.gpio3_mode = GPIO_MODE_UART_B
odrv0.config.gpio4_mode = GPIO_MODE_UART_B
odrv0.reboot()
+7 -7
View File
@@ -8,13 +8,13 @@ GPIO_MODE_DIGITAL = 0
GPIO_MODE_DIGITAL_PULL_UP = 1
GPIO_MODE_DIGITAL_PULL_DOWN = 2
GPIO_MODE_ANALOG_IN = 3
GPIO_MODE_UART0 = 4
GPIO_MODE_UART1 = 5
GPIO_MODE_UART2 = 6
GPIO_MODE_CAN0 = 7
GPIO_MODE_I2C0 = 8
GPIO_MODE_SPI0 = 9
GPIO_MODE_PWM0 = 10
GPIO_MODE_UART_A = 4
GPIO_MODE_UART_B = 5
GPIO_MODE_UART_C = 6
GPIO_MODE_CAN_A = 7
GPIO_MODE_I2C_A = 8
GPIO_MODE_SPI_A = 9
GPIO_MODE_PWM = 10
GPIO_MODE_ENC0 = 11
GPIO_MODE_ENC1 = 12
GPIO_MODE_ENC2 = 13
+3 -3
View File
@@ -109,9 +109,9 @@ class TestSimpleCAN():
def run_test(self, odrive: ODriveComponent, canbus: CanInterfaceComponent, node_id: int, extended_id: bool, logger: Logger):
odrive.disable_mappings()
odrive.handle.config.gpio15_mode = GPIO_MODE_CAN0
odrive.handle.config.gpio16_mode = GPIO_MODE_CAN0
odrive.handle.config.enable_can0 = True
odrive.handle.config.gpio15_mode = GPIO_MODE_CAN_A
odrive.handle.config.gpio16_mode = GPIO_MODE_CAN_A
odrive.handle.config.enable_can_a = True
odrive.save_config_and_reboot()
axis = odrive.handle.axis0
+1 -1
View File
@@ -70,7 +70,7 @@ class TestPwmInput():
odrive.handle.config.gpio4_pwm_mapping
][odrive_gpio_num - 1]
setattr(odrive.handle.config, 'gpio' + str(odrive_gpio_num) + '_mode', GPIO_MODE_PWM0)
setattr(odrive.handle.config, 'gpio' + str(odrive_gpio_num) + '_mode', GPIO_MODE_PWM)
pwm_mapping.endpoint = odrive.handle.axis0.controller._remote_attributes['input_pos']
pwm_mapping.min = min_val
pwm_mapping.max = max_val
+42 -18
View File
@@ -41,16 +41,40 @@ class TestUartAscii():
'rx': (odrive.gpio1, True),
'tx': (odrive.gpio2, False)
}, SerialPortComponent))
yield (odrive, ports)
yield (odrive, 0, ports)
def run_test(self, odrive: ODriveComponent, port: SerialPortComponent, logger: Logger):
logger.debug('Enabling UART...')
# Enable the line below to manually test UART_B. For this you need
# to manually move to the wires go to GPIO1/2 to GPIO3/4. The ones
# that normally go to GPIO3/4 have a low pass filter.
#yield (odrive, 1, ports)
def run_test(self, odrive: ODriveComponent, uart_num: int, port: SerialPortComponent, logger: Logger):
logger.debug('Enabling UART {}...'.format(uart_num))
# GPIOs might be in use by something other than UART and some components
# might be configured so that they would fail in the later test.
odrive.erase_config_and_reboot()
odrive.handle.config.enable_uart0 = True
odrive.handle.config.gpio1_mode = GPIO_MODE_UART0
odrive.handle.config.gpio2_mode = GPIO_MODE_UART0
odrive.disable_mappings()
odrive.handle.config.enable_uart_a = False
odrive.handle.config.uart_a_baudrate = 115200
odrive.handle.config.enable_uart_b = False
odrive.handle.config.uart_b_baudrate = 115200
odrive.handle.config.enable_uart_c = False
odrive.handle.config.uart_c_baudrate = 115200
if uart_num == 0:
odrive.handle.config.enable_uart_a = True
odrive.handle.config.gpio1_mode = GPIO_MODE_UART_A
odrive.handle.config.gpio2_mode = GPIO_MODE_UART_A
odrive.handle.config.gpio3_mode = GPIO_MODE_ANALOG_IN
odrive.handle.config.gpio4_mode = GPIO_MODE_ANALOG_IN
else:
odrive.handle.config.enable_uart_b = True
odrive.handle.config.gpio1_mode = GPIO_MODE_ANALOG_IN
odrive.handle.config.gpio2_mode = GPIO_MODE_ANALOG_IN
odrive.handle.config.gpio3_mode = GPIO_MODE_UART_B
odrive.handle.config.gpio4_mode = GPIO_MODE_UART_B
odrive.save_config_and_reboot()
with port.open(115200) as ser:
# reset port to known state
@@ -163,11 +187,11 @@ class TestUartBaudrate():
yield (odrive, ports)
def run_test(self, odrive: ODriveComponent, port: SerialPortComponent, logger: Logger):
odrive.handle.config.enable_uart0 = True
odrive.handle.config.gpio1_mode = GPIO_MODE_UART0
odrive.handle.config.gpio2_mode = GPIO_MODE_UART0
odrive.handle.config.enable_uart_a = True
odrive.handle.config.gpio1_mode = GPIO_MODE_UART_A
odrive.handle.config.gpio2_mode = GPIO_MODE_UART_A
odrive.handle.config.uart0_baudrate = 9600
odrive.handle.config.uart_a_baudrate = 9600
odrive.save_config_and_reboot()
# Control test: talk to the ODrive with the wrong baudrate
@@ -187,7 +211,7 @@ class TestUartBaudrate():
response = float(ser.readline().strip())
test_assert_eq(response, odrive.handle.vbus_voltage, accuracy=0.1)
odrive.handle.config.uart0_baudrate = 115200
odrive.handle.config.uart_a_baudrate = 115200
odrive.save_config_and_reboot()
@@ -205,9 +229,9 @@ class TestUartBurnIn():
yield (odrive, ports)
def run_test(self, odrive: ODriveComponent, port: SerialPortComponent, logger: Logger):
odrive.handle.config.enable_uart0 = True
odrive.handle.config.gpio1_mode = GPIO_MODE_UART0
odrive.handle.config.gpio2_mode = GPIO_MODE_UART0
odrive.handle.config.enable_uart_a = True
odrive.handle.config.gpio1_mode = GPIO_MODE_UART_A
odrive.handle.config.gpio2_mode = GPIO_MODE_UART_A
with port.open(115200) as ser:
with open('/dev/random', 'rb') as rand:
@@ -262,9 +286,9 @@ class TestUartNoise():
noise_enable.write(False)
time.sleep(0.1)
odrive.handle.config.enable_uart0 = True
odrive.handle.config.gpio1_mode = GPIO_MODE_UART0
odrive.handle.config.gpio2_mode = GPIO_MODE_UART0
odrive.handle.config.enable_uart_a = True
odrive.handle.config.gpio1_mode = GPIO_MODE_UART_A
odrive.handle.config.gpio2_mode = GPIO_MODE_UART_A
with port.open(115200) as ser:
# reset port to known state