Created
May 1, 2022 08:29
-
-
Save nanase/1dd2a413782f633ee48df59b78f7a663 to your computer and use it in GitHub Desktop.
Communication between Raspberry Pi Pico (RP2040) and STM32F303K8 with UART
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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 */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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