#ifndef POS_VTK_SERVICE_H #define POS_VTK_SERVICE_H #include "publicdata/public_define.h" #if (POS_VTK_EN) #ifdef __cplusplus extern "C" { #endif #include "main.h" #include "usart.h" #include "pos_vtk/vtk_pos_protocol.h" #include "pos_vtk/vtk_frame.h" /* POS 串口端口号: * - 默认使用 E_USART_1,若实际接线不同,可在其它头文件中重定义: * #define POS_VTK_COM_ID E_USART_9 */ #ifndef POS_VTK_COM_ID #define POS_VTK_COM_ID E_USART_1 #endif /* 串口发送宏: * - 默认封装为 u16_usart_send(POS_VTK_COM_ID, ...)。 * - 若有特殊需要可以在工程其它位置重定义 POS_VTK_UART_SEND。 */ #ifndef POS_VTK_UART_SEND #define POS_VTK_UART_SEND(pData, dataLen) u16_usart_send(POS_VTK_COM_ID, (uint8_t *)(pData), (uint16_t)(dataLen)) #endif /* 获取系统毫秒节拍的回调(用于会话超时管理): * - 需在用户工程中实现,例如调用 get_current_millis() 或 HAL_GetTick()。 */ extern U32_T pos_vtk_get_tick_ms(void); /* 会话状态 */ typedef enum { POS_VTK_STATE_IDLE = 0, POS_VTK_STATE_PREAUTH_PENDING, POS_VTK_STATE_PREAUTH_OK, POS_VTK_STATE_CHARGING, POS_VTK_STATE_SETTLE_PENDING, POS_VTK_STATE_DONE, POS_VTK_STATE_ERROR } POS_VTK_STATE_E; typedef struct { POS_VTK_STATE_E e_state; U32_T opNumber; /* VTK Operation number */ U32_T preAuthAmount; /* 预扣金额(分) */ U32_T finalAmount; /* 结算金额(分) */ VTK_POS_RESULT_E e_lastResult; /* 最近一次 POS 返回结果 */ U32_T lastUpdateTick; /* 最近状态更新时间(ms) */ } POS_VTK_SESSION_T; /* 初始化 POS-VTK 服务(需在系统启动时调用一次) */ void pos_vtk_init(void); /* 充电前启动预扣款流程(CDP) * @param[in] gunNo 枪号(0 ~ GUN_MAX_CNT-1) * @param[in] amountMinor 预扣款金额(单位:分,例如 5000 = 50.00 元) * @return U8_T 1=请求已发送;0=参数或状态不允许 * * 使用示例: * // 系统启动时 * pos_vtk_init(); * * // 串口接收中断中逐字节喂入 * void UART_POS_Rx_IRQHandler_Byte(U8_T byte) * { * pos_vtk_on_rx_byte(byte); * } * * // 用户启动充电时(以枪0为例),预扣 50 元 * if (!pos_vtk_start_preauth(0, 5000U)) * { * // 预扣请求未正确发送,视为支付失败 * } * * // 后台任务轮询会话状态 * POS_VTK_SESSION_T sess; * pos_vtk_get_session(0, &sess); * if (sess.e_state == POS_VTK_STATE_PREAUTH_OK && * sess.e_lastResult == VTK_POS_RESULT_APPROVED) * { * // 预扣款成功,可以进入充电流程 * } */ U8_T pos_vtk_start_preauth(U8_T gunNo, U32_T amountMinor); /* 充电结束后通知进行结算(CRD) * @param[in] gunNo 枪号 * @param[in] amountMinor 实际消费金额(单位:分) * @return U8_T 1=结算请求已发送;0=状态不允许 * * 使用示例: * // 计费模块算出本次消费 42 元(含服务费等) * if (!pos_vtk_notify_charge_end(0, 4200U)) * { * // 结算请求未正确发送,记录异常 * } * * // 稍后轮询 * POS_VTK_SESSION_T sess; * pos_vtk_get_session(0, &sess); * if (sess.e_state == POS_VTK_STATE_DONE && * sess.e_lastResult == VTK_POS_RESULT_APPROVED) * { * // 结算成功,写订单、上报平台 * } * else if (sess.e_state == POS_VTK_STATE_ERROR) * { * // 结算失败,记录失败原因,可提示人工干预 * } */ U8_T pos_vtk_notify_charge_end(U8_T gunNo, U32_T amountMinor); /* 串口接收入口(逐字节喂入),通常在 UART 接收中断或接收任务中调用 * @param[in] byte UART 接收到的 1 字节数据 * * 示例1(使用中断逐字节喂入,需自行从 HAL/usart 中读取 1 字节): * void UART_POS_IRQHandler(void) * { * U8_T byte; * if (UART_ReadByte(&byte)) * { * pos_vtk_on_rx_byte(byte); * } * } * * 示例2(使用 u16_usart_recv 轮询读取): * void POS_VTK_PollRecv_Task(void) * { * U8_T rxBuf[64]; * U16_T len, i; * * len = u16_usart_recv(POS_VTK_COM_ID, rxBuf, sizeof(rxBuf)); * for (i = 0; i < len; i++) * { * pos_vtk_on_rx_byte(rxBuf[i]); * } * } */ void pos_vtk_on_rx_byte(U8_T byte); /* 获取指定枪的会话状态快照,便于上层判断 POS 当前处理结果 */ void pos_vtk_get_session(U8_T gunNo, POS_VTK_SESSION_T *pOut); #ifdef __cplusplus } #endif #endif /* POS_VTK_EN */ #endif /* POS_VTK_SERVICE_H */