*源文件
@bef WTO file
*/
#include <stdio.h>
#include "A31G12x_int.h"
#include "A31G12x_usart1n.h"
#include "A31G12x_pcu.h"
#include "Wto_uart.h"
#include "Wto_Time.h"
#include "flash.h"
extern void Delay_ms(uint16_t t_ms);
uint8_t Rxbuffer[RX_BUFFER_SIZE];
uint8_t Txbuffer[RX_BUFFER_SIZE];
uint8_t rxStates = TO_START;
//定义与初始化
UartHandle Usart11_Handle ={
.RxHead = 0,
.Rxtail = 0,
.RxStatus = 0,
.RxSize = 0,
.RxBuf = Rxbuffer,
.TxHead = 0,
.Txtail = 0,
.RxSize = 0,
.TxStatus = 0,
.TxBuf = Txbuffer,
};
void USART11_Receive_Data(void);
void USART11_Init(void);
struct __FILE { int handle; /* Add whatever needed */ };
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f)
{
while( UST_CheckBusy(USART11));
UST_SendByte(USART11,ch);
return(ch);
}
/*****************************************************************************************/
/* 串口USART */
/*****************************************************************************************/
void USART11_Init(void)
{
UST_CFG_Type USTConfigStruct;
PCU_SetDirection(PD, 3, ALTERN_FUNC);
PCU_ConfigureFunction(PD, 3, FUNC1);
PCU_ConfigurePullupdown(PD,3, ENPU);
PCU_SetDirection(PD, 2, ALTERN_FUNC);
PCU_ConfigureFunction(PD, 2, FUNC1);
// 115200-8-无-1
USTConfigStruct.Mode = UST_UART_MODE;
USTConfigStruct.Baud_rate = 115200;
USTConfigStruct.Databits = UST_DATABIT_8;
USTConfigStruct.Parity = UST_PARITY_NONE;
USTConfigStruct.Stopbits = UST_STOPBIT_1;
UST_Init(USART11, &USTConfigStruct);
UST_IntConfig((USART1n_Type *)USART11, UST_INTCFG_RXC, ENABLE);
NVIC_SetPriority(USART11_IRQn, 3);
NVIC_EnableIRQ(USART11_IRQn);
EInt_MaskDisable(UST11_MASK);
UST_Enable(USART11, ENABLE);
__enable_irq();
}
void USART11_Handler(void)
{
uint32_t intsrc, tmp;
intsrc = UST_GetStatus(USART11);
tmp = intsrc & UST_SR_BITMASK;
if ((tmp & UST_SR_RXC) == UST_SR_RXC)
{
USART11_Receive_Data();
}
if ((tmp & UST_SR_TXC) == UST_SR_TXC)
{
// UST_ClearStatus(USART11, UST_STATUS_TXC);
}
}
void USART11_Receive_Data(void)
{
uint8_t date;
uint32_t rLen;
while(1)
{
rLen = UST_Receive((USART1n_Type *)USART11, &date, 1, NONE_BLOCKING);
if (rLen)
{
if( 0== Usart11_Handle.RxSize ){
Usart11_Handle.RxHead = 0;
Usart11_Handle.Rxtail = 0;
}
Usart11_Handle.RxBuf[ Usart11_Handle.Rxtail] = date;
Usart11_Handle.Rxtail++;
if( ++Usart11_Handle.RxSize >= RX_BUFFER_SIZE )
{
Usart11_Handle.RxSize = RX_BUFFER_SIZE;
if( ++Usart11_Handle.RxHead >= RX_BUFFER_SIZE ){
Usart11_Handle.RxHead = 0;
}
}
Usart11_Handle.RxStatus = IS_BUSY; // receive data now
Usart11_Handle.RxTim = GetTickSystemTime();
}
else
{
break;
}
}
}
//获取uart的接收状态
uint8_t GetUartRxStatus( void )
{
uint32_t ticknow = GetTickSystemTime();
if( Usart11_Handle.RxStatus == IS_BUSY )
{
if( ticknow > Usart11_Handle.RxTim )
{
if( ( ticknow - Usart11_Handle.RxTim ) >= 30 ) //30ms
{
Usart11_Handle.RxStatus = IS_IDLE;
}
} else {
if( ( ( 0xffffffff - Usart11_Handle.RxTim ) + ticknow ) >= 30 )
{
Usart11_Handle.RxStatus = IS_IDLE;
}
}
}
return Usart11_Handle.RxStatus;
}
void UartSendCmd(uint8_t Cmd)
{
UST_Send(USART11, &Cmd, 1, BLOCKING);
}
// 使用XModem多项式而不是Modbus多项式
// CRC算法名称 多项式公式 宽度 多项式 初始值 结果异或值 输入反转 输出反转
// CRC-16/XMODEM x16 + x12 + x5 + 1 16 0x1021 0000 0000 false false
uint16_t XModem_Crc16(const uint8_t *buffer, uint16_t len)
{
uint16_t polynom = 0x1021; // XModem_CRC多项式
uint8_t i;
uint16_t crc16 = 0x0000;
if (len == 0)
{
return ERROR;
}
while (len--)
{
crc16 ^= ((*buffer) << 8);
for (i = 0; i < 8; i++)
{
if (crc16 & 0x8000)
{
crc16 <<= 1;
crc16 ^= polynom;
}
else
{
crc16 <<= 1;
}
}
buffer++;
}
return crc16;
}
void UsartReceiveHandle(void)
{
extern uint16_t do_crc(uint16_t reg_init,uint8_t* data,uint16_t length);
static uint8_t rxBuf[RX_BUFFER_SIZE] = {0};
static uint8_t rxBuf_OK[128] = {0};
static uint16_t CurrentRxSize = 0;
static uint16_t receiveNum = 0; //计数接收数量
static uint8_t receiveFlag = 0; //接收数据标志
uint16_t crc16Check =0;
uint16_t i;
uint8_t chekL,chekH;
uint32_t Tcnt =0;
static uint32_t Tcnlast =0;
static uint16_t TimerTriggle = 10000;
if( GetUartRxStatus( ) == IS_IDLE ) //判断接收为空闲30ms时,认为接收完数据
{
if( Usart11_Handle.RxSize )
{
printf("Rdata[");
for(i=0; i< Usart11_Handle.RxSize; i++ ){
rxBuf[i] = Usart11_Handle.RxBuf[i];
printf("%02x ", rxBuf[i]);
}
printf("]\n");
// printf("dataSize:%02d\n",Usart11_Handle.RxSize);
CurrentRxSize = Usart11_Handle.RxSize;
for(i =0;i< 128;i++)
{
rxBuf_OK[i] = rxBuf[i+3];
}
Usart11_Handle.RxSize = 0;
Usart11_Handle.RxHead = 0;
Usart11_Handle.Rxtail = 0;
}
crc16Check = XModem_Crc16(&rxBuf_OK[0],128);
chekH = (uint8_t)(crc16Check >> 8);
chekL = (uint8_t)crc16Check ;
if( rxBuf[0] == SOH ) //128字节一包数据
{
if((rxBuf[1] == 0x00) && (rxBuf[2] ==(uint8_t)(~rxBuf[1])) && (rxStates == TO_START ) && ( chekH == rxBuf[CurrentRxSize-2])&&(chekL == rxBuf[CurrentRxSize-1]))
{
rxStates = TO_RECEIVE_DATA; //开始状态,第一包数据
UartSendCmd(ACK);
Delay_ms(500);//等电压稳定
UartSendCmd(CCC);
receiveNum = 0;
printf("start first pack OK \n");
}
else if( (rxBuf[2] ==(uint8_t)(~rxBuf[1])) && (rxStates == TO_RECEIVE_DATA) && (receiveFlag == 0))
{
FlashPageWrite(80+receiveNum,(uint8_t *)rxBuf_OK); //10K开始写
++receiveNum;
printf(" rx data OK \n");
receiveFlag = 1;
// UartSendCmd(ACK);
}
}
else if( rxBuf[0] == STX )//1024字节一包数据
{
}
else if(rxBuf[0] == EOT) //通讯结束
{
if(rxStates == TO_RECEIVE_DATA)
{
UartSendCmd(ACK);
rxStates = TO_START;
receiveFlag = 0;
}
receiveNum = 0;
}
}
Tcnt = GetTickSystemTime();
if((uint32_t)( Tcnt - Tcnlast ) > TimerTriggle )
{
Tcnlast = Tcnt;
if(rxStates != TO_RECEIVE_DATA)
{
UartSendCmd(CCC); //10秒请求主机发送一次
receiveFlag = 0 ;
TimerTriggle = 10000;
}
else{
if(receiveFlag && rxStates == TO_RECEIVE_DATA ){
receiveFlag = 0;
UartSendCmd(ACK);
TimerTriggle = 500;
}
}
}
}
头文件--------------------------------------
#ifndef _WTO_UART_H_
#define _WTO_UART_H_
#define SOH 0x01
#define STX 0x02
#define ACK 0x06
#define NACK 0x15
#define EOT 0x04
#define CCC 0x43
/* 升级的步骤 */
enum UPDATE_STATE
{
TO_START = 0x01,
TO_RECEIVE_DATA = 0x02,
TO_RECEIVE_EOT1 = 0x03,
TO_RECEIVE_EOT2 = 0x04,
TO_RECEIVE_END = 0x05
};
#define PACKET_HEADER (3)
#define PACKET_TRAILER (2)
#define PACKET_OVERHEAD (PACKET_HEADER + 128 + PACKET_TRAILER )
#define PACKET_SIZE (128)
#define PACKET_1K_SIZE (1024)
#define RX_BUFFER_SIZE (( PACKET_SIZE + PACKET_OVERHEAD ) * 2 ) //133*2=266 Bytes
#define IS_IDLE 0
#define IS_BUSY 1
typedef struct{
uint16_t RxHead;
uint16_t Rxtail;
uint16_t RxSize;
uint32_t RxTim;
uint8_t RxStatus;
uint8_t *RxBuf;
uint16_t TxHead;
uint16_t Txtail;
uint16_t TxSize;
uint8_t TxStatus;
uint8_t *TxBuf;
}UartHandle;
extern void USART11_Init(void);
extern uint8_t GetUartRxStatus(void);
extern void UsartReceiveHandle(void);
#endif