driver

/* -------------------- 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值