Moved a new version of osint_mingw.c from the propeller-load project but still needs serial_baud() function to work.
Started adding some better comments in ploader.c.
This commit is contained in:
parent
808ba62a7b
commit
bfd131d38b
|
@ -464,7 +464,7 @@ void hwreset(void)
|
||||||
assert_reset();
|
assert_reset();
|
||||||
msleep(10);
|
msleep(10);
|
||||||
deassert_reset();
|
deassert_reset();
|
||||||
msleep(90);
|
msleep(100);
|
||||||
tcflush(hSerial, TCIFLUSH);
|
tcflush(hSerial, TCIFLUSH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,322 +1,309 @@
|
||||||
/*
|
/*
|
||||||
* osint_mingw.c - serial i/o routines for win32api via mingw
|
* osint_mingw.c - serial i/o routines for win32api via mingw
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011 by Steve Denson.
|
* Copyright (c) 2011 by Steve Denson.
|
||||||
*
|
*
|
||||||
* MIT License
|
* MIT License
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "osint.h"
|
#include "osint.h"
|
||||||
|
|
||||||
static HANDLE hSerial = INVALID_HANDLE_VALUE;
|
static HANDLE hSerial = INVALID_HANDLE_VALUE;
|
||||||
static COMMTIMEOUTS original_timeouts;
|
static COMMTIMEOUTS original_timeouts;
|
||||||
static COMMTIMEOUTS timeouts;
|
static COMMTIMEOUTS timeouts;
|
||||||
|
|
||||||
static void ShowLastError(void);
|
static void ShowLastError(void);
|
||||||
|
|
||||||
/* normally we use DTR for reset but setting this variable to non-zero will use RTS instead */
|
/* Normally we use DTR for reset */
|
||||||
static int use_rts_for_reset = 0;
|
static reset_method_t reset_method = RESET_WITH_DTR;
|
||||||
|
|
||||||
void serial_use_rts_for_reset(int use_rts)
|
int use_reset_method(char* method)
|
||||||
{
|
{
|
||||||
use_rts_for_reset = use_rts;
|
if (strcasecmp(method, "dtr") == 0)
|
||||||
}
|
reset_method = RESET_WITH_DTR;
|
||||||
|
else if (strcasecmp(method, "rts") == 0)
|
||||||
int serial_init(const char *port, unsigned long baud)
|
reset_method = RESET_WITH_RTS;
|
||||||
{
|
else {
|
||||||
char fullPort[20];
|
return -1;
|
||||||
|
}
|
||||||
sprintf(fullPort, "\\\\.\\%s", port);
|
return 0;
|
||||||
|
}
|
||||||
hSerial = CreateFile(
|
|
||||||
fullPort,
|
int serial_init(const char *port, unsigned long baud)
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
{
|
||||||
0,
|
char fullPort[20];
|
||||||
NULL,
|
DCB state;
|
||||||
OPEN_EXISTING,
|
|
||||||
0,
|
sprintf(fullPort, "\\\\.\\%s", port);
|
||||||
NULL);
|
|
||||||
|
hSerial = CreateFile(
|
||||||
if (hSerial == INVALID_HANDLE_VALUE)
|
fullPort,
|
||||||
return FALSE;
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
0,
|
||||||
/* Set the baud rate. Always succeeds with mingw. */
|
NULL,
|
||||||
if (!serial_baud(baud)) {
|
OPEN_EXISTING,
|
||||||
serial_done();
|
0,
|
||||||
return 0;
|
NULL);
|
||||||
}
|
|
||||||
|
if (hSerial == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
GetCommTimeouts(hSerial, &original_timeouts);
|
|
||||||
timeouts = original_timeouts;
|
GetCommState(hSerial, &state);
|
||||||
timeouts.ReadIntervalTimeout = MAXDWORD;
|
switch (baud) {
|
||||||
timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
|
case 9600:
|
||||||
timeouts.WriteTotalTimeoutConstant = 1;
|
state.BaudRate = CBR_9600;
|
||||||
timeouts.WriteTotalTimeoutMultiplier = 1;
|
break;
|
||||||
|
case 19200:
|
||||||
/* setup device buffers */
|
state.BaudRate = CBR_19200;
|
||||||
SetupComm(hSerial, 10000, 10000);
|
break;
|
||||||
|
case 38400:
|
||||||
/* purge any information in the buffer */
|
state.BaudRate = CBR_38400;
|
||||||
PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
|
break;
|
||||||
|
case 57600:
|
||||||
return TRUE;
|
state.BaudRate = CBR_57600;
|
||||||
}
|
break;
|
||||||
|
case 115200:
|
||||||
void serial_done(void)
|
state.BaudRate = CBR_115200;
|
||||||
{
|
break;
|
||||||
if (hSerial != INVALID_HANDLE_VALUE) {
|
default:
|
||||||
FlushFileBuffers(hSerial);
|
return FALSE;
|
||||||
CloseHandle(hSerial);
|
}
|
||||||
hSerial = INVALID_HANDLE_VALUE;
|
state.ByteSize = 8;
|
||||||
}
|
state.Parity = NOPARITY;
|
||||||
}
|
state.StopBits = ONESTOPBIT;
|
||||||
|
state.fOutxDsrFlow = FALSE;
|
||||||
/**
|
state.fDtrControl = DTR_CONTROL_DISABLE;
|
||||||
* change the baud rate of the serial port
|
state.fOutxCtsFlow = FALSE;
|
||||||
* @param baud - baud rate
|
state.fRtsControl = RTS_CONTROL_DISABLE;
|
||||||
* @returns 1 for success and 0 for failure
|
state.fInX = FALSE;
|
||||||
*/
|
state.fOutX = FALSE;
|
||||||
int serial_baud(unsigned long baud)
|
state.fBinary = TRUE;
|
||||||
{
|
state.fParity = FALSE;
|
||||||
DCB state;
|
state.fDsrSensitivity = FALSE;
|
||||||
GetCommState(hSerial, &state);
|
state.fTXContinueOnXoff = TRUE;
|
||||||
switch (baud) {
|
state.fNull = FALSE;
|
||||||
case 9600:
|
state.fAbortOnError = FALSE;
|
||||||
state.BaudRate = CBR_9600;
|
SetCommState(hSerial, &state);
|
||||||
break;
|
|
||||||
case 19200:
|
GetCommTimeouts(hSerial, &original_timeouts);
|
||||||
state.BaudRate = CBR_19200;
|
timeouts = original_timeouts;
|
||||||
break;
|
timeouts.ReadIntervalTimeout = MAXDWORD;
|
||||||
case 38400:
|
timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
|
||||||
state.BaudRate = CBR_38400;
|
|
||||||
break;
|
/* setup device buffers */
|
||||||
case 57600:
|
SetupComm(hSerial, 10000, 10000);
|
||||||
state.BaudRate = CBR_57600;
|
|
||||||
break;
|
/* purge any information in the buffer */
|
||||||
case 115200:
|
PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
|
||||||
state.BaudRate = CBR_115200;
|
|
||||||
break;
|
return TRUE;
|
||||||
default:
|
}
|
||||||
printf("Unsupported baudrate. Use ");
|
|
||||||
printf("115200, 57600, 38400, 19200, or 9600\n");
|
void serial_done(void)
|
||||||
printf("Setting default 115200\n");
|
{
|
||||||
state.BaudRate = CBR_115200;
|
if (hSerial != INVALID_HANDLE_VALUE) {
|
||||||
break;
|
FlushFileBuffers(hSerial);
|
||||||
}
|
CloseHandle(hSerial);
|
||||||
|
hSerial = INVALID_HANDLE_VALUE;
|
||||||
state.ByteSize = 8;
|
}
|
||||||
state.Parity = NOPARITY;
|
}
|
||||||
state.StopBits = ONESTOPBIT;
|
|
||||||
state.fOutxDsrFlow = FALSE;
|
/**
|
||||||
state.fDtrControl = DTR_CONTROL_DISABLE;
|
* transmit a buffer
|
||||||
state.fOutxCtsFlow = FALSE;
|
* @param buff - char pointer to buffer
|
||||||
state.fRtsControl = RTS_CONTROL_DISABLE;
|
* @param n - number of bytes in buffer to send
|
||||||
state.fInX = FALSE;
|
* @returns zero on failure
|
||||||
state.fOutX = FALSE;
|
*/
|
||||||
state.fBinary = TRUE;
|
int tx(uint8_t* buff, int n)
|
||||||
state.fParity = FALSE;
|
{
|
||||||
state.fDsrSensitivity = FALSE;
|
DWORD dwBytes = 0;
|
||||||
state.fTXContinueOnXoff = TRUE;
|
if(!WriteFile(hSerial, buff, n, &dwBytes, NULL)){
|
||||||
state.fNull = FALSE;
|
printf("Error writing port\n");
|
||||||
state.fAbortOnError = FALSE;
|
ShowLastError();
|
||||||
SetCommState(hSerial, &state);
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return dwBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* transmit a buffer
|
* receive a buffer
|
||||||
* @param buff - char pointer to buffer
|
* @param buff - char pointer to buffer
|
||||||
* @param n - number of bytes in buffer to send
|
* @param n - number of bytes in buffer to read
|
||||||
* @returns zero on failure
|
* @returns number of bytes read
|
||||||
*/
|
*/
|
||||||
int tx(uint8_t* buff, int n)
|
int rx(uint8_t* buff, int n)
|
||||||
{
|
{
|
||||||
DWORD dwBytes = 0;
|
DWORD dwBytes = 0;
|
||||||
if(!WriteFile(hSerial, buff, n, &dwBytes, NULL)){
|
SetCommTimeouts(hSerial, &original_timeouts);
|
||||||
printf("Error writing port\n");
|
if(!ReadFile(hSerial, buff, n, &dwBytes, NULL)){
|
||||||
ShowLastError();
|
printf("Error reading port\n");
|
||||||
return 0;
|
ShowLastError();
|
||||||
}
|
return 0;
|
||||||
return dwBytes;
|
}
|
||||||
}
|
return dwBytes;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* receive a buffer
|
/**
|
||||||
* @param buff - char pointer to buffer
|
* receive a buffer with a timeout
|
||||||
* @param n - number of bytes in buffer to read
|
* @param buff - char pointer to buffer
|
||||||
* @returns number of bytes read
|
* @param n - number of bytes in buffer to read
|
||||||
*/
|
* @param timeout - timeout in milliseconds
|
||||||
int rx(uint8_t* buff, int n)
|
* @returns number of bytes read or SERIAL_TIMEOUT
|
||||||
{
|
*/
|
||||||
DWORD dwBytes = 0;
|
int rx_timeout(uint8_t* buff, int n, int timeout)
|
||||||
SetCommTimeouts(hSerial, &original_timeouts);
|
{
|
||||||
if(!ReadFile(hSerial, buff, n, &dwBytes, NULL)){
|
DWORD dwBytes = 0;
|
||||||
printf("Error reading port\n");
|
timeouts.ReadTotalTimeoutConstant = timeout;
|
||||||
ShowLastError();
|
SetCommTimeouts(hSerial, &timeouts);
|
||||||
return 0;
|
if(!ReadFile(hSerial, buff, n, &dwBytes, NULL)){
|
||||||
}
|
printf("Error reading port\n");
|
||||||
return dwBytes;
|
ShowLastError();
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
/**
|
return dwBytes > 0 ? dwBytes : SERIAL_TIMEOUT;
|
||||||
* receive a buffer with a timeout
|
}
|
||||||
* @param buff - char pointer to buffer
|
|
||||||
* @param n - number of bytes in buffer to read
|
/**
|
||||||
* @param timeout - timeout in milliseconds
|
* hwreset ... resets Propeller hardware using DTR
|
||||||
* @returns number of bytes read or SERIAL_TIMEOUT
|
* @returns void
|
||||||
*/
|
*/
|
||||||
int rx_timeout(uint8_t* buff, int n, int timeout)
|
void hwreset(void)
|
||||||
{
|
{
|
||||||
DWORD dwBytes = 0;
|
EscapeCommFunction(hSerial, reset_method == RESET_WITH_RTS ? SETRTS : SETDTR);
|
||||||
timeouts.ReadTotalTimeoutConstant = timeout;
|
Sleep(25);
|
||||||
SetCommTimeouts(hSerial, &timeouts);
|
EscapeCommFunction(hSerial, reset_method == RESET_WITH_RTS ? CLRRTS : CLRDTR);
|
||||||
if(!ReadFile(hSerial, buff, n, &dwBytes, NULL)){
|
Sleep(90);
|
||||||
printf("Error reading port\n");
|
// Purge here after reset helps to get rid of buffered data.
|
||||||
ShowLastError();
|
PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
return dwBytes > 0 ? dwBytes : SERIAL_TIMEOUT;
|
static unsigned long getms()
|
||||||
}
|
{
|
||||||
|
LARGE_INTEGER ticksPerSecond;
|
||||||
/**
|
LARGE_INTEGER tick; // A point in time
|
||||||
* hwreset ... resets Propeller hardware using DTR
|
LARGE_INTEGER time; // For converting tick into real time
|
||||||
* @returns void
|
// get the high resolution counter's accuracy
|
||||||
*/
|
QueryPerformanceFrequency(&ticksPerSecond);
|
||||||
void hwreset(void)
|
if(ticksPerSecond.QuadPart < 1000) {
|
||||||
{
|
printf("Your system does not meet timer requirement. Try another computer. Exiting program.\n");
|
||||||
// reset then purge port
|
exit(1);
|
||||||
EscapeCommFunction(hSerial, use_rts_for_reset ? SETRTS : SETDTR);
|
}
|
||||||
Sleep(25);
|
// what time is it?
|
||||||
PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
|
QueryPerformanceCounter(&tick);
|
||||||
EscapeCommFunction(hSerial, use_rts_for_reset ? CLRRTS : CLRDTR);
|
time.QuadPart = (tick.QuadPart*1000/ticksPerSecond.QuadPart);
|
||||||
Sleep(90);
|
return (unsigned long)(time.QuadPart);
|
||||||
// Purge here after reset helps to get rid of buffered data.
|
}
|
||||||
PurgeComm(hSerial, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
|
|
||||||
}
|
/**
|
||||||
|
* sleep for ms milliseconds
|
||||||
static unsigned long getms()
|
* @param ms - time to wait in milliseconds
|
||||||
{
|
*/
|
||||||
LARGE_INTEGER ticksPerSecond;
|
void msleep(int ms)
|
||||||
LARGE_INTEGER tick; // A point in time
|
{
|
||||||
LARGE_INTEGER time; // For converting tick into real time
|
unsigned long t = getms();
|
||||||
// get the high resolution counter's accuracy
|
while((t+ms+10) > getms())
|
||||||
QueryPerformanceFrequency(&ticksPerSecond);
|
;
|
||||||
if(ticksPerSecond.QuadPart < 1000) {
|
}
|
||||||
printf("Your system does not meet timer requirement. Try another computer. Exiting program.\n");
|
|
||||||
exit(1);
|
static void ShowLastError(void)
|
||||||
}
|
{
|
||||||
// what time is it?
|
LPVOID lpMsgBuf;
|
||||||
QueryPerformanceCounter(&tick);
|
FormatMessage(
|
||||||
time.QuadPart = (tick.QuadPart*1000/ticksPerSecond.QuadPart);
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
return (unsigned long)(time.QuadPart);
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
}
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
/**
|
GetLastError(),
|
||||||
* sleep for ms milliseconds
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
* @param ms - time to wait in milliseconds
|
(LPTSTR)&lpMsgBuf,
|
||||||
*/
|
0, NULL);
|
||||||
void msleep(int ms)
|
printf(" %s\n", (char *)lpMsgBuf);
|
||||||
{
|
LocalFree(lpMsgBuf);
|
||||||
unsigned long t = getms();
|
exit(1); // exit on error
|
||||||
while((t+ms+10) > getms())
|
}
|
||||||
;
|
|
||||||
}
|
/* escape from terminal mode */
|
||||||
|
#define ESC 0x1b
|
||||||
static void ShowLastError(void)
|
|
||||||
{
|
/*
|
||||||
LPVOID lpMsgBuf;
|
* if "check_for_exit" is true, then
|
||||||
FormatMessage(
|
* a sequence EXIT_CHAR 00 nn indicates that we should exit
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
*/
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
#define EXIT_CHAR 0xff
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
NULL,
|
void terminal_mode(int check_for_exit, int pst_mode)
|
||||||
GetLastError(),
|
{
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
int sawexit_char = 0;
|
||||||
(LPTSTR)&lpMsgBuf,
|
int sawexit_valid = 0;
|
||||||
0, NULL);
|
int exitcode = 0;
|
||||||
printf(" %s\n", (char *)lpMsgBuf);
|
int continue_terminal = 1;
|
||||||
LocalFree(lpMsgBuf);
|
|
||||||
exit(1); // exit on error
|
while (continue_terminal) {
|
||||||
}
|
uint8_t buf[1];
|
||||||
|
if (rx_timeout(buf, 1, 0) != SERIAL_TIMEOUT) {
|
||||||
/* escape from terminal mode */
|
if (sawexit_valid) {
|
||||||
#define ESC 0x1b
|
exitcode = buf[0];
|
||||||
|
continue_terminal = 0;
|
||||||
/*
|
}
|
||||||
* if "check_for_exit" is true, then
|
else if (sawexit_char) {
|
||||||
* a sequence EXIT_CHAR 00 nn indicates that we should exit
|
if (buf[0] == 0) {
|
||||||
*/
|
sawexit_valid = 1;
|
||||||
#define EXIT_CHAR 0xff
|
} else {
|
||||||
|
putchar(EXIT_CHAR);
|
||||||
void terminal_mode(int check_for_exit, int pst_mode)
|
putchar(buf[0]);
|
||||||
{
|
fflush(stdout);
|
||||||
int sawexit_char = 0;
|
}
|
||||||
int sawexit_valid = 0;
|
}
|
||||||
int exitcode = 0;
|
else if (check_for_exit && buf[0] == EXIT_CHAR) {
|
||||||
int continue_terminal = 1;
|
sawexit_char = 1;
|
||||||
|
}
|
||||||
while (continue_terminal) {
|
else {
|
||||||
uint8_t buf[1];
|
putchar(buf[0]);
|
||||||
if (rx_timeout(buf, 1, 0) != SERIAL_TIMEOUT) {
|
if (pst_mode && buf[0] == '\r')
|
||||||
if (sawexit_valid) {
|
putchar('\n');
|
||||||
exitcode = buf[0];
|
fflush(stdout);
|
||||||
continue_terminal = 0;
|
}
|
||||||
}
|
}
|
||||||
else if (sawexit_char) {
|
else if (kbhit()) {
|
||||||
if (buf[0] == 0) {
|
if ((buf[0] = getch()) == ESC)
|
||||||
sawexit_valid = 1;
|
break;
|
||||||
} else {
|
tx(buf, 1);
|
||||||
putchar(EXIT_CHAR);
|
/* this should be handled by the library */
|
||||||
putchar(buf[0]);
|
#if 0
|
||||||
fflush(stdout);
|
if(buf[0] == '\r') {
|
||||||
//sawexit_char = 0;
|
buf[0] = '\n';
|
||||||
}
|
tx(buf, 1);
|
||||||
}
|
}
|
||||||
else if (check_for_exit && buf[0] == EXIT_CHAR) {
|
#endif
|
||||||
sawexit_char = 1;
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
putchar(buf[0]);
|
if (check_for_exit && sawexit_valid) {
|
||||||
if (pst_mode && buf[0] == '\r')
|
exit(exitcode);
|
||||||
putchar('\n');
|
}
|
||||||
fflush(stdout);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (kbhit()) {
|
|
||||||
if ((buf[0] = getch()) == ESC)
|
|
||||||
break;
|
|
||||||
tx(buf, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_for_exit && sawexit_valid) {
|
|
||||||
exit(exitcode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
20
ploader.c
20
ploader.c
|
@ -32,7 +32,7 @@ int PL_LoadSpinBinary(PL_state *state, int loadType, uint8_t *image, int size)
|
||||||
int retries = 100;
|
int retries = 100;
|
||||||
uint8_t buf[1];
|
uint8_t buf[1];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
TLong(state, loadType);
|
TLong(state, loadType);
|
||||||
TLong(state, size / sizeof(uint32_t));
|
TLong(state, size / sizeof(uint32_t));
|
||||||
|
|
||||||
|
@ -54,6 +54,12 @@ int PL_LoadSpinBinary(PL_state *state, int loadType, uint8_t *image, int size)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wait for eeprom programming and verification */
|
||||||
|
if (loadType == LOAD_TYPE_EEPROM || loadType == LOAD_TYPE_EEPROM_RUN) {
|
||||||
|
/* BUG: need to add handling of ACK/NAK from EEPROM programming */
|
||||||
|
/* BUG: need to add handling of ACK/NAK from EEPROM verification */
|
||||||
|
}
|
||||||
|
|
||||||
return retries >= 0 ? 0 : -1;
|
return retries >= 0 ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,19 +82,25 @@ int PL_HardwareFound(PL_state *state, int *pVersion)
|
||||||
/* initialize the serial buffers */
|
/* initialize the serial buffers */
|
||||||
SerialInit(state);
|
SerialInit(state);
|
||||||
|
|
||||||
/* reset the propeller */
|
/* reset the propeller (includes post-reset delay of 100ms) */
|
||||||
(*state->serial->reset)(state->serialData);
|
(*state->serial->reset)(state->serialData);
|
||||||
|
|
||||||
/* send the connect string + blanks for echoes */
|
/* transmit the calibration pulses */
|
||||||
TByte(state, 0xf9);
|
TByte(state, 0xf9);
|
||||||
|
|
||||||
|
/* transmit the handshake pattern */
|
||||||
state->lfsr = 'P';
|
state->lfsr = 'P';
|
||||||
for (i = 0; i < 250; ++i)
|
for (i = 0; i < 250; ++i)
|
||||||
TByte(state, IterateLFSR(state) | 0xfe);
|
TByte(state, IterateLFSR(state) | 0xfe);
|
||||||
|
|
||||||
|
/* transmit calibration pulses to clock out the connection response and the version byte */
|
||||||
for (i = 0; i < 250 + 8; ++i)
|
for (i = 0; i < 250 + 8; ++i)
|
||||||
TByte(state, 0xf9);
|
TByte(state, 0xf9);
|
||||||
|
|
||||||
|
/* flush the transmit buffer */
|
||||||
TComm(state);
|
TComm(state);
|
||||||
|
|
||||||
/* receive the connect string */
|
/* receive the connection response */
|
||||||
for (i = 0; i < 250; ++i)
|
for (i = 0; i < 250; ++i)
|
||||||
if (RBit(state, 100) != IterateLFSR(state))
|
if (RBit(state, 100) != IterateLFSR(state))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in New Issue