diff options
| author | Nick Van Doorn <vandoorn.nick@gmail.com> | 2018-09-10 23:23:21 -0700 | 
|---|---|---|
| committer | Nick Van Doorn <vandoorn.nick@gmail.com> | 2018-09-10 23:23:21 -0700 | 
| commit | 83639bdffb6b9355a29d2b2e55807aa3b6837bbd (patch) | |
| tree | e5858b146a3901880e5babaa89aacbe0979f0552 /upload/upload.c | |
Initial commit
Diffstat (limited to 'upload/upload.c')
| -rw-r--r-- | upload/upload.c | 161 | 
1 files changed, 161 insertions, 0 deletions
| diff --git a/upload/upload.c b/upload/upload.c new file mode 100644 index 0000000..a18244e --- /dev/null +++ b/upload/upload.c @@ -0,0 +1,161 @@ +#include "legato.h" +#include "interfaces.h" +#include "xmodem.h" +#include "util.h" + +#define MTK7697_BAUD 115200 +#define MTK7697_BAUDX 115200 * 8 +static const char* SERIAL_PORT_PATH = "/dev/ttyHS0"; +static const char* LDR_BIN_PATH = "/home/root/mtfiles/mt7697_bootloader.bin"; +static const char* N9_BIN_PATH = +    "/home/root/mtfiles/WIFI_RAM_CODE_MT76X7_in_flash.bin"; +static const char* CM4_BIN_PATH = "/home/root/mtfiles/ble_smart_connect.bin"; +static const char* DA_PATH = "/home/root/mtfiles/da97.bin"; + +typedef enum { LDR = 1, N9 = 3, CM4 = 2 } MtkMemorySegment; + +typedef struct { +  int serialPort; +  int errorCount; +  int cCount; +  int retry; +  int startTime; +} FlashState; + +FlashState state = {0, 0, 0, 0}; + +void configureSerialPort(FlashState* s, int baud) { +  close(s->serialPort); +  s->serialPort = fd_openSerial(SERIAL_PORT_PATH, baud); +} + +bool flashDa(FlashState* s) { +  configureSerialPort(&state, MTK7697_BAUD); +  LE_INFO("Sending DA over xmodem"); +  bool r = XSend(s->serialPort, DA_PATH) == 0; +  LE_INFO("DA success: %d", r); +  return r; +} + +void putIntoBootloader() { +  // make sure the bootstrap pin is on +  mtBootstrap_Activate(); +  // reset state && wait +  mtRst_Deactivate(); +  sleep(1); +  // pull out of reset +  mtRst_Activate(); +} + +void retryInitSequence(FlashState* s) { +  s->retry++; +  s->cCount = 0; +  s->errorCount = 0; +  s->startTime = util_getUnixDatetime(); +  close(s->serialPort); +  putIntoBootloader(); +  configureSerialPort(s, MTK7697_BAUD); +} + +bool verifyInitSequence(FlashState* s) { +  uint8_t data; +  bool initDone = false; +  s->startTime = util_getUnixDatetime(); +  while (!initDone) { +    data = fd_getChar(s->serialPort); +    fd_flush(s->serialPort); +    if (data == 'C') { +      s->cCount++; +      LE_INFO("Got a C"); +    } else if (data != 0) { +      s->errorCount++; +      LE_INFO("Got an error"); +    } +    if (s->cCount > 1) { +      initDone = true; +      LE_INFO("Init done"); +      break; +    } +    if (s->errorCount > 3 || (util_getUnixDatetime() - s->startTime > 3)) { +      LE_INFO("Retrying..."); +      retryInitSequence(s); +    } +    if (s->retry > 3) { +      LE_INFO("Aborting"); +      break; +    } +  } +  return initDone; +} + +bool flashBinary(FlashState* s, MtkMemorySegment segment, const char* binPath) { +  putIntoBootloader(); +  configureSerialPort(s, MTK7697_BAUD); +  bool init = verifyInitSequence(s); +  LE_INFO("Init verified: %d", init); +  flashDa(s); +  configureSerialPort(s, MTK7697_BAUDX); +  sleep(1); +  bool initDone = false; +  int data = '0'; +  switch (segment) { +    case LDR: +      fd_puts(s->serialPort, "1\r"); +      break; +    case N9: +      fd_puts(s->serialPort, "3\r"); +      break; +    case CM4: +      fd_puts(s->serialPort, "2\r"); +      break; +  } +  while (!initDone) { +    LE_INFO("here %c", data); +    data = fd_getChar(s->serialPort); +    if (data == 'C') { +      initDone = true; +      break; +    } +  } +  fd_flush(s->serialPort); +  LE_INFO("Sending %s over xmodem", binPath); +  bool r = XSend(s->serialPort, binPath) == 0; +  LE_INFO("%s success: %d", binPath, r); +  sleep(1); +  fd_puts(s->serialPort, "C\r"); +  fd_flush(s->serialPort); +  return true; +} + +bool flashLdr(FlashState* s) { +  LE_INFO("Flashing LDR segment"); +  return flashBinary(s, LDR, LDR_BIN_PATH); +} + +bool flashN9(FlashState* s) { +  LE_INFO("Flashing N9 segment"); +  return flashBinary(s, N9, N9_BIN_PATH); +} + +bool flashCm4(FlashState* s) { +  LE_INFO("Flashing CM4"); +  return flashBinary(s, CM4, CM4_BIN_PATH); +} + +void resetPins() { +  mtBootstrap_Deactivate(); +} + +void configureGpio() { +  mtRst_SetPushPullOutput(MTRST_ACTIVE_HIGH, true); +  mtBootstrap_SetPushPullOutput(MTBOOTSTRAP_ACTIVE_HIGH, true); +} + +COMPONENT_INIT { +  configureGpio(); +  flashLdr(&state); +  flashN9(&state); +  flashCm4(&state); +  resetPins(); +  close(state.serialPort); +} | 
