cancel
Showing results for 
Search instead for 
Did you mean: 

ERROR IN CIRUCULAR BUFFER TO TRANSMIT FROM LAPTOP TO CAN via PYSERIAL AND THEN RECIVEING AT PRINTING THE FRAMES ON ANOTHER STM32 ON SERIAL

tantheman
Associate III

Code is given below in the files:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define RING_BUF_SIZE   32
#define PACKET_SIZE     8
#define CAN_CMD_ID      0x100
/* USER CODE END PD */

/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan;
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;

/* USER CODE BEGIN PV */
uint8_t r_buffer[RING_BUF_SIZE];
volatile uint16_t head_index = 0;
volatile uint16_t tail_index = 0;

static uint8_t packet[PACKET_SIZE];
static uint8_t pkt_index = 0;

CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailbox;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_CAN_Init(void);
static void MX_USART1_UART_Init(void);

/* USER CODE BEGIN PFP */
static void CAN_AppInit(void);
static void uart_can(uint8_t b);
static void send_can_packet(uint8_t *data);
/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

static void CAN_AppInit(void)
{
    TxHeader.StdId  = CAN_CMD_ID;
    TxHeader.IDE    = CAN_ID_STD;
    TxHeader.RTR    = CAN_RTR_DATA;
    TxHeader.DLC    = 8;
    TxHeader.TransmitGlobalTime = DISABLE;

    if (HAL_CAN_Start(&hcan) != HAL_OK)
        Error_Handler();
}

static void send_can_packet(uint8_t *data)
{
    if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailbox) != HAL_OK)
    {
        // CAN TX error handling if needed
    }
}

static void uart_can(uint8_t b)
{
    packet[pkt_index++] = b;

    if (pkt_index == PACKET_SIZE)
    {
        send_can_packet(packet);
        pkt_index = 0;
    }
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    HAL_Init();
    SystemClock_Config();

    MX_GPIO_Init();
    MX_DMA_Init();
    MX_CAN_Init();
    MX_USART1_UART_Init();

    CAN_AppInit();

    // Start DMA ring buffer reception
    HAL_UART_Receive_DMA(&huart1, r_buffer, RING_BUF_SIZE);

    while (1)
    {
        head_index = (RING_BUF_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx)) % RING_BUF_SIZE;

        while (tail_index != head_index)
        {
            uint8_t b = r_buffer[tail_index];
            tail_index = (tail_index + 1) % RING_BUF_SIZE;

            uart_can(b);
        }
    }
}

/* ---------------- SYSTEM & PERIPHERAL CONFIG BELOW ---------------- */

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState       = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState       = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource  = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL     = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) Error_Handler();

  RCC_ClkInitStruct.ClockType      = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                   | RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) Error_Handler();
}

static void MX_CAN_Init(void)
{
  hcan.Instance = CAN1;

  // 36 MHz / (18 * 16) ≈ 125 kbps (your desired bitrate)
  hcan.Init.Prescaler = 18;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_2TQ;

  hcan.Init.TimeTriggeredMode  = DISABLE;
  hcan.Init.AutoBusOff         = ENABLE;
  hcan.Init.AutoWakeUp         = DISABLE;
  hcan.Init.AutoRetransmission = ENABLE;
  hcan.Init.ReceiveFifoLocked  = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;

  if (HAL_CAN_Init(&hcan) != HAL_OK) Error_Handler();
}

static void MX_USART1_UART_Init(void)
{
  huart1.Instance        = USART1;
  huart1.Init.BaudRate   = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits   = UART_STOPBITS_1;
  huart1.Init.Parity     = UART_PARITY_NONE;
  huart1.Init.Mode       = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;

  if (HAL_UART_Init(&huart1) != HAL_OK) Error_Handler();
}

static void MX_DMA_Init(void)
{
  __HAL_RCC_DMA1_CLK_ENABLE();

  HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
}

static void MX_GPIO_Init(void)
{
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
}

void Error_Handler(void)
{
  __disable_irq();
  while (1) {}
}

#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{ }
#endif

(TRANSMITTER CODE ABOVE) 

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdbool.h>
#include <string.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define CAN_CMD_ID 0x100
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan;
UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8];

volatile bool rx_ready_flag = false;
uint8_t buff[8];
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
static void CAN_AppInit(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

static void CAN_AppInit(void)
{
  CAN_FilterTypeDef sFilterConfig = {0};

  // Accept only StdId = CAN_CMD_ID (0x100) into FIFO0
  sFilterConfig.FilterBank           = 0;
  sFilterConfig.FilterMode           = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale          = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
  sFilterConfig.FilterActivation     = ENABLE;

  // 11-bit ID goes in bits [10:0] → stored at [15:5] in FilterIdHigh
  sFilterConfig.FilterIdHigh     = (CAN_CMD_ID << 5);
  sFilterConfig.FilterIdLow      = 0x0000;
  sFilterConfig.FilterMaskIdHigh = (0x7FF << 5);   // match all 11 bits
  sFilterConfig.FilterMaskIdLow  = 0x0000;

  if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }

  if (HAL_CAN_Start(&hcan) != HAL_OK)
  {
    Error_Handler();
  }

  // Enable RX FIFO0 pending interrupt
  if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
    Error_Handler();
  }
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan_rx)
{
  if (hcan_rx->Instance == CAN1)
  {
    if (HAL_CAN_GetRxMessage(hcan_rx, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
    {
      // Error while reading, ignore
      return;
    }

    if ((RxHeader.IDE == CAN_ID_STD) &&
        (RxHeader.StdId == CAN_CMD_ID) &&
        (RxHeader.DLC  == 8))
    {
      memcpy(buff, RxData, 8);   // dst = buff, src=RxData

    }
  }
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  HAL_Init();

  /* USER CODE BEGIN Init */
  /* USER CODE END Init */

  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */

  MX_GPIO_Init();
  MX_CAN_Init();
  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */
  CAN_AppInit();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    if (rx_ready_flag == true)
    {
      HAL_UART_Transmit(&huart1, buff, 8, HAL_MAX_DELAY);

      // optional: newline so each frame is on its own line
      uint8_t nl[2] = {'\r', '\n'};
      HAL_UART_Transmit(&huart1, nl, 2, HAL_MAX_DELAY);

      rx_ready_flag = false;
    }
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState       = RCC_HSE_ON;        // <-- FIXED
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState       = RCC_HSI_ON;        // <-- FIXED
  RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_ON;        // <-- FIXED
  RCC_OscInitStruct.PLL.PLLSource  = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL     = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType      = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                   | RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;   // APB1 = 36 MHz
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;   // APB2 = 72 MHz
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief CAN Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_CAN_Init(void)
{
  hcan.Instance = CAN1;
  hcan.Init.Prescaler           = 18;          // 36MHz / (18 * 16) ≈ 125 kbit/s
  hcan.Init.Mode                = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth       = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1            = CAN_BS1_13TQ;
  hcan.Init.TimeSeg2            = CAN_BS2_2TQ;
  hcan.Init.TimeTriggeredMode   = DISABLE;
  hcan.Init.AutoBusOff          = ENABLE;
  hcan.Init.AutoWakeUp          = DISABLE;
  hcan.Init.AutoRetransmission  = ENABLE;
  hcan.Init.ReceiveFifoLocked   = DISABLE;
  hcan.Init.TransmitFifoPriority= DISABLE;

  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief USART1 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{
  huart1.Instance        = USART1;
  huart1.Init.BaudRate   = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits   = UART_STOPBITS_1;
  huart1.Init.Parity     = UART_PARITY_NONE;
  huart1.Init.Mode       = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;

  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief GPIO Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
}

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  __disable_irq();
  while (1)
  {
  }
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
  (void)file;
  (void)line;
}
#endif /* USE_FULL_ASSERT */

(RECIEVER CODE)

 

import serial
import time

# --------- Configure your COM port here ---------
PORT = "COM12"           # change if needed
BAUD = 115200

# timeout > 0  → blocking read with this max wait time (in seconds)
ser = serial.Serial(PORT, BAUD, timeout=0.05)   # 50 ms timeout is plenty


def format_frame(val: int) -> bytes:
    """
    Convert integer val (0–256) into exactly 8 bytes:
    "+XYZ+XYZ" where XYZ is a zero-padded 3-digit number.
    """
    return f"+{val:03d}+{val:03d}".encode("ascii")


print("Starting PWM sweep over UART...\n")

try:
    while True:

        # -------- INCREASE: 0 → 256 --------
        for pwm in range(0, 257):
            frame = format_frame(pwm)
            ser.write(frame)

            # Print what we sent
            print(f"TX: {frame.decode('ascii')}")
            # Optional: try to read back 8 bytes (if STM echoes)
            resp = ser.read(8)
            if resp:
                print(f"RX: {resp.decode(errors='ignore')}")

            time.sleep(0.01)   # 10 ms between frames

        # -------- DECREASE: 256 → 0 --------
        for pwm in range(256, -1, -1):
            frame = format_frame(pwm)
            ser.write(frame)

            print(f"TX: {frame.decode('ascii')}")
            resp = ser.read(8)
            if resp:
                print(f"RX: {resp.decode(errors='ignore')}")

            time.sleep(0.01)

except KeyboardInterrupt:
    print("\nStopped by user.")

ser.close()

(PYSERIAL CODE)

THE

Screenshot 2025-12-07 013214.png

THE FIRST COMMAND KEEPS REPEATING ON THE CAN REICIEVER END...... IS THERE ANY LOGICAL ERROR OR CODE ERROR, PLEASE POINT IT OUT 

0 REPLIES 0