BOOTLOADER
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
xmodem.c
Go to the documentation of this file.
1 /******************************************************
2 * Function: Xmodem protocol for image download through
3 * rs232
4 *
5 * File: xmodem.c
6 * Author: Book Chen
7 * Date: 2008.07.18
8 *******************************************************
9 */
10 #include "includes.h"
11 
12 #define XmodemIdleState 0
13 #define XmodemRxState0 1
14 #define XmodemRxState1 2
15 #define XmodemRxState2 3
16 
17 #define XmodemSohSubstate 0
18 #define XmodemBlockNumberSubstate 1
19 #define XmodemBlockNumber2Substate 2
20 #define XmodemDataSubstate 3
21 
22 #define XMODEM_DOWNLOAD_ADDRESS IMAGE_ADDRESS
24 
25 void F_XmodemInit(void);
26 void F_XmodemSvc(void);
34 
35 void F_XmodemInit(void){
36  XmodemCtrl.Id=ID_XMODEM;
37  XmodemCtrl.InUse=FALSE;
38  XmodemCtrl.NewBlock=0;
39  XmodemCtrl.BlockNumber=1;
40  XmodemCtrl.Error=0;
41  XmodemCtrl.ErrorCount=0;
42  XmodemCtrl.ErrorCode=0;
43  XmodemCtrl.ErrorRecord=0;
44  XmodemCtrl.Buffer.Put=0;
45  XmodemCtrl.Buffer.Get=0;
46  XmodemCtrl.ByteCount=0;
47  XmodemCtrl.Timer=0;
48  XmodemCtrl.ReceiveStart=FALSE;
49  XmodemCtrl.ReceiveFinish=FALSE;
50  XmodemCtrl.pData=(INT8U *)XMODEM_DOWNLOAD_ADDRESS;
51  XmodemCtrl.State=XmodemIdleState;
52  XmodemCtrl.SubState=XmodemSohSubstate;
53 }
55  if(XmodemCtrl.InUse==TRUE) return TRUE;
56  else return FALSE;
57 }
59  if(XmodemCtrl.InUse==FALSE){
60  XmodemCtrl.InUse=TRUE;
61  XmodemCtrl.UserId=UserId;
62  return TRUE;
63  }
64  else return FALSE;
65 }
67  if((XmodemCtrl.InUse==TRUE)&&(XmodemCtrl.UserId==UserId)){
68  XmodemCtrl.InUse=FALSE;
69  return TRUE;
70  }
71  else return FALSE;
72 }
74  if((XmodemCtrl.InUse==TRUE)&&(XmodemCtrl.UserId==UserId)){
75  XmodemCtrl.State=XmodemRxState0;
76  return TRUE;
77  }
78  else return FALSE;
79 }
80 BOOL F_XmodemStatusCheck(void){ // xmodem busy check
81  if(XmodemCtrl.State==XmodemIdleState) return TRUE;
82  else return FALSE;
83 }
85  if((XmodemCtrl.InUse!=TRUE)||(XmodemCtrl.UserId!=UserId)) return FALSE;
86  XmodemCtrl.NewBlock=0;
87  XmodemCtrl.BlockNumber=1;
88  XmodemCtrl.Error=0;
89  XmodemCtrl.ErrorCount=0;
90  XmodemCtrl.ErrorCode=0;
91  XmodemCtrl.ErrorRecord=0;
92  XmodemCtrl.Buffer.Put=0;
93  XmodemCtrl.Buffer.Get=0;
94  XmodemCtrl.ByteCount=0;
95  XmodemCtrl.TotalBlockCount=0;
96  XmodemCtrl.Timer=0;
97  XmodemCtrl.ReceiveStart=FALSE;
98  XmodemCtrl.ReceiveFinish=FALSE;
99  XmodemCtrl.pData=(INT8U *)XMODEM_DOWNLOAD_ADDRESS;
100  XmodemCtrl.State=XmodemIdleState;
101  XmodemCtrl.SubState=XmodemSohSubstate;
102  return TRUE;
103 }
105  INT16U Crc16,DataCrc16;
106  INT8U ByteCount;
107  INT8U i;
108 
109  Crc16=0;
110  DataCrc16=0;
111  ByteCount=128;
112  while(ByteCount--){
113  Crc16=Crc16^((INT16U)*pData++<<8);
114  for(i=0;i<8;i++){
115  if(Crc16&0x8000) Crc16=(Crc16<<1)^0x1021;
116  else Crc16=Crc16<<1;
117  }
118  }
119  DataCrc16=(*pData++)*0x100;
120  DataCrc16+=*pData;
121  if(DataCrc16==Crc16) return TRUE;
122  else return FALSE;
123 }
124 void F_XmodemSvc(void){
125  INT8U Data;
126  INT8U i;
127 
128  if(XmodemCtrl.InUse==FALSE) return; // not in use...no run
129  switch(XmodemCtrl.State){
130  case XmodemIdleState:
131  break;
132  case XmodemRxState0:
133  F_XmodemRxReset(XmodemCtrl.UserId);
134  XmodemCtrl.State=XmodemRxState1;
135  break;
136  case XmodemRxState1:
137  if((XmodemCtrl.Timer==0)&&(XmodemCtrl.ReceiveStart==FALSE)){ // xmodem start condition
139  while(F_Uart0TxBufferCheck()!=UART0_BUFFER_EMPTY) F_Uart0Svc(); // for uart tx
140  while(Uart0Ctrl.UartTxTransmit==1) F_Uart0Svc();
141  XmodemCtrl.Timer=10000; //10000*0.3ms=3sec
142  }
143  //else if((XmodemCtrl.Timer==0)&&(XmodemCtrl.ReceiveStart==TRUE)){ // time out to restart
144  // F_Uart0TxBufferPut(XMODEM_NAK);
145  // F_XmodemRxReset(XmodemCtrl.UserId);
146  // break;
147  //}
149  //while(F_Uart0RxBufferCheck()!=UART0_BUFFER_EMPTY){
150  XmodemCtrl.Timer=300000; // 300000*1ms=90sec
151  while(1){
153  if(XmodemCtrl.Timer==0) break; // xmodem transfer time out
154  Data=F_Uart0RxBufferGet();
155  if( XmodemCtrl.ReceiveStart==FALSE){ // wait until SOH is received
156  if(Data==XMODEM_SOH) XmodemCtrl.ReceiveStart=TRUE;
157  else continue;
158  }
159  switch(XmodemCtrl.SubState){
160  case XmodemSohSubstate:
161  if(Data==XMODEM_SOH) XmodemCtrl.SubState=XmodemBlockNumberSubstate;
162  else if(Data==XMODEM_EOT) XmodemCtrl.ReceiveFinish=TRUE;
163  else if(Data==XMODEM_ETB) XmodemCtrl.ReceiveFinish=TRUE;
164  else if(Data==XMODEM_CAN){ // force receiver to send 'C'
166  while(F_Uart0TxBufferCheck()!=UART0_BUFFER_EMPTY) F_Uart0Svc(); // for usrt tx
167  while(Uart0Ctrl.UartTxTransmit==1) F_Uart0Svc();
168  }
169  else{
170  XmodemCtrl.Error=1;
171  XmodemCtrl.ErrorCode=1;
172  XmodemCtrl.ErrorRecord=Data;
173  }
174  break;
176  if(Data==XmodemCtrl.BlockNumber) XmodemCtrl.SubState=XmodemBlockNumber2Substate;
177  else{
178  XmodemCtrl.Error=1;
179  XmodemCtrl.ErrorCode=2;
180  }
181  break;
183  if(Data==(0xff-XmodemCtrl.BlockNumber)){
184  XmodemCtrl.SubState=XmodemDataSubstate;
185  XmodemCtrl.Buffer.Put=0;
186  }
187  else{
188  XmodemCtrl.Error=1;
189  XmodemCtrl.ErrorCode=3;
190  }
191  break;
192  case XmodemDataSubstate:
193  if(XmodemCtrl.Buffer.Put<130){ // 128 data byte + 2 crc byte
194  XmodemCtrl.Buffer.Data[XmodemCtrl.Buffer.Put]=Data;
195  XmodemCtrl.Buffer.Put++;
196  if(XmodemCtrl.Buffer.Put==130){
197  XmodemCtrl.NewBlock=1;
198  }
199  }
200  break;
201  }
202  if(XmodemCtrl.NewBlock==1) break;
203  if(XmodemCtrl.Error==1) break;
204  }
205  if(XmodemCtrl.NewBlock==1){
206  XmodemCtrl.Timer=300000;
207  XmodemCtrl.NewBlock=0;
209  while(F_Uart0TxBufferCheck()!=UART0_BUFFER_EMPTY) F_Uart0Svc(); // for usrt tx
210  while(Uart0Ctrl.UartTxTransmit==1) F_Uart0Svc();
211  if(F_XmodemCrcCheck(XmodemCtrl.Buffer.Data)==TRUE){
212  XmodemCtrl.BlockNumber++;
213  XmodemCtrl.TotalBlockCount++;
214  XmodemCtrl.ByteCount+=128;
215  for(i=0;i<128;i++) *XmodemCtrl.pData++=XmodemCtrl.Buffer.Data[i];
216  XmodemCtrl.SubState=XmodemSohSubstate;
217  }
218  else{
219  XmodemCtrl.Error=1;
220  XmodemCtrl.ErrorCode=4;
221  }
222  }
223  if(XmodemCtrl.Error==1){
224  //XmodemCtrl.ErrorCount++;
226  while(F_Uart0TxBufferCheck()!=UART0_BUFFER_EMPTY) F_Uart0Svc(); // for usrt tx
227  while(Uart0Ctrl.UartTxTransmit==1) F_Uart0Svc();
228  XmodemCtrl.State=XmodemIdleState;
229  break;
230 
231  }
232  if(XmodemCtrl.ErrorCount==100){
233  XmodemCtrl.ByteCount=0;
234  XmodemCtrl.State=XmodemIdleState;
235  }
236  if(XmodemCtrl.ReceiveFinish==TRUE){
237  XmodemCtrl.State=XmodemIdleState;
238  XmodemCtrl.SubState=XmodemSohSubstate;
239  }
240  if((XmodemCtrl.State==XmodemIdleState)||( XmodemCtrl.Timer==0)) break;
241  }
242  break;
243  default:
244  break;
245  }
246 }
247