/* -------------------- lin_driver_dsPIC.h -------------------- */
#ifndef LIN_DRIVER_DSPIC_H
#define LIN_DRIVER_DSPIC_H
#include <stdint.h>
#include <stdbool.h>
// 保持与S32K相同的类型定义
typedef enum {
LIN_SUCCESS = 0,
LIN_ERROR,
LIN_TIMEOUT,
LIN_BUFFER_FULL
} lin_status_t;
typedef enum {
LIN_TX_IDLE,
LIN_TX_BUSY,
LIN_TX_COMPLETE
} lin_transmit_status_t;
typedef enum {
LIN_RX_IDLE,
LIN_RX_BUSY,
LIN_RX_COMPLETE
} lin_receive_status_t;
// 回调函数类型
typedef void (*lin_callback_t)(uint8_t instance, uint32_t status);
// LIN节点类型
typedef enum {
MASTER_NODE,
SLAVE_NODE
} lin_node_function_t;
// 校验和类型
typedef enum {
CLASSIC_CS,
ENHANCED_CS
} lin_checksum_type_t;
// LIN配置结构体
typedef struct {
lin_node_function_t node_function;
uint32_t baud_rate;
lin_checksum_type_t checksum_type;
uint16_t response_timeout; // ms
} lin_user_config_t;
// 函数声明 - 与S32K驱动接口完全一致
lin_status_t LIN_DRV_Init(uint8_t instance, const lin_user_config_t *config);
void LIN_DRV_GetDefaultConfig(lin_user_config_t *config);
lin_status_t LIN_DRV_InstallCallback(uint8_t instance, uint8_t callback_type,
lin_callback_t callback);
lin_status_t LIN_DRV_SendFrameDataBlocking(uint8_t instance, uint8_t pid,
const uint8_t *txBuff, uint8_t txSize);
lin_status_t LIN_DRV_SendFrameData(uint8_t instance, uint8_t pid,
const uint8_t *txBuff, uint8_t txSize);
lin_transmit_status_t LIN_DRV_GetTransmitStatus(uint8_t instance);
lin_status_t LIN_DRV_ReceiveFrameDataBlocking(uint8_t instance, uint8_t *rxBuff,
uint8_t rxSize, uint32_t timeout);
lin_status_t LIN_DRV_ReceiveFrameData(uint8_t instance, uint8_t *rxBuff,
uint8_t rxSize);
lin_status_t LIN_DRV_AbortTransferData(uint8_t instance);
lin_receive_status_t LIN_DRV_GetReceiveStatus(uint8_t instance);
lin_status_t LIN_DRV_GoToSleepMode(uint8_t instance);
lin_status_t LIN_DRV_GotoIdleState(uint8_t instance);
lin_status_t LIN_DRV_MasterSendHeader(uint8_t instance, uint8_t pid);
#endif /* LIN_DRIVER_DSPIC_H */
/* -------------------- lin_driver_dsPIC.c -------------------- */
#include "lin_driver_dsPIC.h"
#include <xc.h>
#include <string.h>
// 配置参数
#define LIN_INSTANCE_COUNT 1 // 支持的单通道
#define LIN_TX_QUEUE_SIZE 64 // 发送队列大小
#define LIN_RX_QUEUE_SIZE 64 // 接收队列大小
#define MAX_RESPONSE_TIMEOUT 100 // 最大响应超时(ms)
// LIN驱动状态结构体
typedef struct {
// 发送队列 (MCC风格)
uint8_t txQueue[LIN_TX_QUEUE_SIZE];
volatile uint8_t *txHead;
volatile uint8_t *txTail;
// 接收队列 (MCC风格)
uint8_t rxQueue[LIN_RX_QUEUE_SIZE];
volatile uint8_t *rxHead;
volatile uint8_t *rxTail;
// LIN状态
lin_user_config_t config;
lin_transmit_status_t txStatus;
lin_receive_status_t rxStatus;
bool isMaster;
bool headerSent;
bool responseExpected;
uint8_t expectedPID;
uint16_t responseTimeout;
// 回调函数
lin_callback_t txCallback;
lin_callback_t rxCallback;
lin_callback_t breakCallback;
} lin_driver_state_t;
static lin_driver_state_t linState[LIN_INSTANCE_COUNT];
// 私有函数声明
static void LIN_ConfigureHardware(uint8_t instance);
static void LIN_ResetQueues(uint8_t instance);
static void LIN_ProcessReceivedData(uint8_t instance);
static bool LIN_IsTxReady(uint8_t instance);
static bool LIN_IsRxReady(uint8_t instance);
/* ===================== 接口函数实现 ===================== */
lin_status_t LIN_DRV_Init(uint8_t instance, const lin_user_config_t *config)
{
if(instance >= LIN_INSTANCE_COUNT) return LIN_ERROR;
// 保存配置
memcpy(&linState[instance].config, config, sizeof(lin_user_config_t));
// 初始化队列
LIN_ResetQueues(instance);
// 配置硬件
LIN_ConfigureHardware(instance);
// 初始化状态
linState[instance].isMaster = (config->node_function == MASTER_NODE);
linState[instance].txStatus = LIN_TX_IDLE;
linState[instance].rxStatus = LIN_RX_IDLE;
linState[instance].headerSent = false;
linState[instance].responseExpected = false;
// 启用接收中断
IFS4bits.U1RXIF = 0;
IEC4bits.U1RXIE = 1;
return LIN_SUCCESS;
}
void LIN_DRV_GetDefaultConfig(lin_user_config_t *config)
{
config->node_function = MASTER_NODE;
config->baud_rate = 19200;
config->checksum_type = ENHANCED_CS;
config->response_timeout = 100; // 100ms默认超时
}
lin_status_t LIN_DRV_InstallCallback(uint8_t instance, uint8_t callback_type,
lin_callback_t callback)
{
if(instance >= LIN_INSTANCE_COUNT) return LIN_ERROR;
switch(callback_type) {
case 1: // LIN_TX_COMPLETE_CALLBACK
linState[instance].txCallback = callback;
break;
case 2: // LIN_RX_COMPLETE_CALLBACK
linState[instance].rxCallback = callback;
break;
case 3: // LIN_BREAK_DETECT_CALLBACK
linState[instance].breakCallback = callback;
break;
default:
return LIN_ERROR;
}
return LIN_SUCCESS;
}
lin_status_t LIN_DRV_SendFrameDataBlocking(uint8_t instance, uint8_t pid,
const uint8_t *txBuff, uint8_t txSize)
{
lin_status_t status = LIN_DRV_SendFrameData(instance, pid, txBuff, txSize);
if(status != LIN_SUCCESS) return status;
// 阻塞等待发送完成
uint32_t timeout = linState[instance].config.response_timeout * 1000; // μs
while(LIN_DRV_GetTransmitStatus(instance) == LIN_TX_BUSY) {
__delay_us(10);
if(timeout-- == 0) return LIN_TIMEOUT;
}
return LIN_SUCCESS;
}
lin_status_t LIN_DRV_SendFrameData(uint8_t instance, uint8_t pid,
const uint8_t *txBuff, uint8_t txSize)
{
if(instance >= LIN_INSTANCE_COUNT) return LIN_ERROR;
// 1. 发送帧头
if(linState[instance].isMaster) {
LIN_DRV_MasterSendHeader(instance, pid);
// 设置数据长度 (主设备用U1P2)
U1P2 = txSize;
}
// 2. 添加数据到发送队列
for(int i = 0; i < txSize; i++) {
// 检查队列空间 (MCC风格)
while(!LIN_IsTxReady(instance)) {
// 可添加超时机制
__delay_us(10);
}
// 添加到队列尾部
*linState[instance].txTail = txBuff[i];
linState[instance].txTail++;
// 环形缓冲区处理
if(linState[instance].txTail ==
&linState[instance].txQueue[LIN_TX_QUEUE_SIZE]) {
linState[instance].txTail = linState[instance].txQueue;
}
}
// 3. 启动发送
linState[instance].txStatus = LIN_TX_BUSY;
IEC4bits.U1TXIE = 1; // 使能发送中断
return LIN_SUCCESS;
}
lin_transmit_status_t LIN_DRV_GetTransmitStatus(uint8_t instance)
{
if(instance >= LIN_INSTANCE_COUNT) return LIN_TX_IDLE;
return linState[instance].txStatus;
}
lin_status_t LIN_DRV_ReceiveFrameDataBlocking(uint8_t instance, uint8_t *rxBuff,
uint8_t rxSize, uint32_t timeout)
{
uint32_t startTime = getSystemTime(); // 伪代码,需实现获取时间
while(!LIN_IsRxReady(instance)) {
if(getSystemTime() - startTime > timeout) {
return LIN_TIMEOUT;
}
// 可添加低功耗等待
__delay_us(100);
}
return LIN_DRV_ReceiveFrameData(instance, rxBuff, rxSize);
}
lin_status_t LIN_DRV_ReceiveFrameData(uint8_t instance, uint8_t *rxBuff,
uint8_t rxSize)
{
if(instance >= LIN_INSTANCE_COUNT) return LIN_ERROR;
uint8_t received = 0;
// 从接收队列读取数据 (MCC风格)
while(received < rxSize &&
linState[instance].rxHead != linState[instance].rxTail) {
rxBuff[received] = *linState[instance].rxHead;
received++;
linState[instance].rxHead++;
if(linState[instance].rxHead ==
&linState[instance].rxQueue[LIN_RX_QUEUE_SIZE]) {
linState[instance].rxHead = linState[instance].rxQueue;
}
}
if(received == rxSize) {
return LIN_SUCCESS;
}
return LIN_INCOMPLETE;
}
lin_status_t LIN_DRV_AbortTransferData(uint8_t instance)
{
if(instance >= LIN_INSTANCE_COUNT) return LIN_ERROR;
// 禁用发送中断
IEC4bits.U1TXIE = 0;
// 重置队列
LIN_ResetQueues(instance);
// 更新状态
linState[instance].txStatus = LIN_TX_IDLE;
linState[instance].rxStatus = LIN_RX_IDLE;
return LIN_SUCCESS;
}
lin_receive_status_t LIN_DRV_GetReceiveStatus(uint8_t instance)
{
if(instance >= LIN_INSTANCE_COUNT) return LIN_RX_IDLE;
return linState[instance].rxStatus;
}
lin_status_t LIN_DRV_GoToSleepMode(uint8_t instance)
{
if(instance >= LIN_INSTANCE_COUNT) return LIN_ERROR;
// 发送睡眠命令 (简化实现)
if(linState[instance].isMaster) {
uint8_t sleepFrame[2] = {0x00, 0x00};
LIN_DRV_SendFrameData(instance, 0x3C, sleepFrame, 2);
}
// 禁用UART节省功耗
U1MODEbits.UARTEN = 0;
return LIN_SUCCESS;
}
lin_status_t LIN_DRV_GotoIdleState(uint8_t instance)
{
if(instance >= LIN_INSTANCE_COUNT) return LIN_ERROR;
// 确保UART启用
U1MODEbits.UARTEN = 1;
U1STAbits.UTXEN = 1;
U1STAbits.URXEN = 1;
// 重置状态
LIN_ResetQueues(instance);
linState[instance].txStatus = LIN_TX_IDLE;
linState[instance].rxStatus = LIN_RX_IDLE;
return LIN_SUCCESS;
}
lin_status_t LIN_DRV_MasterSendHeader(uint8_t instance, uint8_t pid)
{
if(instance >= LIN_INSTANCE_COUNT || !linState[instance].isMaster)
return LIN_ERROR;
// 确保处于主模式
U1MODEbits.MOD = 0b1100;
// 写入PID触发自动帧头发送
U1P1 = pid & 0x3F;
linState[instance].headerSent = true;
// 设置超时计数器
linState[instance].responseTimeout = linState[instance].config.response_timeout;
linState[instance].responseExpected = true;
return LIN_SUCCESS;
}
/* ===================== 中断处理函数 ===================== */
void __attribute__((interrupt, no_auto_psv)) _U1Interrupt(void)
{
// 处理接收中断
if(IFS4bits.U1RXIF && IEC4bits.U1RXIE) {
// 处理所有可用数据
while(U1STAbits.URXDA) {
uint8_t data = U1RXREG;
// 添加到接收队列 (MCC风格)
*linState[0].rxTail = data;
linState[0].rxTail++;
if(linState[0].rxTail == &linState[0].rxQueue[LIN_RX_QUEUE_SIZE]) {
linState[0].rxTail = linState[0].rxQueue;
}
// 更新接收状态
linState[0].rxStatus = LIN_RX_BUSY;
// 特殊处理:从设备PID匹配
if(!linState[0].isMaster && linState[0].expectedPID == data) {
// 准备响应...
}
}
// 标记数据接收完成
if(linState[0].rxHead != linState[0].rxTail) {
linState[0].rxStatus = LIN_RX_COMPLETE;
// 调用接收完成回调
if(linState[0].rxCallback) {
linState[0].rxCallback(0, 0);
}
}
IFS4bits.U1RXIF = 0; // 清除接收中断标志
}
// 处理发送中断
if(IFS4bits.U1TXIF && IEC4bits.U1TXIE) {
// 检查是否有数据要发送
if(linState[0].txHead != linState[0].txTail) {
// 发送数据直到硬件缓冲区满
while(!U1STAHbits.UTXBF &&
(linState[0].txHead != linState[0].txTail)) {
U1TXREG = *linState[0].txHead;
linState[0].txHead++;
if(linState[0].txHead == &linState[0].txQueue[LIN_TX_QUEUE_SIZE]) {
linState[0].txHead = linState[0].txQueue;
}
}
// 检查是否发送完成
if(linState[0].txHead == linState[0].txTail) {
linState[0].txStatus = LIN_TX_COMPLETE;
IEC4bits.U1TXIE = 0; // 禁用发送中断
// 调用发送完成回调
if(linState[0].txCallback) {
linState[0].txCallback(0, 0);
}
// 特殊处理:帧头发送后
if(linState[0].headerSent) {
linState[0].headerSent = false;
// 可触发数据阶段
}
}
}
IFS4bits.U1TXIF = 0; // 清除发送中断标志
}
// 处理Break检测中断
if(IFS4bits.U1RXBKIF) {
// 调用Break检测回调
if(linState[0].breakCallback) {
linState[0].breakCallback(0, 0);
}
// 从设备:准备接收帧头
if(!linState[0].isMaster) {
linState[0].rxStatus = LIN_RX_BUSY;
}
IFS4bits.U1RXBKIF = 0;
}
}
/* ===================== 私有函数实现 ===================== */
static void LIN_ConfigureHardware(uint8_t instance)
{
// 禁用UART
U1MODEbits.UARTEN = 0;
// 配置为LIN模式
U1MODEbits.MOD = (linState[instance].config.node_function == MASTER_NODE) ?
0b1100 : 0b1101;
// 校验和类型
U1CONbits.C0EN = (linState[instance].config.checksum_type == ENHANCED_CS);
// 波特率
uint32_t brg = (FCY / (16 * linState[instance].config.baud_rate)) - 1;
U1BRG = (brg > 0xFFFF) ? 0xFFFF : brg;
// 使能UART
U1MODEbits.UARTEN = 1;
U1STAbits.UTXEN = 1;
U1STAbits.URXEN = 1;
// 配置中断优先级
IPC4bits.U1RXIP = 4; // 接收中断优先级
IPC4bits.U1TXIP = 3; // 发送中断优先级
}
static void LIN_ResetQueues(uint8_t instance)
{
linState[instance].txHead = linState[instance].txQueue;
linState[instance].txTail = linState[instance].txQueue;
linState[instance].rxHead = linState[instance].rxQueue;
linState[instance].rxTail = linState[instance].rxQueue;
}
static bool LIN_IsTxReady(uint8_t instance)
{
// 计算队列中的空闲空间
uint16_t used = (linState[instance].txTail - linState[instance].txHead);
if(linState[instance].txTail < linState[instance].txHead) {
used = LIN_TX_QUEUE_SIZE -
(linState[instance].txHead - linState[instance].txTail);
}
return (LIN_TX_QUEUE_SIZE - used) > 0;
}
static bool LIN_IsRxReady(uint8_t instance)
{
return linState[instance].rxHead != linState[instance].rxTail;
}