начало измнений для аппаратноо кан:

- без ошибок работает аппаратный кан
- с ошибками - программный
This commit is contained in:
2025-08-08 11:57:34 +03:00
parent 7a7f838a4a
commit f85acb03a9
11 changed files with 400 additions and 262 deletions

33
Core/CANEmu/canConfig.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef CANCONFIG_H
#define CANCONFIG_H
#define CAN_ONLY_EMULATING
// Настройки GPIO и таймера
#define CANEMU_TX_GPIO_PORT GPIOA
#define CANEMU_TX_GPIO_PIN 12
#define CANEMU_TIM TIM2
#define CANEMU_TIM_US_TICKS 72 // Для 1 мкс при 72 МГц
#define CANEMU_TIM_CLOCK_HZ 72000000UL // частота таймера
#define CAN_MIN_PERIOD 20
#define LED_WORKING(on_off) \
do { \
if (!on_off) GPIOC->ODR |= (1U << 13); \
else GPIOC->ODR &= ~(1U << 13); \
} while (0)
// === Макросы управления GPIO ===
#define can_tx_set_1() (CANEMU_TX_GPIO_PORT->BSRR = (1U << CANEMU_TX_GPIO_PIN))
#define can_tx_set_0() (CANEMU_TX_GPIO_PORT->BRR = (1U << CANEMU_TX_GPIO_PIN))
// === Макросы управления таймером ===
#define tim_reset(TIM) ((TIM)->CNT = 0)
#define tim_get(TIM) ((uint16_t)(TIM)->CNT)
#define tim_start(TIM) ((TIM)->CR1 |= TIM_CR1_CEN)
#define tim_stop(TIM) ((TIM)->CR1 &= ~TIM_CR1_CEN)
#endif // CANEMU_H

View File

@@ -1,12 +1,8 @@
#include "canEmu.h"
#include "stm32f1xx_hal.h"
#include "rs_message.h"
volatile uint32_t CANEMU_BIT_TICKS = 0;
CANEmu_HandleTypeDef hcanemu;
int flag_manual = 0;
int transmit_prev = 0;
static void delay_us(uint32_t us) {
uint32_t ticks = us * CANEMU_TIM_US_TICKS;
@@ -29,7 +25,7 @@ void CANEmu_Init(CANEmu_HandleTypeDef *canemu, uint32_t bitrate) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin : PB0 */
/*Configure GPIO pin */
GPIO_InitStruct.Pin = (1<<CANEMU_TX_GPIO_PIN);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
@@ -45,6 +41,7 @@ void CANEmu_Init(CANEmu_HandleTypeDef *canemu, uint32_t bitrate) {
canemu->bitrate_bps = bitrate;
tim_start(CANEMU_TIM);
can_tx_set_1(); // Recessive level
canemu->EmuFlag = 1;
}
void wait_exact_ticks(uint16_t target_ticks) {
@@ -87,60 +84,3 @@ void CANEmu_SendFrame(CANEmu_HandleTypeDef *canemu) {
LED_WORKING(0);
#endif
}
void CANEmu_Working(CANEmu_HandleTypeDef *canemu)
{
if(flag_manual == 0)
{
canemu->start_poll = MB_DATA.Coils.START_POLLING;
canemu->transmit = MB_DATA.Coils.START_SINGLE_FRAME;
canemu->period_ms = MB_DATA.HoldRegs.CAN_PERIOD;
if(canemu->period_ms < CAN_MIN_PERIOD)
{
canemu->period_ms = CAN_MIN_PERIOD;
}
// can message
canemu->header.IDE = MB_DATA.Coils.HEADER_IDE;
canemu->header.RTR = MB_DATA.Coils.HEADER_RTR;
canemu->bitrate_bps = (uint32_t)MB_DATA.HoldRegs.CAN_BITRATE_KBPS*1000;
canemu->header.ExtId = ((uint32_t)MB_DATA.HoldRegs.CAN_ID_HI << 16) | MB_DATA.HoldRegs.CAN_ID_LO;
canemu->header.StdId = canemu->header.ExtId;
canemu->header.DLC = (uint8_t)MB_DATA.HoldRegs.CAN_DLC & 0xF;
canemu->data[0] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_0;
canemu->data[1] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_1;
canemu->data[2] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_2;
canemu->data[3] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_3;
canemu->data[4] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_4;
canemu->data[5] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_5;
canemu->data[6] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_6;
canemu->data[7] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_7;
// errors
canemu->errors.FF_SRS = MB_DATA.Coils.FLIP_SRS;
canemu->errors.FF_IDE = MB_DATA.Coils.FLIP_IDE;
canemu->errors.FF_RTR = MB_DATA.Coils.FLIP_RTR;
canemu->errors.FF_R1 = MB_DATA.Coils.FLIP_R1;
canemu->errors.FF_R0 = MB_DATA.Coils.FLIP_R0;
canemu->errors.MSGID = MB_DATA.Coils.FLIP_MSGID_BIT;
canemu->errors.DATA = MB_DATA.Coils.FLIP_DATA_BIT;
canemu->errors.CRC_ERR = MB_DATA.Coils.FLIP_CRC_BIT;
canemu->errors.STUFF_BITS = MB_DATA.Coils.DISABLE_STUFF_BITS;
}
if(canemu->start_poll)
{
canemu->transmit = 0;
HAL_Delay(canemu->period_ms);
CANEmu_SendFrame(&hcanemu);
}
else if((canemu->transmit == 1) && (transmit_prev == 0))
{
CANEmu_SendFrame(&hcanemu);
}
transmit_prev = canemu->transmit;
}

View File

@@ -3,30 +3,7 @@
#include "canform.h"
#include "tim.h"
// Настройки GPIO и таймера
#define CANEMU_TX_GPIO_PORT GPIOB
#define CANEMU_TX_GPIO_PIN 0
#define CANEMU_TIM TIM2
#define CANEMU_TIM_US_TICKS 72 // Для 1 мкс при 72 МГц
#define CANEMU_TIM_CLOCK_HZ 72000000UL // частота таймера
#define CAN_MIN_PERIOD 20
#define LED_WORKING(on_off) \
do { \
if (!on_off) GPIOC->ODR |= (1U << 13); \
else GPIOC->ODR &= ~(1U << 13); \
} while (0)
// === Макросы управления GPIO ===
#define can_tx_set_1() (CANEMU_TX_GPIO_PORT->BSRR = (1U << CANEMU_TX_GPIO_PIN))
#define can_tx_set_0() (CANEMU_TX_GPIO_PORT->BRR = (1U << CANEMU_TX_GPIO_PIN))
// === Макросы управления таймером ===
#define tim_reset(TIM) ((TIM)->CNT = 0)
#define tim_get(TIM) ((uint16_t)(TIM)->CNT)
#define tim_start(TIM) ((TIM)->CR1 |= TIM_CR1_CEN)
#define tim_stop(TIM) ((TIM)->CR1 &= ~TIM_CR1_CEN)
#include "canConfig.h"
typedef struct
{
@@ -37,6 +14,7 @@ typedef struct
uint32_t transmit;
uint32_t period_ms;
CAN_ErrorFlags_t errors;
unsigned EmuFlag;
}CANEmu_HandleTypeDef;
extern CANEmu_HandleTypeDef hcanemu;

97
Core/CANEmu/canWorking.c Normal file
View File

@@ -0,0 +1,97 @@
#include "canWorking.h"
CANEmu_HandleTypeDef hcanemu;
uint32_t mbox;
CANEmu_HandleTypeDef hcanemu;
int flag_manual = 0;
int transmit_prev = 0;
void CAN_Init(CANEmu_HandleTypeDef *canemu)
{
#ifdef CAN_ONLY_EMULATING
CANEmu_SendFrame(canemu);
if(canemu->EmuFlag == 0)
{
CANEmu_Init(canemu, canemu->bitrate_bps);
}
#else
if(canemu->errors.all && (canemu->EmuFlag == 0))
{
CANEmu_Init(canemu, canemu->bitrate_bps);
}
else if ((canemu->errors.all == 0) && canemu->EmuFlag)
{
canemu->EmuFlag = 0;
HAL_CAN_MspInit(&hcan);
}
#endif
}
void CAN_SendFrame(CANEmu_HandleTypeDef *canemu)
{
#ifdef CAN_ONLY_EMULATING
CANEmu_SendFrame(canemu);
#else
if(canemu->errors.all)
CANEmu_SendFrame(canemu);
else
HAL_CAN_AddTxMessage(&hcan, &canemu->header, canemu->data, &mbox);
#endif
}
void CANEmu_Working(CANEmu_HandleTypeDef *canemu)
{
if(flag_manual == 0)
{
canemu->start_poll = MB_DATA.Coils.START_POLLING;
canemu->transmit = MB_DATA.Coils.START_SINGLE_FRAME;
canemu->period_ms = MB_DATA.HoldRegs.CAN_PERIOD;
if(canemu->period_ms < CAN_MIN_PERIOD)
{
canemu->period_ms = CAN_MIN_PERIOD;
}
// can message
canemu->header.IDE = MB_DATA.Coils.HEADER_IDE;
canemu->header.RTR = MB_DATA.Coils.HEADER_RTR;
canemu->bitrate_bps = (uint32_t)MB_DATA.HoldRegs.CAN_BITRATE_KBPS*1000;
canemu->header.ExtId = ((uint32_t)MB_DATA.HoldRegs.CAN_ID_HI << 16) | MB_DATA.HoldRegs.CAN_ID_LO;
canemu->header.StdId = canemu->header.ExtId;
canemu->header.DLC = (uint8_t)MB_DATA.HoldRegs.CAN_DLC & 0xF;
canemu->data[0] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_0;
canemu->data[1] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_1;
canemu->data[2] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_2;
canemu->data[3] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_3;
canemu->data[4] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_4;
canemu->data[5] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_5;
canemu->data[6] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_6;
canemu->data[7] = (uint8_t)MB_DATA.HoldRegs.CAN_DATA_7;
// errors
canemu->errors.bit.FF_SRS = MB_DATA.Coils.FLIP_SRS;
canemu->errors.bit.FF_IDE = MB_DATA.Coils.FLIP_IDE;
canemu->errors.bit.FF_RTR = MB_DATA.Coils.FLIP_RTR;
canemu->errors.bit.FF_R1 = MB_DATA.Coils.FLIP_R1;
canemu->errors.bit.FF_R0 = MB_DATA.Coils.FLIP_R0;
canemu->errors.bit.MSGID = MB_DATA.Coils.FLIP_MSGID_BIT;
canemu->errors.bit.DATA = MB_DATA.Coils.FLIP_DATA_BIT;
canemu->errors.bit.CRC_ERR = MB_DATA.Coils.FLIP_CRC_BIT;
canemu->errors.bit.STUFF_BITS = MB_DATA.Coils.DISABLE_STUFF_BITS;
}
CAN_Init(canemu);
if(canemu->start_poll)
{
canemu->transmit = 0;
HAL_Delay(canemu->period_ms);
CAN_SendFrame(canemu);
}
else if((canemu->transmit == 1) && (transmit_prev == 0))
{
CAN_SendFrame(canemu);
}
transmit_prev = canemu->transmit;
}

12
Core/CANEmu/canWorking.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef CANWORKING_H
#define CANWORKING_H
#include "stm32f1xx_hal.h"
#include "can.h"
#include "rs_message.h"
#include "canEmu.h"
void CANEmu_Working(CANEmu_HandleTypeDef *canemu);
#endif // CANEMU_H

View File

@@ -161,7 +161,7 @@ void form_CAN_bitstream_full(const CAN_TxHeaderTypeDef *header, const uint8_t *d
uint32_t crc_start = raw_len;
append_bits(raw_bits, &raw_len, crc, 15);
if (errors.CRC_ERR) {
if (errors.bit.CRC_ERR) {
flip_bit(crc_start); // инвертируем 1-й бит CRC для примера
}
@@ -169,17 +169,17 @@ void form_CAN_bitstream_full(const CAN_TxHeaderTypeDef *header, const uint8_t *d
append_bit(raw_bits, &raw_len, 1);
// Ошибки
if (errors.FF_SRS) flip_bit(srr_idx);
if (errors.FF_IDE) flip_bit(ide_idx);
if (errors.FF_RTR) flip_bit(rtr_idx);
if (errors.FF_R1) flip_bit(r1_idx);
if (errors.FF_R0) flip_bit(r0_idx);
if (errors.DATA) flip_bit(data_idx);
if (errors.bit.FF_SRS) flip_bit(srr_idx);
if (errors.bit.FF_IDE) flip_bit(ide_idx);
if (errors.bit.FF_RTR) flip_bit(rtr_idx);
if (errors.bit.FF_R1) flip_bit(r1_idx);
if (errors.bit.FF_R0) flip_bit(r0_idx);
if (errors.bit.DATA) flip_bit(data_idx);
// MSGID_ERR — переворачиваем 1-й бит ID (MSB ID[10]) для примера
if (errors.MSGID) flip_bit(id_start);
if (errors.bit.MSGID) flip_bit(id_start);
// 10. Apply bit stuffing, пропускаем вставку stuff bits если ошибка ERR_STUFF_BITS
apply_bit_stuffing_with_error(raw_bits, raw_len, can_bits, &can_bits_len, errors.STUFF_BITS);
apply_bit_stuffing_with_error(raw_bits, raw_len, can_bits, &can_bits_len, errors.bit.STUFF_BITS);
// 7. ACK Slot (dominant)
append_bit(can_bits, &can_bits_len, 1);

View File

@@ -7,17 +7,21 @@
#include <stdbool.h>
typedef struct {
uint16_t FF_SRS : 1; // Ошибка SRS бит (extended frame)
uint16_t FF_IDE : 1; // Ошибка IDE бит
uint16_t FF_RTR : 1; // Ошибка RTR бит
uint16_t FF_R1 : 1; // Ошибка r1 бит (reserved)
uint16_t FF_R0 : 1; // Ошибка r0 бит (reserved)
uint16_t MSGID : 1; // Ошибка битов ID
uint16_t DATA : 1; // Ошибка битов данных
uint16_t CRC_ERR : 1; // Ошибка битов CRC
uint16_t STUFF_BITS : 1; // Ошибка бит-стаффинга (пропуск вставки stuff bits)
uint16_t reserved : 7; // Зарезервировано
typedef union {
uint16_t all;
struct
{
unsigned FF_SRS : 1; // Ошибка SRS бит (extended frame)
unsigned FF_IDE : 1; // Ошибка IDE бит
unsigned FF_RTR : 1; // Ошибка RTR бит
unsigned FF_R1 : 1; // Ошибка r1 бит (reserved)
unsigned FF_R0 : 1; // Ошибка r0 бит (reserved)
unsigned MSGID : 1; // Ошибка битов ID
unsigned DATA : 1; // Ошибка битов данных
unsigned CRC_ERR : 1; // Ошибка битов CRC
unsigned STUFF_BITS : 1; // Ошибка бит-стаффинга (пропуск вставки stuff bits)
unsigned reserved : 7; // Зарезервировано
}bit;
} CAN_ErrorFlags_t;
#ifndef IS_FUNCTIONAL_STATE

View File

@@ -69,6 +69,14 @@ void MX_GPIO_Init(void)
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// /*Configure GPIO pin : PA9 */
// GPIO_InitStruct.Pin = GPIO_PIN_9;
// GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
// GPIO_InitStruct.Pull = GPIO_NOPULL;
// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
// HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}