|
@@ -0,0 +1,717 @@
|
|
|
|
+#include <stdio.h>
|
|
|
|
+#include <string.h>
|
|
|
|
+#include <ctype.h>
|
|
|
|
+#include <errno.h>
|
|
|
|
+#include <unistd.h>
|
|
|
|
+#include <gfaserial.h>
|
|
|
|
+#include <byteswap.h>
|
|
|
|
+#include <gfabootlmast.h>
|
|
|
|
+#include "bl_commands.h"
|
|
|
|
+
|
|
|
|
+#ifdef _TARGET_BUILD
|
|
|
|
+#define _DEVICE_NAME "/dev/ttyO4"
|
|
|
|
+#else
|
|
|
|
+#define _DEVICE_NAME "/dev/tty0"
|
|
|
|
+#endif // _TARGET_BUILD
|
|
|
|
+
|
|
|
|
+#define _SLAVE_NODE_ADDR 0xFF
|
|
|
|
+#define _BL_MATERIAL "G.Z.40015 P01"
|
|
|
|
+#define _BL_SERIAL "18-080015 1409" // "012345678901234"
|
|
|
|
+
|
|
|
|
+#define TRACE(...) printf(__VA_ARGS__), fflush(stdout)
|
|
|
|
+
|
|
|
|
+#if 0
|
|
|
|
+#define TRACE_FRAME(f) GfaMininetMasterDumpFrame(stdout, f)
|
|
|
|
+#else
|
|
|
|
+#define TRACE_FRAME(f)
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#define _countof(a) (sizeof(a) / sizeof(*a))
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+#define GFA_APP_BOOTLOADER_START_ADDRESS ((uint32_t)0x00000000)
|
|
|
|
+#define GFA_APP_APPLICATION_START_ADDRESS ((uint32_t)0x00002000)
|
|
|
|
+#define GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH 16 // including the zero terminator
|
|
|
|
+#define GFA_APP_MAX_IMG_NAME_BUILD_LENGTH 24 // including the zero terminator
|
|
|
|
+#define GFA_APP_IMG_HEADER_PREFIX_0 ((uint32_t)0xFF01FF02)
|
|
|
|
+#define GFA_APP_IMG_HEADER_PREFIX_1 ((uint32_t)0xFF03FF04)
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+typedef struct _GFA_APP_IMG_HEADER
|
|
|
|
+{
|
|
|
|
+ const uintptr_t nPrefix0;
|
|
|
|
+ const uintptr_t nPrefix1;
|
|
|
|
+ const uintptr_t nImgLength;
|
|
|
|
+ const uintptr_t nImgCRC32;
|
|
|
|
+ const uintptr_t nReserved[4];
|
|
|
|
+ union
|
|
|
|
+ {
|
|
|
|
+ struct
|
|
|
|
+ {
|
|
|
|
+ const char * const pszImgMaterialNum;
|
|
|
|
+ const char * const pszImgNameBuild;
|
|
|
|
+ }app;
|
|
|
|
+ struct
|
|
|
|
+ {
|
|
|
|
+ const char szImgMaterialNum[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH];
|
|
|
|
+ const char szImgNameBuild[GFA_APP_MAX_IMG_NAME_BUILD_LENGTH];
|
|
|
|
+ }bl;
|
|
|
|
+ };
|
|
|
|
+}GFA_APP_IMG_HEADER, *LPGFA_APP_IMG_HEADER;
|
|
|
|
+typedef const GFA_APP_IMG_HEADER *LPCGFA_APP_IMG_HEADER;
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+static ssize_t _DataPayloadFromMininetFrame(LPCGFA_MININET_FRAME pFrame, void *pData, size_t nCbData)
|
|
|
|
+{
|
|
|
|
+ if(pFrame && pData && nCbData)
|
|
|
|
+ {
|
|
|
|
+ if(pFrame->len > 6)
|
|
|
|
+ {
|
|
|
|
+ size_t nDatalen = (size_t)pFrame->len - 6;
|
|
|
|
+
|
|
|
|
+ if(nDatalen <= nCbData)
|
|
|
|
+ {
|
|
|
|
+ memcpy(pData, &pFrame->data.by[1], nDatalen);
|
|
|
|
+ return (ssize_t)nDatalen;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+static ssize_t _PollBlData(HGFAMINEMST hMst, void *pData, size_t nCbData, uint32_t nTimeoutMS)
|
|
|
|
+{
|
|
|
|
+ if(hMst && pData && nCbData)
|
|
|
|
+ {
|
|
|
|
+ size_t s, nReceived = 0;
|
|
|
|
+ struct timeval tvRX;
|
|
|
|
+ ssize_t nRet = -1;
|
|
|
|
+ uint8_t cmd[32];
|
|
|
|
+ uint8_t txb[32];
|
|
|
|
+ uint8_t rxb[512];
|
|
|
|
+ uint8_t *pszData = (uint8_t*)pData;
|
|
|
|
+ tvRX.tv_sec = nTimeoutMS / 1000;
|
|
|
|
+ tvRX.tv_usec = (nTimeoutMS % 1000) * 1000;
|
|
|
|
+
|
|
|
|
+ GfaMininetMasterSaveTimeouts(hMst);
|
|
|
|
+ GfaMininetMasterSetTimeouts(hMst, &tvRX, NULL);
|
|
|
|
+
|
|
|
|
+ while(nReceived < nCbData)
|
|
|
|
+ {
|
|
|
|
+ s = GfaBLM_BuildCmdDataPacket("BU", NULL, 0, cmd, sizeof(cmd), true);
|
|
|
|
+ nRet = GfaMininetMasterBuildFrame(hMst, _SLAVE_NODE_ADDR, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nRet)) <= 0)
|
|
|
|
+ {
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), true)) > 0)
|
|
|
|
+ {
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, _SLAVE_NODE_ADDR, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)rxb);
|
|
|
|
+
|
|
|
|
+ if((nRet = _DataPayloadFromMininetFrame((LPCGFA_MININET_FRAME)rxb, pszData, nCbData - nReceived)) > 0)
|
|
|
|
+ {
|
|
|
|
+ pszData += nRet;
|
|
|
|
+ nReceived += nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ TRACE("\nACK ...\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ nReceived = nRet;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ GfaMininetMasterRestoreTimeouts(hMst);
|
|
|
|
+ return nReceived;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int _BlPing(HGFAMINEMST hMst)
|
|
|
|
+{
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ uint8_t nCmd = COMMAND_PING;
|
|
|
|
+ char txb[32], rxb[32], cmd[8], ack[2];
|
|
|
|
+
|
|
|
|
+ size_t s = GfaBLM_BuildCmdDataPacket("BU", &nCmd, 1, cmd, sizeof(cmd), true);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(hMst, _SLAVE_NODE_ADDR, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)txb);
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nLen)) < nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, _SLAVE_NODE_ADDR, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
|
|
|
|
+ (nRet == MINET_SLAVE_RESPONSE_ACK))
|
|
|
|
+ {
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)rxb);
|
|
|
|
+ if((nRet = _DataPayloadFromMininetFrame((LPCGFA_MININET_FRAME)rxb, ack, 2)) != 2)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if((nRet = _PollBlData(hMst, ack, 2, 200)) != 2)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(ack[0] == 0)
|
|
|
|
+ {
|
|
|
|
+ return (ack[1] == COMMAND_ACK);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int _BlGetStatus(HGFAMINEMST hMst, uint8_t *pbStatus)
|
|
|
|
+{
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ uint8_t nCmd = COMMAND_GET_STATUS;
|
|
|
|
+ char txb[32], rxb[32], cmd[8], ack[3], stat[3];
|
|
|
|
+
|
|
|
|
+ size_t s = GfaBLM_BuildCmdDataPacket("BU", &nCmd, 1, cmd, sizeof(cmd), true);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(hMst, _SLAVE_NODE_ADDR, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)txb);
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nLen)) < nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, _SLAVE_NODE_ADDR, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
|
|
|
|
+ (nRet == MINET_SLAVE_RESPONSE_ACK))
|
|
|
|
+ {
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)rxb);
|
|
|
|
+ if((nRet = _DataPayloadFromMininetFrame((LPCGFA_MININET_FRAME)rxb, ack, 2)) != 2)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if((nRet = _PollBlData(hMst, ack, 2, 200)) != 2)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(ack[0] == 0)
|
|
|
|
+ {
|
|
|
|
+ if(ack[1] == COMMAND_ACK)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = _PollBlData(hMst, stat, 3, 200)) != 3)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ if((stat[0] == 3) && (stat[1] == stat[2]))
|
|
|
|
+ {
|
|
|
|
+ if(pbStatus)
|
|
|
|
+ *pbStatus = stat[2];
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(hMst, _SLAVE_NODE_ADDR, 0, "BU\xCC", 3, txb, sizeof(txb));
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)txb);
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), true)) <= 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, _SLAVE_NODE_ADDR, rxb, nRet, true, &nIndex);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ // TODO!
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int _BlSetBaudrate(HGFAMINEMST hMst, uint32_t nNewBaudrate)
|
|
|
|
+{
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ size_t s;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ char txb[32], rxb[32], cmd[8];
|
|
|
|
+ uint32_t nBaudrate = bswap_32(nNewBaudrate);
|
|
|
|
+
|
|
|
|
+ s = GfaBLM_BuildCmdDataPacket("BB", &nBaudrate, sizeof(nBaudrate), cmd, sizeof(cmd), false);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(hMst, _SLAVE_NODE_ADDR, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)txb);
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, _SLAVE_NODE_ADDR, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ GFA_SER_CFG_PARAMS scp;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterGetConfigParams(hMst, &scp, sizeof(scp))) == sizeof(scp))
|
|
|
|
+ {
|
|
|
|
+ scp.baud = nNewBaudrate;
|
|
|
|
+ return GfaMininetMasterSetConfigParams(hMst, &scp, sizeof(scp));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int _BlDumpMemory(HGFAMINEMST hMst, uint32_t nAddress, uint32_t nCntDwords, void *pBuffer, size_t nCbBuffer)
|
|
|
|
+{
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ size_t s;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ char txb[32], rxb[128], cmd[10], dmp[sizeof(uint32_t) * nCntDwords];
|
|
|
|
+
|
|
|
|
+ if(nCntDwords > 16)
|
|
|
|
+ nCntDwords = 16;
|
|
|
|
+
|
|
|
|
+ if((nCntDwords * sizeof(uint32_t)) > nCbBuffer)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ struct _MEM
|
|
|
|
+ {
|
|
|
|
+ uint32_t nAddr;
|
|
|
|
+ uint32_t nCount;
|
|
|
|
+ }mem = {bswap_32(nAddress), bswap_32(nCntDwords)};
|
|
|
|
+
|
|
|
|
+ s = GfaBLM_BuildCmdDataPacket("BD", &mem, sizeof(mem), cmd, sizeof(cmd), false);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(hMst, _SLAVE_NODE_ADDR, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)txb);
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, _SLAVE_NODE_ADDR, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)rxb);
|
|
|
|
+ if((nRet = _DataPayloadFromMininetFrame((LPCGFA_MININET_FRAME)rxb, dmp, sizeof(uint32_t) * nCntDwords)) != (ssize_t)(sizeof(uint32_t) * nCntDwords))
|
|
|
|
+ return -1;
|
|
|
|
+ memcpy(pBuffer, dmp, sizeof(uint32_t) * nCntDwords);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = _PollBlData(hMst, dmp, sizeof(uint32_t) * nCntDwords, 200)) != (ssize_t)(sizeof(uint32_t) * nCntDwords))
|
|
|
|
+ return -1;
|
|
|
|
+ memcpy(pBuffer, dmp, sizeof(uint32_t) * nCntDwords);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int _BlReadMaterialAndSerial(HGFAMINEMST hMst, char *pszMaterial, size_t nCbMaterial, char *pszSerial, size_t nCbSerial)
|
|
|
|
+{
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ char txb[32], rxb[64], data[32];
|
|
|
|
+
|
|
|
|
+ if(!pszMaterial || (nCbMaterial < 16) || !pszSerial || (nCbSerial < 16))
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(hMst, _SLAVE_NODE_ADDR, 0, "BR", 2, txb, sizeof(txb));
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)txb);
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, _SLAVE_NODE_ADDR, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)rxb);
|
|
|
|
+ if((nRet = _DataPayloadFromMininetFrame((LPCGFA_MININET_FRAME)rxb, data, sizeof(data))) != sizeof(data))
|
|
|
|
+ return -1;
|
|
|
|
+ memcpy(pszMaterial, data, 16);
|
|
|
|
+ pszMaterial[15] = '\0';
|
|
|
|
+ memcpy(pszSerial, &data[16], 16);
|
|
|
|
+ pszSerial[15] = '\0';
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = _PollBlData(hMst, data, sizeof(data), 200)) != (ssize_t)sizeof(data))
|
|
|
|
+ return -1;
|
|
|
|
+ memcpy(pszMaterial, data, 16);
|
|
|
|
+ pszMaterial[15] = '\0';
|
|
|
|
+ memcpy(pszSerial, &data[16], 16);
|
|
|
|
+ pszSerial[15] = '\0';
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int _BlWriteMaterialAndSerial(HGFAMINEMST hMst, const char *pszMaterial, const char *pszSerial)
|
|
|
|
+{
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ size_t s;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ size_t nLenMaterial, nLenSerial;
|
|
|
|
+ struct _TS
|
|
|
|
+ {
|
|
|
|
+ char szMaterial[16];
|
|
|
|
+ char szSerial[16];
|
|
|
|
+ }ts;
|
|
|
|
+ char txb[64], rxb[32], cmd[64];
|
|
|
|
+
|
|
|
|
+ if(!pszMaterial || !pszSerial)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ nLenMaterial = strlen(pszMaterial);
|
|
|
|
+ nLenSerial = strlen(pszSerial);
|
|
|
|
+
|
|
|
|
+ if((nLenMaterial > 15) || (nLenSerial > 15))
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ memcpy(ts.szMaterial, pszMaterial, nLenMaterial);
|
|
|
|
+ if(nLenMaterial < 15)
|
|
|
|
+ memset(&ts.szMaterial[nLenMaterial], ' ', 15 - nLenMaterial);
|
|
|
|
+ ts.szMaterial[15] = '\0';
|
|
|
|
+
|
|
|
|
+ memcpy(ts.szSerial, pszSerial, nLenSerial);
|
|
|
|
+ if(nLenSerial < 15)
|
|
|
|
+ memset(&ts.szSerial[nLenSerial], ' ', 15 - nLenSerial);
|
|
|
|
+ ts.szSerial[15] = '\0';
|
|
|
|
+
|
|
|
|
+ s = GfaBLM_BuildCmdDataPacket("BW", &ts, sizeof(ts), cmd, sizeof(cmd), false);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(hMst, _SLAVE_NODE_ADDR, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)txb);
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, _SLAVE_NODE_ADDR, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)rxb);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int _BlExecute(HGFAMINEMST hMst)
|
|
|
|
+{
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ char txb[32], rxb[32];
|
|
|
|
+
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(hMst, _SLAVE_NODE_ADDR, 0, "BE", 2, txb, sizeof(txb));
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)txb);
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, _SLAVE_NODE_ADDR, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)rxb);
|
|
|
|
+ // TODO: application response
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int _BlIsExecuting(HGFAMINEMST hMst)
|
|
|
|
+{
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ char txb[32], rxb[32];
|
|
|
|
+
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(hMst, _SLAVE_NODE_ADDR, 0, "BU", 2, txb, sizeof(txb));
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)txb);
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, _SLAVE_NODE_ADDR, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ TRACE_FRAME((LPCGFA_MININET_FRAME)rxb);
|
|
|
|
+ // TODO: application response
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int _BlGetImgInfo(HGFAMINEMST hMst, uint32_t *pnImgLength, uint32_t *pnImgCRC32)
|
|
|
|
+{
|
|
|
|
+ if(hMst && pnImgLength && pnImgCRC32)
|
|
|
|
+ {
|
|
|
|
+ ssize_t nRet = 0;
|
|
|
|
+ int nDumpIndex = 0;
|
|
|
|
+ bool bNeedMore;
|
|
|
|
+ uint32_t i, nDumpAddr, nDumpLen, nBufLen;
|
|
|
|
+ uint32_t aDump[24] = {0};
|
|
|
|
+
|
|
|
|
+ for(i = 0; i < 257; i += 16)
|
|
|
|
+ {
|
|
|
|
+ nDumpAddr = GFA_APP_BOOTLOADER_START_ADDRESS + i * sizeof(uint32_t);
|
|
|
|
+ nBufLen = nDumpLen = 16;
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ bNeedMore = false;
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlDumpMemory(hMst, nDumpAddr, nDumpLen, &aDump[nDumpIndex], sizeof(aDump) - nDumpIndex * sizeof(uint32_t))) == 0)
|
|
|
|
+ {
|
|
|
|
+ uint32_t j;
|
|
|
|
+ LPCGFA_APP_IMG_HEADER paih;
|
|
|
|
+// TRACE("Address: %08X, Length: %2u\n", nDumpAddr, nDumpLen);
|
|
|
|
+
|
|
|
|
+ for(j = nDumpIndex; j < (nDumpLen + nDumpIndex); ++j)
|
|
|
|
+ {
|
|
|
|
+ aDump[j] = bswap_32(aDump[j]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for(j = 0; j < nBufLen; ++j)
|
|
|
|
+ {
|
|
|
|
+ paih = (LPCGFA_APP_IMG_HEADER)&aDump[j];
|
|
|
|
+
|
|
|
|
+ if(paih->nPrefix0 == GFA_APP_IMG_HEADER_PREFIX_0)
|
|
|
|
+ {
|
|
|
|
+ if(j < (nBufLen - 1))
|
|
|
|
+ {
|
|
|
|
+ if(paih->nPrefix1 == GFA_APP_IMG_HEADER_PREFIX_1)
|
|
|
|
+ {
|
|
|
|
+ if(j < (nBufLen - 3))
|
|
|
|
+ {
|
|
|
|
+ *pnImgLength = paih->nImgLength;
|
|
|
|
+ *pnImgCRC32 = paih->nImgCRC32;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ nDumpAddr += nDumpLen * sizeof(uint32_t);
|
|
|
|
+ nDumpIndex = nDumpLen;
|
|
|
|
+ nDumpLen = 2;
|
|
|
|
+ nBufLen += nDumpLen;
|
|
|
|
+ bNeedMore = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ nDumpAddr += nDumpLen * sizeof(uint32_t);
|
|
|
|
+ nDumpIndex = nDumpLen;
|
|
|
|
+ nDumpLen = 3;
|
|
|
|
+ nBufLen += nDumpLen;
|
|
|
|
+ bNeedMore = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ while(bNeedMore);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int main(void)
|
|
|
|
+{
|
|
|
|
+ ssize_t nRet = 0;
|
|
|
|
+
|
|
|
|
+ ////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ GFA_MININET_MST_CFG_PARAMS mmcp;
|
|
|
|
+ memset(&mmcp, 0, sizeof(mmcp));
|
|
|
|
+
|
|
|
|
+ if(GfaSerialGetDeviceInterface(&mmcp.devcfg.itf))
|
|
|
|
+ {
|
|
|
|
+ GFA_SER_CFG_PARAMS scp;
|
|
|
|
+ memset(&scp, 0, sizeof(scp));
|
|
|
|
+
|
|
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
|
|
+ // serial interface parameters
|
|
|
|
+
|
|
|
|
+ scp.baud = 19200;
|
|
|
|
+ scp.data = 8;
|
|
|
|
+ scp.stop = 1;
|
|
|
|
+ scp.parity = 'N';
|
|
|
|
+#ifdef _TARGET_BUILD
|
|
|
|
+ scp.bHandleTxEcho = true;
|
|
|
|
+#endif // _TARGET_BUILD
|
|
|
|
+
|
|
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
|
|
+ // mininet master configuration
|
|
|
|
+
|
|
|
|
+ mmcp.devcfg.pszDeviceName = _DEVICE_NAME;
|
|
|
|
+ mmcp.devcfg.pDevParams = &scp;
|
|
|
|
+ mmcp.devcfg.nSizeDevParams = sizeof(scp);
|
|
|
|
+
|
|
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
|
|
+ ////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ HGFAMINEMST hMst = GfaMininetMasterOpen(&mmcp);
|
|
|
|
+
|
|
|
|
+ if(hMst)
|
|
|
|
+ {
|
|
|
|
+ uint8_t status;
|
|
|
|
+ char szMaterial[16], szSerial[16];
|
|
|
|
+ uint32_t nImgLength = 0, nImgCRC32 = 0;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterResetSlaveIndex(hMst, _SLAVE_NODE_ADDR)) == 0)
|
|
|
|
+ TRACE("\nReset Slave index.\n");
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlIsExecuting(hMst)) != 0)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = _BlExecute(hMst)) == 0)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Executing Bootloader.\n");
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterResetSlaveIndex(hMst, _SLAVE_NODE_ADDR)) == 0)
|
|
|
|
+ TRACE("Reset Slave index.\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ TRACE("Bootloader is already executing.\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlSetBaudrate(hMst, 115200)) == 0)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Set Baudrate: %u\n", 115200);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlPing(hMst)) == 1)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Ping ok!\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlGetStatus(hMst, &status)) == 0)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Status: 0x%02hhX\n", status);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlGetImgInfo(hMst, &nImgLength, &nImgCRC32)) == 0)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Bootloader Img. Length: %u, Bootloader Img. CRC: 0x%08X\n", nImgLength, nImgCRC32);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlWriteMaterialAndSerial(hMst, "Material 1", "123456789-1")) == 0)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Set Material and Serial Numbers ...\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlReadMaterialAndSerial(hMst, szMaterial, sizeof(szMaterial), szSerial, sizeof(szSerial))) == 0)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Material: \"%s\", Serial: \"%s\"\n", szMaterial, szSerial);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlWriteMaterialAndSerial(hMst, _BL_MATERIAL, _BL_SERIAL)) == 0)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Set Material and Serial Numbers ...\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlReadMaterialAndSerial(hMst, szMaterial, sizeof(szMaterial), szSerial, sizeof(szSerial))) == 0)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Material: \"%s\", Serial: \"%s\"\n", szMaterial, szSerial);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlSetBaudrate(hMst, 19200)) == 0)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Set Baudrate: %u\n", 19200);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = _BlPing(hMst)) == 1)
|
|
|
|
+ {
|
|
|
|
+ TRACE("Ping ok!\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ GfaMininetMasterClose(hMst);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nRet;
|
|
|
|
+}
|