dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
op_dfu.c
Go to the documentation of this file.
1 
15 /*
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24  * for more details.
25  *
26  * You should have received a copy of the GNU General Public License along
27  * with this program; if not, see <http://www.gnu.org/licenses/>
28  */
29 
30 /* Includes ------------------------------------------------------------------*/
31 #include "pios.h"
32 #include "op_dfu.h"
33 #include "pios_bl_helper.h"
34 #include "pios_com_msg.h"
35 #include <pios_board_info.h>
36 //programmable devices
38 uint8_t numberOfDevices = 0;
39 
40 DFUProgType currentProgrammingDestination; //flash, flash_trough spi
44 
45 uint8_t Buffer[64];
46 uint8_t echoBuffer[64];
47 uint8_t SendBuffer[64];
48 uint8_t Command = 0;
49 uint8_t EchoReqFlag = 0;
50 uint8_t EchoAnsFlag = 0;
51 uint8_t StartFlag = 0;
52 uint32_t Aditionals = 0;
53 uint32_t SizeOfTransfer = 0;
54 uint32_t Expected_CRC = 0;
55 uint8_t SizeOfLastPacket = 0;
56 uint32_t Next_Packet = 0;
57 uint8_t TransferType;
58 uint32_t Count = 0;
59 uint32_t Data;
60 uint8_t Data0;
61 uint8_t Data1;
62 uint8_t Data2;
63 uint8_t Data3;
64 uint8_t offset = 0;
65 uint32_t aux;
66 //Download vars
67 uint32_t downSizeOfLastPacket = 0;
68 uint32_t downPacketTotal = 0;
69 uint32_t downPacketCurrent = 0;
71 /* Extern variables ----------------------------------------------------------*/
72 extern DFUStates DeviceState;
73 extern uint8_t JumpToApp;
74 /* Private function prototypes -----------------------------------------------*/
75 /* Private functions ---------------------------------------------------------*/
76 void sendData(uint8_t * buf, uint16_t size);
77 uint32_t CalcFirmCRC(void);
78 
80  if ((DeviceState == downloading)) {
81 
82  uint8_t packetSize;
83  uint32_t offset;
84  uint32_t partoffset;
85  SendBuffer[0] = 0x01;
86  SendBuffer[1] = Download;
87  SendBuffer[2] = downPacketCurrent >> 24;
88  SendBuffer[3] = downPacketCurrent >> 16;
89  SendBuffer[4] = downPacketCurrent >> 8;
92  packetSize = downSizeOfLastPacket;
93  } else {
94  packetSize = 14;
95  }
96  for (uint8_t x = 0; x < packetSize; ++x) {
97  partoffset = (downPacketCurrent * 14 * 4) + (x * 4);
98  offset = baseOfAdressType(downType) + partoffset;
99  if (!flash_read(SendBuffer + (6 + x * 4), offset,
102  }
103  }
107  Aditionals = (uint32_t) Download;
108  }
109  sendData(SendBuffer + 1, 63);
110  }
111 }
112 void processComand(uint8_t *xReceive_Buffer) {
113 
114  Command = xReceive_Buffer[COMMAND];
115 #ifdef DEBUG_SSP
116  char str[63]= {0};
117  sprintf(str,"Received COMMAND:%d|",Command);
119 #endif
120  EchoReqFlag = (Command >> 7);
121  EchoAnsFlag = (Command >> 6) & 0x01;
122  StartFlag = (Command >> 5) & 0x01;
123  Count = xReceive_Buffer[COUNT] << 24;
124  Count += xReceive_Buffer[COUNT + 1] << 16;
125  Count += xReceive_Buffer[COUNT + 2] << 8;
126  Count += xReceive_Buffer[COUNT + 3];
127 
128  Data = xReceive_Buffer[DATA] << 24;
129  Data += xReceive_Buffer[DATA + 1] << 16;
130  Data += xReceive_Buffer[DATA + 2] << 8;
131  Data += xReceive_Buffer[DATA + 3];
132  Data0 = xReceive_Buffer[DATA];
133  Data1 = xReceive_Buffer[DATA + 1];
134  Data2 = xReceive_Buffer[DATA + 2];
135  Data3 = xReceive_Buffer[DATA + 3];
136  Command = Command & 0b00011111;
137 
138  if (EchoReqFlag == 1) {
139  memcpy(echoBuffer, Buffer, 64);
140  }
141  switch (Command) {
142  case EnterDFU:
143  if (((DeviceState == BLidle) && (Data0 < numberOfDevices))
144  || (DeviceState == DFUidle)) {
145  if (Data0 > 0)
146  OPDfuIni(true);
149  currentDeviceCanRead = devicesTable[Data0].readWriteFlags & 0x01;
150  currentDeviceCanWrite = devicesTable[Data0].readWriteFlags >> 1
151  & 0x01;
152  currentDevice = devicesTable[Data0];
153  uint8_t result = 0;
155  case Self_flash:
156  result = PIOS_BL_HELPER_FLASH_Ini();
157  break;
159  result = true;
160  break;
161  default:
163  Aditionals = (uint16_t) Command;
164  }
165  if (result != 1) {
167  Aditionals = (uint32_t) Command;
168  }
169  }
170  break;
171  case Upload:
172  if ((DeviceState == DFUidle) || (DeviceState == uploading)) {
173  if ((StartFlag == 1) && (Next_Packet == 0)) {
176  Next_Packet = 1;
177  Expected_CRC = Data2 << 24;
178  Expected_CRC += Data3 << 16;
179  Expected_CRC += xReceive_Buffer[DATA + 4] << 8;
180  Expected_CRC += xReceive_Buffer[DATA + 5];
182 
184  * 14 * 4 + SizeOfLastPacket * 4) == true) {
186  Aditionals = (uint32_t) Command;
187  } else {
188  uint8_t result = 1;
189  if (TransferType == FW) {
191  case Self_flash:
192  result = PIOS_BL_HELPER_FLASH_Start();
193  break;
195  result = false;
196  break;
197  default:
198  break;
199  }
200  }
201  if (result != 1) {
203  Aditionals = (uint32_t) Command;
204  } else {
205 
207  }
208  }
209  } else if ((StartFlag != 1) && (Next_Packet != 0)) {
210  if (Count > SizeOfTransfer) {
212  Aditionals = Count;
213  } else if (Count == Next_Packet - 1) {
214  uint8_t numberOfWords = 14;
215  if (Count == SizeOfTransfer - 1)//is this the last packet?
216  {
217  numberOfWords = SizeOfLastPacket;
218  }
219  uint8_t result = 0;
221  case Self_flash:
222  for (uint8_t x = 0; x < numberOfWords; ++x) {
223  offset = 4 * x;
224  Data = xReceive_Buffer[DATA + offset] << 24;
225  Data += xReceive_Buffer[DATA + 1 + offset] << 16;
226  Data += xReceive_Buffer[DATA + 2 + offset] << 8;
227  Data += xReceive_Buffer[DATA + 3 + offset];
228  aux = baseOfAdressType(TransferType) + (uint32_t)(
229  Count * 14 * 4 + x * 4);
230  result = 0;
231  for (int retry = 0; retry < MAX_WRI_RETRYS; ++retry) {
232  if (result == 0) {
233  result = (FLASH_ProgramWord(aux, Data)
234  == FLASH_COMPLETE) ? 1 : 0;
235  }
236  }
237  }
238  break;
240  result = false; // No support for this for the PipX
241  break;
242  default:
243  result = 0;
244  break;
245  }
246  if (result != 1) {
248  Aditionals = (uint32_t) Command;
249  }
250 
251  ++Next_Packet;
252  } else {
254  Aditionals = Count;
255  }
256  } else {
258  Aditionals = (uint32_t) Command;
259  }
260  }
261  break;
262  case Req_Capabilities:
263  OPDfuIni(true);
264  Buffer[0] = 0x01;
266  if (Data0 == 0) {
267  Buffer[2] = 0;
268  Buffer[3] = 0;
269  Buffer[4] = 0;
270  Buffer[5] = 0;
271  Buffer[6] = 0;
272  Buffer[7] = numberOfDevices;
273  uint16_t WRFlags = 0;
274  for (int x = 0; x < numberOfDevices; ++x) {
275  WRFlags = ((devicesTable[x].readWriteFlags << (x * 2))
276  | WRFlags);
277  }
278  Buffer[8] = WRFlags >> 8;
279  Buffer[9] = WRFlags;
280  } else {
281  Buffer[2] = devicesTable[Data0 - 1].sizeOfCode >> 24;
282  Buffer[3] = devicesTable[Data0 - 1].sizeOfCode >> 16;
283  Buffer[4] = devicesTable[Data0 - 1].sizeOfCode >> 8;
284  Buffer[5] = devicesTable[Data0 - 1].sizeOfCode;
285  Buffer[6] = Data0;
286  Buffer[7] = devicesTable[Data0 - 1].BL_Version;
287  Buffer[8] = devicesTable[Data0 - 1].sizeOfDescription;
288  Buffer[9] = devicesTable[Data0 - 1].devID;
289  Buffer[10] = devicesTable[Data0 - 1].FW_Crc >> 24;
290  Buffer[11] = devicesTable[Data0 - 1].FW_Crc >> 16;
291  Buffer[12] = devicesTable[Data0 - 1].FW_Crc >> 8;
292  Buffer[13] = devicesTable[Data0 - 1].FW_Crc;
293  Buffer[14] = devicesTable[Data0 - 1].devID >> 8;
294  Buffer[15] = devicesTable[Data0 - 1].devID;
295  }
296  sendData(Buffer + 1, 63);
297  break;
298  case JumpFW:
299  if ((Data & 0xFFFF) == 0x5AFE) {
300  /* Force board into safe mode */
301  PIOS_IAP_WriteBootCount(0xFFFF);
302  }
303  FLASH_Lock();
304  JumpToApp = 1;
305  break;
306  case Reset:
307  PIOS_SYS_Reset();
308  break;
309  case Abort_Operation:
310  Next_Packet = 0;
312  break;
313 
314  case Op_END:
315  if (DeviceState == uploading) {
316  if (Next_Packet - 1 == SizeOfTransfer) {
317  Next_Packet = 0;
318  if ((TransferType != FW) || (Expected_CRC == CalcFirmCRC())) {
320  } else {
322  }
323  }
324  if (Next_Packet - 1 < SizeOfTransfer) {
325  Next_Packet = 0;
327  }
328  }
329  break;
330  case Download_Req:
331 #ifdef DEBUG_SSP
332  sprintf(str,"COMMAND:DOWNLOAD_REQ 1 Status=%d|",DeviceState);
334 #endif
335  if (DeviceState == DFUidle) {
336 #ifdef DEBUG_SSP
337  PIOS_COM_SendString(PIOS_COM_TELEM_USB,"COMMAND:DOWNLOAD_REQ 1|");
338 #endif
339  downType = Data0;
343  + downSizeOfLastPacket) == 1) {
345  Aditionals = (uint32_t) Command;
346 
347  } else {
348  downPacketCurrent = 0;
350  }
351  } else {
353  Aditionals = (uint32_t) Command;
354  }
355  break;
356 
357  case Status_Request:
358  Buffer[0] = 0x01;
359  Buffer[1] = Status_Rep;
361  Buffer[2] = Aditionals >> 24;
362  Buffer[3] = Aditionals >> 16;
363  Buffer[4] = Aditionals >> 8;
364  Buffer[5] = Aditionals;
365  } else {
366  Buffer[2] = 0;
367  Buffer[3] = ((uint16_t) Aditionals) >> 8;
368  Buffer[4] = ((uint16_t) Aditionals);
369  Buffer[5] = 0;
370  }
371  Buffer[6] = DeviceState;
372  Buffer[7] = 0;
373  Buffer[8] = 0;
374  Buffer[9] = 0;
375  sendData(Buffer + 1, 63);
378  }
379  break;
380  case Status_Rep:
381 
382  break;
383 
384  }
385  if (EchoReqFlag == 1) {
387  sendData(echoBuffer + 1, 63);
388  }
389  return;
390 }
391 void OPDfuIni(uint8_t discover) {
392  const struct pios_board_info * bdinfo = &pios_board_info_blob;
393  Device dev;
394 
397  dev.startOfUserCode = bdinfo->fw_base;
398  dev.sizeOfCode = bdinfo->fw_size;
399  dev.sizeOfDescription = bdinfo->desc_size;
400  dev.BL_Version = bdinfo->bl_rev;
401  dev.FW_Crc = CalcFirmCRC();
402  dev.devID = (bdinfo->board_type << 8) | (bdinfo->board_rev);
403  dev.devType = bdinfo->hw_type;
404  numberOfDevices = 1;
405  devicesTable[0] = dev;
406  if (discover) {
407  //TODO check other devices trough spi or whatever
408  }
409 }
411  switch (type) {
412  case FW:
413  return currentDevice.startOfUserCode;
414  break;
415  case Descript:
416  return currentDevice.startOfUserCode + currentDevice.sizeOfCode;
417  break;
418  default:
419 
420  return 0;
421  }
422 }
423 uint8_t isBiggerThanAvailable(DFUTransfer type, uint32_t size) {
424  switch (type) {
425  case FW:
426  return (size > currentDevice.sizeOfCode) ? 1 : 0;
427  break;
428  case Descript:
429  return (size > currentDevice.sizeOfDescription) ? 1 : 0;
430  break;
431  default:
432  return true;
433  }
434 }
435 
436 uint32_t CalcFirmCRC() {
438  case Self_flash:
440  break;
442  return 0;
443  break;
444  default:
445  return 0;
446  break;
447  }
448 
449 }
450 void sendData(uint8_t * buf, uint16_t size) {
452 }
453 
454 bool flash_read(uint8_t * buffer, uint32_t adr, DFUProgType type) {
455  switch (type) {
457  return false; // We should not get this for the PipX
458  break;
459  case Self_flash:
460  for (uint8_t x = 0; x < 4; ++x) {
461  buffer[x] = *PIOS_BL_HELPER_FLASH_If_Read(adr + x);
462  }
463  return true;
464  break;
465  default:
466  return false;
467  }
468 }
469 
void sendData(uint8_t *buf, uint16_t size)
Definition: op_dfu.c:450
#define MAX_WRI_RETRYS
Definition: common.h:114
uint8_t * PIOS_BL_HELPER_FLASH_If_Read(uint32_t SectorAddress)
uint8_t currentDeviceCanWrite
Definition: op_dfu.c:42
int32_t PIOS_COM_SendString(uintptr_t com_id, const char *str)
uint32_t baseOfAdressType(DFUTransfer type)
Definition: op_dfu.c:410
int32_t PIOS_COM_MSG_Send(uintptr_t com_id, const uint8_t *msg, uint16_t msg_len)
Definition: common.h:50
Device currentDevice
Definition: op_dfu.c:43
Definition: common.h:85
uint8_t Data1
Definition: op_dfu.c:61
Main PiOS header to include all the compiled in PiOS options.
uint32_t PIOS_BL_HELPER_CRC_Memory_Calc()
DFUTransfer
Definition: common.h:84
int sprintf(char *out, const char *format,...)
uint8_t Buffer[64]
Definition: op_dfu.c:45
#define BOARD_READABLE
Definition: pios_board.h:78
uint8_t EchoAnsFlag
Definition: op_dfu.c:50
void processComand(uint8_t *xReceive_Buffer)
Definition: op_dfu.c:112
uint16_t devID
Definition: op_dfu.h:43
uint32_t Aditionals
Definition: op_dfu.c:52
uint8_t Data3
Definition: op_dfu.c:63
Definition: common.h:67
Definition: common.h:70
uint8_t BL_Version
Definition: op_dfu.h:42
uint8_t Command
Definition: op_dfu.c:48
void OPDfuIni(uint8_t discover)
Definition: op_dfu.c:391
#define PIOS_COM_TELEM_USB
Definition: pios_board.h:114
uint32_t Next_Packet
Definition: op_dfu.c:56
#define BOARD_WRITABLE
Definition: pios_board.h:79
const struct pios_board_info pios_board_info_blob
Definition: common.h:66
uint8_t isBiggerThanAvailable(DFUTransfer type, uint32_t size)
Definition: op_dfu.c:423
DeviceType devType
Definition: op_dfu.h:44
uint32_t aux
Definition: op_dfu.c:65
uint32_t downPacketCurrent
Definition: op_dfu.c:69
uint8_t EchoReqFlag
Definition: op_dfu.c:49
uint32_t downSizeOfLastPacket
Definition: op_dfu.c:67
uint8_t SizeOfLastPacket
Definition: op_dfu.c:55
uint32_t downPacketTotal
Definition: op_dfu.c:68
uint32_t FW_Crc
Definition: op_dfu.h:45
uint32_t startOfUserCode
Definition: op_dfu.h:39
#define DATA
Definition: op_dfu.h:53
DFUTransfer downType
Definition: op_dfu.c:70
DFUProgType
Definition: common.h:100
DFUProgType currentProgrammingDestination
Definition: op_dfu.c:40
COM MSG layer functions header.
This file contains the DFU commands handling code.
int32_t PIOS_SYS_Reset(void)
uint8_t numberOfDevices
Definition: op_dfu.c:38
uint8_t currentDeviceCanRead
Definition: op_dfu.c:41
uint32_t SizeOfTransfer
Definition: op_dfu.c:53
Definition: op_dfu.h:36
uint8_t programmingType
Definition: op_dfu.h:37
bool flash_read(uint8_t *buffer, uint32_t adr, DFUProgType type)
Definition: op_dfu.c:454
uint8_t JumpToApp
Definition: main.c:62
uint32_t Data
Definition: op_dfu.c:59
#define COUNT
Definition: op_dfu.h:52
uint8_t type
DFUStates DeviceState
Definition: main.c:60
uint32_t Count
Definition: op_dfu.c:58
uint32_t Expected_CRC
Definition: op_dfu.c:54
DFUStates
Definition: common.h:42
uint8_t offset
Definition: op_dfu.c:64
uint32_t CalcFirmCRC(void)
Definition: op_dfu.c:436
uint8_t TransferType
Definition: op_dfu.c:57
Definition: common.h:43
void PIOS_IAP_WriteBootCount(uint16_t)
Definition: pios_iap.c:98
uint8_t StartFlag
Definition: op_dfu.c:51
Definition: common.h:69
uint8_t SendBuffer[64]
Definition: op_dfu.c:47
#define COMMAND
Definition: op_dfu.h:51
uint32_t sizeOfCode
Definition: op_dfu.h:40
uint8_t sizeOfDescription
Definition: op_dfu.h:41
uint8_t Data0
Definition: op_dfu.c:60
Device devicesTable[10]
Definition: op_dfu.c:37
uint8_t PIOS_BL_HELPER_FLASH_Ini()
uint8_t PIOS_BL_HELPER_FLASH_Start()
DownloadAction
Definition: common.h:34
uint8_t readWriteFlags
Definition: op_dfu.h:38
uint8_t echoBuffer[64]
Definition: op_dfu.c:46
void DataDownload(DownloadAction action)
Definition: op_dfu.c:79
uint8_t Data2
Definition: op_dfu.c:62