Skip to content

Instantly share code, notes, and snippets.

@nanase
Created May 1, 2022 08:29
Show Gist options
  • Save nanase/1dd2a413782f633ee48df59b78f7a663 to your computer and use it in GitHub Desktop.
Save nanase/1dd2a413782f633ee48df59b78f7a663 to your computer and use it in GitHub Desktop.
Communication between Raspberry Pi Pico (RP2040) and STM32F303K8 with UART
// STM32F303K8 (Slave)
#include "main.h"
#include "usart.h"
/*
RP2040 ---- STM32F303K8
UART0_TX GPIO16 ---\/--- PB6 UART1_TX
UART0_RX GPIO17 <--/\--> PB7 UART1_RX
UART0_RTS GPIO18 ---\/--- PA11 UART1_RTS (pulled-up)
UART0_CTS GPIO19 <--/\--> PA12 UART1_CTS (pulled-up)
*/
extern volatile bool uart_received;
extern uint8_t uart_receive_buffer[COM_SIZE];
extern uint8_t uart_transmit_buffer[COM_SIZE];
uint8_t buffer[COM_SIZE];
uint8_t index = 0;
bool uart_recover_error() {
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_ORE) || __HAL_UART_GET_FLAG(&huart1, UART_FLAG_NE) ||
__HAL_UART_GET_FLAG(&huart1, UART_FLAG_FE) || __HAL_UART_GET_FLAG(&huart1, UART_FLAG_PE)) {
__HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_NEF | UART_CLEAR_OREF | UART_FLAG_RXNE | UART_FLAG_ORE);
HAL_UART_Abort(&huart1);
HAL_UART_Receive_IT(&huart1, uart_receive_buffer, RECEIVE_SIZE);
return true;
}
return false;
}
void loop() {
while (!uart_received) {
// HAL_Delay(1);
}
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
uart_received = false;
if (uart_recover_error())
return;
for (size_t i = 0; i < RECEIVE_SIZE; i++) {
buffer[i + index] = uart_receive_buffer[i];
}
index += RECEIVE_SIZE;
if (index >= COM_SIZE) {
if (buffer[0] == 0x42) {
// OK = 0x42
uart_transmit_buffer[0] = 0x42 | 0x80;
for (size_t i = 1; i < COM_SIZE; i++) {
uart_transmit_buffer[i] = buffer[i];
}
HAL_UART_Transmit_IT(&huart1, uart_transmit_buffer, COM_SIZE);
} else {
// error
HAL_UART_Receive(&huart1, uart_receive_buffer, 1, 0);
// send error code to master
uart_transmit_buffer[0] = 0xb3;
HAL_UART_Transmit_IT(&huart1, uart_transmit_buffer, 1);
}
index = 0;
} else {
HAL_UART_Receive_IT(&huart1, uart_receive_buffer, RECEIVE_SIZE);
}
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
}
/* USER CODE BEGIN Header */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f3xx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
#define COM_SIZE 16
#define RECEIVE_SIZE 1
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
void setup();
void loop();
void yield();
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define LED_Pin GPIO_PIN_3
#define LED_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
// STM32F303K8 (Slave)
#include "main.h"
#include "usart.h"
volatile bool uart_received = false;
uint8_t uart_receive_buffer[COM_SIZE];
uint8_t uart_transmit_buffer[COM_SIZE];
void setup() {
HAL_UART_Receive_IT(&huart1, uart_receive_buffer, RECEIVE_SIZE);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == huart1.Instance) {
uart_received = true;
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == huart1.Instance) {
HAL_UART_Receive_IT(&huart1, uart_receive_buffer, RECEIVE_SIZE);
}
}
// RP2040 (Master)
#include <Arduino.h>
#define COM_SIZE 16
#define USB_SPEED 9600
#define UART_SPEED 2000000
/*
RP2040 ---- STM32F303K8
UART0_TX GPIO16 ---\/--- PB6 UART1_TX
UART0_RX GPIO17 <--/\--> PB7 UART1_RX
UART0_RTS GPIO18 ---\/--- PA11 UART1_RTS (pulled-up)
UART0_CTS GPIO19 <--/\--> PA12 UART1_CTS (pulled-up)
*/
arduino::UART Serial1Test(16, 17, 18, 19);
void setup() {
SerialUSB.begin(USB_SPEED);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
Serial1Test.begin(UART_SPEED);
}
bool uart_test() {
static uint8_t value = 0xff;
uint8_t buffer[COM_SIZE];
value++;
buffer[0] = 0x42;
for (size_t i = 1; i < COM_SIZE; i++) {
buffer[i] = value;
}
// SerialUSB.print("send: ");
// for (size_t i = 0; i < COM_SIZE - 1; i++) {
// SerialUSB.print(buffer[i], HEX);
// SerialUSB.print(" ");
// }
// SerialUSB.println(buffer[COM_SIZE - 1], HEX);
digitalWrite(LED_BUILTIN, HIGH);
// Make rx_buffer in Serial.h public if an error occurs here.
// Instead, if you don't care about speed, try following:
// Serial1Test.end();
// Serial1Test.begin(UART_SPEED);
Serial1Test.rx_buffer.clear();
Serial1Test.write(buffer, COM_SIZE);
for (size_t i = 0; i < COM_SIZE; i++) {
buffer[i] = 0;
}
bool succeeded = true;
for (size_t i = 0; i < COM_SIZE; i++) {
uint16_t timeout = 0;
while (Serial1Test.available() < 1) {
// delayMicroseconds(1);
timeout++;
if (timeout > 1000) {
succeeded = false;
break;
}
}
buffer[i] = (uint8_t)Serial1Test.read();
if (i == 0) {
if (buffer[0] != (0x42 | 0x80)) {
// error
Serial1Test.rx_buffer.clear();
succeeded = false;
break;
}
} else {
succeeded = succeeded && (buffer[i] == value);
}
}
digitalWrite(LED_BUILTIN, LOW);
// SerialUSB.print("recv: ");
// for (size_t i = 0; i < COM_SIZE - 1; i++) {
// SerialUSB.print(buffer[i], HEX);
// SerialUSB.print(" ");
// }
// SerialUSB.println(buffer[COM_SIZE - 1], HEX);
return succeeded;
}
void loop() {
uint32_t success = 0;
uint32_t failed = 0;
uint32_t t = micros();
for (uint32_t i = 0; i < 1000; i++) {
if (uart_test())
success++;
else
failed++;
}
uint32_t elapsed = micros() - t;
SerialUSB.print("success: ");
SerialUSB.print(success);
SerialUSB.print(", failed: ");
SerialUSB.print(failed);
SerialUSB.print(" (");
SerialUSB.print(elapsed / 1000.0, 2);
SerialUSB.println(" ms)");
delay(1000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment