Fork to see if I can get working
Dependencies: BufferedSerial OneWire WinbondSPIFlash libxDot-dev-mbed5-deprecated
Fork of xDotBridge_update_test20180823 by
Revision 78:43f074baac34, committed 2017-11-13
- Comitter:
- mbriggs_vortex
- Date:
- Mon Nov 13 09:50:49 2017 -0700
- Parent:
- 77:176e3eb8f712
- Child:
- 79:69c4f03c0f86
- Commit message:
- Committing code so far for getting bootloader to work.
Changed in this revision
--- a/WinbondSPIFlash.lib Wed May 17 16:41:56 2017 -0600 +++ b/WinbondSPIFlash.lib Mon Nov 13 09:50:49 2017 -0700 @@ -1,1 +1,1 @@ -http://developer.mbed.org/users/mbriggs_vortex/code/WinbondSPIFlash/#3bb82c1d3aeb +https://developer.mbed.org/users/mbriggs_vortex/code/WinbondSPIFlash/#5dcaed12578a
--- a/xDotBridge/inc/SerialTermMgr.h Wed May 17 16:41:56 2017 -0600
+++ b/xDotBridge/inc/SerialTermMgr.h Mon Nov 13 09:50:49 2017 -0700
@@ -17,8 +17,10 @@
const uint8_t TERM_TIMEOUT = 30; // In seconds
const float XMODEM_TIMEOUT = 10.0;
+const unsigned char MAX_TIMEOUTS = 6; // multiple by TIMEOUT above. 60 total seconds
const uint16_t FLASH_BIN_OFFSET = 256; // Skip first flash page
const uint16_t XMODEM_PACKET_SIZE = 128;
+//const char NEW_CODE [] = "NEWCODE0";
enum ScreenId {
mainScreenId,
@@ -48,6 +50,7 @@
void inputEnterProgMode (char in);
void printEnterProgMode();
bool xmodem2Flash();
+ void writeBootloaderCtrlPage(uint32_t nBytes);
public:
SerialTermMgr(BaseboardIO *bbio, WinbondSPIFlash *flash, float fwVersion);
void regSerial (BufferedSerial *pc) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xDotBridge/inc/bootloader.h Mon Nov 13 09:50:49 2017 -0700
@@ -0,0 +1,189 @@
+/*
+ * bootloader.h
+ *
+ * Created on: Nov 12, 2017
+ * Author: mbriggs
+ */
+
+#ifndef XDOTBRIDGE_INC_BOOTLOADER_H_
+#define XDOTBRIDGE_INC_BOOTLOADER_H_
+
+const char NEW_CODE [] = "NEWCODE0";
+const char END0LINE [] = "END0LINE";
+#define XDOT_FLASH_START 0x08000000
+#define XDOT_FLASH_SIZE 0x00040000
+#define XDOT_SECTOR_SIZE 4096
+#define BOOTLOADER_OFFSET 81920 // 80 KB
+//#define APPLICATION_ADDRESS XDOT_FLASH_START
+#define APPLICATION_ADDRESS XDOT_FLASH_START+BOOTLOADER_OFFSET
+#define PAGE_SIZE 256
+
+//FLASH_ProcessTypeDef pFlash;
+__attribute__( ( section(".data") ) )
+void writeBootLoaderReprogramDone(WinbondSPIFlash *flash)
+{
+ // This should always be less than 256 bytes
+ const uint32_t zero = 0;
+ const unsigned int ctrlSize = sizeof(END0LINE)+sizeof(uint32_t);
+ char buf[ctrlSize];
+ std::memcpy(buf, END0LINE, sizeof(END0LINE));
+ std::memcpy(buf+sizeof(END0LINE), &zero, sizeof(zero));
+ // TODO add reprogram counter just for fun
+
+ // Copy to first page of flash
+ flash->writeStream(0, buf, sizeof(buf));
+}
+
+__attribute__( ( section(".data") ) )
+uint32_t readBootLoaderCtrlPage(WinbondSPIFlash *flash)
+{
+ const unsigned int ctrlSize = sizeof(NEW_CODE)+sizeof(uint32_t);
+ char buf[ctrlSize];
+ flash->readStream(0, buf, sizeof(buf));
+ uint32_t nBytes = 0;
+ char ctrlCode[sizeof(NEW_CODE)];
+ // This should always be less than 256 bytes
+ std::memcpy(&ctrlCode, buf, sizeof(NEW_CODE));
+ std::memcpy(&nBytes, buf+sizeof(NEW_CODE), sizeof(nBytes));
+ // TODO add reprogram counter just for fun
+
+ // Check NEW_CODE str
+ for (unsigned int i=0;i<sizeof(NEW_CODE);i++) {
+ if (ctrlCode[i] != NEW_CODE[i]) {
+ return 0;
+ }
+ }
+
+ // Copy to first page of flash
+ return nBytes;
+}
+
+//__attribute__( ( section(".data")) )
+//HAL_StatusTypeDef RAM_HAL_FLASH_Unlock(void)
+//{
+// if (HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PRGLOCK))
+// {
+// /* Unlocking FLASH_PECR register access*/
+// if(HAL_IS_BIT_SET(FLASH->PECR, FLASH_PECR_PELOCK))
+// {
+// WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY1);
+// WRITE_REG(FLASH->PEKEYR, FLASH_PEKEY2);
+// }
+//
+// /* Unlocking the program memory access */
+// WRITE_REG(FLASH->PRGKEYR, FLASH_PRGKEY1);
+// WRITE_REG(FLASH->PRGKEYR, FLASH_PRGKEY2);
+// }
+// else
+// {
+// return HAL_ERROR;
+// }
+//
+// return HAL_OK;
+//}
+//
+//__attribute__( ( section(".data")) )
+//HAL_StatusTypeDef RAM_HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
+//{
+// HAL_StatusTypeDef status = HAL_ERROR;
+//
+// /* Process Locked */
+// __HAL_LOCK(&pFlash);
+//
+// /* Check the parameters */
+// assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
+// assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
+//
+// /* Wait for last operation to be completed */
+// status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+//
+// if(status == HAL_OK)
+// {
+// /* Clean the error context */
+// pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
+//
+// /*Program word (32-bit) at a specified address.*/
+// *(__IO uint32_t *)Address = Data;
+//
+// /* Wait for last operation to be completed */
+// status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
+// }
+//
+// /* Process Unlocked */
+// __HAL_UNLOCK(&pFlash);
+//
+// return status;
+//}
+//
+//__attribute__( ( section(".data")) )
+//HAL_StatusTypeDef RAM_HAL_FLASH_Lock(void)
+//{
+// /* Set the PRGLOCK Bit to lock the FLASH Registers access */
+// SET_BIT(FLASH->PECR, FLASH_PECR_PRGLOCK);
+//
+//
+// return HAL_OK;
+//}
+
+__attribute__( ( section(".data") ) )
+void copyNewProgram ()
+{
+ uint32_t nBytes, updateBytes;
+ WinbondSPIFlash *flash = new WinbondSPIFlash(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_NSS);
+ char *charbuf = new char [PAGE_SIZE];
+ HAL_FLASH_Unlock();
+
+ flash->releaseFromPowerDown();
+
+ nBytes = readBootLoaderCtrlPage(flash);
+
+ if (nBytes > 0) {
+// printf("flash read address %lu\r\n", readBootLoaderCtrlPage);
+// printf("Updating main application %lu bytes...\r\n", nBytes);
+
+ uint32_t nBytesCopied=0;
+ unsigned int pageIdx=0;
+ while (nBytesCopied < nBytes){
+// printf("Start read %d.\r\n", us_ticker_read());
+ flash->readStream(pageIdx*PAGE_SIZE, charbuf, PAGE_SIZE);
+
+// printf("Stop read, start erase %d.\r\n", us_ticker_read());
+ // Erase page
+ // Erasing may not be required but it seems like good practice
+ FLASH_EraseInitTypeDef eraseStruct;
+ eraseStruct.TypeErase = FLASH_TYPEERASE_PAGES;
+ eraseStruct.NbPages = 1;
+ eraseStruct.PageAddress = APPLICATION_ADDRESS+nBytesCopied;
+ // eraseStruct.PageAddress = 0x0801E000; // Sector 30, Page 478
+
+ uint32_t eraseError;
+ if (HAL_FLASHEx_Erase(&eraseStruct, &eraseError) != HAL_OK) {
+// printf("Error erasing flash. \r\n");
+ }
+
+// printf("Stop erase, start write %d.\r\n", us_ticker_read());
+ // Write page
+ for (unsigned int i=0;i<(PAGE_SIZE/sizeof(uint32_t));i++) {
+ if (HAL_FLASH_Program(TYPEPROGRAM_WORD, APPLICATION_ADDRESS+nBytesCopied,
+ *((uint32_t *)(charbuf+sizeof(uint32_t)*i))) != HAL_OK) {
+// printf("Error programming flash. \r\n");
+ }
+ nBytesCopied += sizeof(uint32_t);
+ }
+// printf("Stop write %d.\r\n", us_ticker_read());
+ pageIdx++;
+ printf("%lu / %lu\r\n", nBytesCopied, nBytes);
+ }
+ HAL_FLASH_Lock();
+ }
+
+ // FIXME add some prints and checking code
+
+ flash->powerDown();
+ delete flash;
+
+// printf("Restarting main application...\r\n");
+ NVIC_SystemReset();
+}
+
+#endif /* XDOTBRIDGE_INC_BOOTLOADER_H_ */
--- a/xDotBridge/src/SerialTermMgr.cpp Wed May 17 16:41:56 2017 -0600
+++ b/xDotBridge/src/SerialTermMgr.cpp Mon Nov 13 09:50:49 2017 -0700
@@ -7,6 +7,7 @@
#include "SerialTermMgr.h"
#include "UserInterface.h"
+#include "bootloader.h"
extern Serial pc;
const char ACK = 0x06;
@@ -22,6 +23,7 @@
mCurrScreen = mainScreenId;
mBbio = bbio;
mFlash = flash;
+
}
void SerialTermMgr::printScreen()
{
@@ -242,6 +244,7 @@
uint8_t csum = 0;
unsigned char pktIdx = 0;
time_t lastValidInput = 0;
+ unsigned char nTimeouts = 0;
while (1) {
// Send a NAK if a packet is not received within timeout period
if ((time(NULL)-lastValidInput) > XMODEM_TIMEOUT){
@@ -249,39 +252,41 @@
pktIdx = 0;
mPc->printf("%c", NAK); // Send NAK
lastValidInput = time(NULL);
- // TODO need to timeout of XMODEM
+ nTimeouts++;
+ if (nTimeouts >= MAX_TIMEOUTS) {
+ mPc->printf("Programming timed out.\r\n");
+ pc.printf("Programming timed out.\r\n");
+ break;
+ }
+
}
if (mPc->readable()) {
packetBuf[pktIdx++] = mPc->getc();
if (pktIdx == 1 && packetBuf[0] == EOT) {
lastValidInput = time(NULL);
mPc->printf("%c", ACK); // Last ACK
+ mPc->printf("Success.\r\n");
+ pc.printf("Success on xmodem. Reset in progress.\r\n");
+ writeBootloaderCtrlPage(packetNum*XMODEM_PACKET_SIZE);
+// copyNewProgram();
+
wait(0.01);
- mPc->printf("Success.\r\n");
- pc.printf("Success on xmodem.\r\n");
+ mFlash->powerDown();
+ NVIC_SystemReset();
+ // Should never get here because of reset.
break;
}
else if (pktIdx >= 132) {
lastValidInput = time(NULL);
+ nTimeouts = 0; // Clear n timeouts with new packet
csum = 0;
-// pc.printf("Got full packet.\r\n");
-// pc.printf("Header SOH: %02X, Packet #%02X, inv #%02x\r\n", packetBuf[0], packetBuf[1], packetBuf[2]);
for (int i=3; i<131; i++) {
-// pc.printf("%02X", packetBuf[i]);
csum += packetBuf[i];
}
pktIdx = 0;
-// pc.printf("\r\ncsum = %d (%02X). Got %d (%02X)\r\n", csum, csum, packetBuf[131], packetBuf[131]);
if ((csum == packetBuf[131]) && (packetBuf[0] == SOH) &&
(packetBuf[1] == ((uint8_t)packetNum)) && (((uint8_t)~packetBuf[2]) == ((uint8_t)packetNum))) {
-// if (packetBuf[1] == packetNum) {
-// pc.printf("One works.\r\n");
-// }
-// if (((uint8_t)~packetBuf[2]) == packetNum) {
-// pc.printf("Two works.\r\n");
-// }
-// pc.printf("%02X == %02X\r\n", packetNum, (uint8_t)~packetBuf[2]);
- mFlash->writeStream(FLASH_BIN_OFFSET+packetNum*XMODEM_PACKET_SIZE, packetBuf+3, XMODEM_PACKET_SIZE);
+ mFlash->writeStream(FLASH_BIN_OFFSET+(packetNum-1)*XMODEM_PACKET_SIZE, packetBuf+3, XMODEM_PACKET_SIZE);
mPc->printf("%c", ACK);
packetNum++;
}
@@ -296,3 +301,16 @@
return true;
}
+
+void SerialTermMgr::writeBootloaderCtrlPage(uint32_t nBytes)
+{
+ // This should always be less than 256 bytes
+ const unsigned int ctrlSize = sizeof(NEW_CODE)+sizeof(nBytes);
+ char buf[ctrlSize];
+ std::memcpy(buf, NEW_CODE, sizeof(NEW_CODE));
+ std::memcpy(buf+sizeof(NEW_CODE), &nBytes, sizeof(nBytes));
+ // TODO add reprogram counter just for fun
+
+ // Copy to first page of flash
+ mFlash->writeStream(0, buf, sizeof(buf));
+}
--- a/xDotBridge/src/main.cpp Wed May 17 16:41:56 2017 -0600
+++ b/xDotBridge/src/main.cpp Mon Nov 13 09:50:49 2017 -0700
@@ -17,14 +17,18 @@
#define RX_SEQ_LOG 1
-const float BridgeVersion = 1.01;
+const float BridgeVersion = 99.99;
+
+// 232 Pins
+const PinName SER_TERM_TX = UART_TX;
+const PinName SER_TERM_RX = UART_RX;
#ifndef __TEST__ // Exclude code for tests
Serial pc(USBTX, USBRX);
//RawSerial outPc(UART_TX, UART_RX);
//Serial *outPc;
BufferedSerial *outPc;
-InterruptIn uart1RxIntIn (UART_RX);
+InterruptIn uart1RxIntIn (SER_TERM_RX);
//// Serial interrupts / buffer code
//const int buffer_size = 255;
@@ -85,6 +89,11 @@
pairBtnIntFlag = true;
}
+void testFunc() {
+ const uint32_t test=0xDEADBEEF;
+ printf("%d", test);
+}
+
int main() {
CommProtocolPeerBrute *protocol = new CommProtocolPeerBrute();
BaseboardIO *bbio = new BaseboardIO();
@@ -208,6 +217,8 @@
while (true) {
// myLogInfo("Start of loop time %d", us_ticker_read());
ledPatterns.turnOff();
+ bbio->serialRx(true); // FIXME find a better home
+ bbio->serialTx(false); // FIXME only turn on during TX
// Pair logic and switch sampling
if (pairBtnIntFlag) {
@@ -293,10 +304,11 @@
// Serial Terminal
if (uartRxFlag) {
+ pc.printf("Got RX Int\r\n");
uart1RxIntIn.disable_irq();
// pc.printf("Got uart flag!!!\r\n");
uartRxFlag = false;
- outPc = new BufferedSerial(UART1_TX, UART1_RX);
+ outPc = new BufferedSerial(SER_TERM_TX, SER_TERM_RX);
outPc->baud(TERM_BAUD);
serialTermMgr.regSerial(outPc);
char c;
