📄 mx21serial.cpp
字号:
#include <conio.h>
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include <stdio.h>
#include <windows.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <io.h>
#include "mx21serial.h"
static int debug = 0;
static int action = ENUM_NULL;
const DATA_LEN = 1024 * 4;
static unsigned char scratch_buf[DATA_LEN]; // 16KB data
// cmd | addr | width | count | data | end
unsigned char irom_readl[16] = {1, 1, _x, _x, _x, _x, 32, 0, 0, 0, 4, 0, 0, 0, 0, 0};
unsigned char irom_readw[16] = {1, 1, _x, _x, _x, _x, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0};
unsigned char irom_readb[16] = {1, 1, _x, _x, _x, _x, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0};
unsigned char irom_writel[16] = {2, 2, _x, _x, _x, _x, 32, 0, 0, 0, 4, _x,_x,_x,_x, 0};
unsigned char irom_writew[16] = {2, 2, _x, _x, _x, _x, 16, 0, 0, 0, 2, _x,_x,_x,_x, 0};
unsigned char irom_writeb[16] = {2, 2, _x, _x, _x, _x, 8, 0, 0, 0, 1, _x,_x,_x,_x, 0};
unsigned char irom_status[16] = {5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char irom_download[16]= {4, 4, _x, _x, _x, _x, 0, _x,_x,_x,_x, 0, 0, 0, 0, END_RPT};
unsigned char irom_exec[16] = {4, 4, _x, _x, _x, _x, 0, 0, 0, 0, 0, 0, 0, 0, 0, END_EXEC};
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
struct reg_addr_val {
unsigned long r_w;
unsigned long addr;
unsigned long val;
} mx21reg_initsys[] = {
// ### AHB-Lite IP Interface
{REG_WEITE, 0x10000000, 0x00040304},
{REG_WEITE, 0x10020000, 0x00000000},
{REG_WEITE, 0x10000004, 0xFFFBFCFB},
{REG_WEITE, 0x10020004, 0xFFFFFFFF},
{REG_WEITE, 0x10027020, 0x31084003},
// # CS0 Initialization (Async Mode) 32-bit, ?? wait states
{REG_WEITE, 0xDF001000, 0x00000E01},
{REG_WEITE, 0xDF001004, 0x00000E01},
// # Setting for Memory Map IO Port
// # CS1 Initialization (Async Mode)
// # 16-bit, D0..15, ?? wait states
{REG_WEITE, 0xDF001008, 0x00002000},
{REG_WEITE, 0xDF00100C, 0x11118501},
// # CSD0 Initialization (SDRAM)
{REG_WEITE, 0xDF000000, 0x92120300},
// *** Issue Precharge all Command
{REG_READ, 0xC0200000, 0},
// *** Set AutoRefresh Command
{REG_WEITE, 0xDF000000, 0xA2120300},
// *** Issue AutoRefresh Command
{REG_READ, 0xC0000000, 0},
{REG_READ, 0xC0000000, 0},
{REG_READ, 0xC0000000, 0},
{REG_READ, 0xC0000000, 0},
{REG_READ, 0xC0000000, 0},
{REG_READ, 0xC0000000, 0},
{REG_READ, 0xC0000000, 0},
{REG_READ, 0xC0000000, 0},
// *** Set Mode Register
{REG_WEITE, 0xDF000000, 0xB2120300},
{REG_READ, 0xC0119800, 0},
{REG_WEITE, 0xDF000000, 0x8212F339},
// ### End of Memory Configuration
{REG_WEITE, 0x1003F300, 0x00123056},
// ### CSCR: FCLK=MPLL/1; HCLK=FCLK/4; #####(If MPLL==266MHz, FCLK=266MHz and HCLK=66MHz)
{REG_WEITE, 0x10027000, 0x17000E07},
// for flashing
{REG_WEITE, SERIAL_DOWNLOAD_MAGIC_REG, SERIAL_DOWNLOAD_MAGIC},
{REG_WEITE, SERIAL_DOWNLOAD_SRC_REG, SERIAL_DOWNLOAD_SRC_ADDR},
{REG_WEITE, SERIAL_DOWNLOAD_TGT_REG, NULL},
{REG_WEITE, SERIAL_DOWNLOAD_SZ_REG, NULL},
};
#define INIT_LOOP_COUNT (sizeof(mx21reg_initsys) / sizeof(struct reg_addr_val))
#define SET_MAGIC_FOR_DOWNLOAD() (mx21reg_initsys[INIT_LOOP_COUNT-4].val = 0)
#define SET_TGT_ADDR_FOR_FLASH(x) (mx21reg_initsys[INIT_LOOP_COUNT-2].val = x)
#define SET_SIZE_FOR_FLASH(x) (mx21reg_initsys[INIT_LOOP_COUNT-1].val = x)
int main(int argc, char* argv[])
{
int port;
unsigned long download = 0, result;
char *file_name;
char *port_name;
HANDLE portH;
FILE *fp;
unsigned long total;
unsigned long bytes_read = 0;
if (argc == 1) {
goto help_msg;
}
if (argc != 4 && argc != 5) {
printf("Wrong number of arguments.\n");
goto help_msg_short;
}
if (parse_cmd_line(argc, argv, &port, &download) != 0) {
printf("Command parsing error\n");
goto help_msg_short;
}
port_name = argv[1];
file_name = argv[3];
if (download >= SDRAM_BASE_ADDR &&
download < (SDRAM_BASE_ADDR + SDRAM_SIZE)) {
action = ENUM_DOWNLOAD;
if (debug) printf("downloading to sdram ...\n");
} else if (download >= CS0_BASE_ADDR &&
download < (CS0_BASE_ADDR + CS0_SIZE)) {
action = ENUM_NOR;
} else if (download >= NFC_BASE &&
download < (NFC_BASE + NFC_SIZE)) {
action = ENUM_NAND;
printf("programing to NAND flash is not supported yet\n");
printf("nice try :<\n");
exit (-1);
} else {
printf("Unknown address range. Assuming download ...\n");
}
// Open the serial port.
if ((portH = Open_Port(port_name, CBR_115200)) == INVALID_HANDLE_VALUE) {
printf("Error: %s is in use\n", port_name);
return -1;
}
if (op_header(portH, irom_status, &result) != ROM_OK)
goto func_out;
if (debug) printf("status = 0x%08x '%s'\n", result, status_to_string(result));
switch (action) {
case ENUM_DOWNLOAD:
SET_MAGIC_FOR_DOWNLOAD();
if (config_reg(portH, mx21reg_initsys, INIT_LOOP_COUNT) != ROM_OK) {
printf("config_reg(portH, mx21reg_initsys, INIT_LOOP_COUNT) failed\n");
goto func_out;
}
printf("Downloading to SDRAM at 0x%x via %s. File: %s\n",
download, port_name, file_name);
if (download_file(portH, file_name, download) != ROM_OK) {
printf("download_file() failed at line %d\n", __LINE__);
goto func_out;
}
// execute
SET_ADDR(irom_exec, download);
if (op_header(portH, irom_exec, &result) != ROM_OK) {
printf("Failed to exec\n");
goto func_out;
}
printf("\nJumping to 0x%08x\n", download);
if (op_header(portH, irom_status, &result) != ROM_OK)
goto func_out;
break;
case ENUM_NOR:
SET_TGT_ADDR_FOR_FLASH(download);
if ((fp = fopen(file_name,"rb")) == NULL) {
printf("\nUnable to open file: %s\n", file_name);
return ERR_FILE_NOT_OPEN;
}
if ((total = filelength(fileno(fp))) == 0 || total > 0x2000000 /* 32MB max*/) {
printf("File has invalid size %d.\n", total);
return ERR_FILE_ZERO_BYTE;
}
if (!fp) {
fclose(fp);
}
SET_SIZE_FOR_FLASH(total);
if (config_reg(portH, mx21reg_initsys, INIT_LOOP_COUNT) != ROM_OK) {
printf("config_reg(portH, mx21reg_initsys, INIT_LOOP_COUNT) failed\n");
goto func_out;
}
if (debug) printf("Downloading to SDRAM at 0x%x via %s. File: %s\n",
SERIAL_DOWNLOAD_SRC_ADDR, port_name, file_name);
printf("Downloading\n");
if (download_file(portH, file_name, SERIAL_DOWNLOAD_SRC_ADDR) != ROM_OK) {
printf("download_file() failed at line %d\n", __LINE__);
goto func_out;
}
if (debug)printf("Downloading .dat to SDRAM at 0x%x via %s. File: %s\n",
FLASH_CODE_ADDR, port_name, "./flash_code");
if (download_file(portH, "./flash_code", FLASH_CODE_ADDR) != ROM_OK) {
printf("download_file() failed at line %d\n", __LINE__);
goto func_out;
}
// execute
SET_ADDR(irom_exec, FLASH_CODE_ADDR);
if (op_header(portH, irom_exec, &result) != ROM_OK) {
printf("Failed to exec\n");
goto func_out;
}
op_header(portH, irom_status, &result);
if (PurgeComm(portH, PURGE_RXABORT|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_TXCLEAR) == 0) {
printf("PurgeComm() failed\n");
return ROM_ERROR;
}
Shutdown_Port(portH);
if ((portH = Open_Port(port_name, CBR_115200)) == INVALID_HANDLE_VALUE) {
printf("Error: %s is in use\n", port_name);
return -1;
}
printf("\nStart erasing\n");
while (1) {
unsigned char c, cc[9];
printf(".");
if (ReadFile(portH, &c, 1, &bytes_read, NULL) == 0) {
printf("\nReadFile failed at line: %d\n", __LINE__);
goto func_out;
}
if (debug) printf("%c", c);
if (c == '\n') {
if (ReadFile(portH, &cc, 8, &bytes_read, NULL) == 0) {
printf("\nReadFile failed at line: %d\n", __LINE__);
goto func_out;
}
cc[8] = 0;
if (debug) printf("cc=%s\n", cc);
if (memcmp(cc, "BEADDEAD", 8) == 0) {
printf("\nErase failed\n");
goto func_out;
} else if (memcmp(cc, "BEADBEEF", 8) == 0) {
printf("\nErase ok. Start programming\n");
} else if (memcmp(cc, "BEADFEEF", 8) == 0) {
printf("\nProgram failed\n");
goto func_out;
} else if (memcmp(cc, "BEADCEEF", 8) == 0) {
printf("\nProgram ok\n");
goto func_out;
}
}
}
break;
case ENUM_NAND:
break;
}
func_out:
if (!fp) fclose(fp);
Shutdown_Port(portH);
exit (0);
help_msg:
PRINT_HELP_MSG(argv[0]);
exit (-1);
help_msg_short:
printf("Type %s without argument for help\n", argv[0]);
exit(-1);
}
/*!
* Open a serial port for reading or writing.
*/
HANDLE Open_Port(char* pcCommPort, int baud)
{
HANDLE hCom;
if (debug) printf("\nOpen_Port for RW Opening = %s \n",pcCommPort);
hCom = CreateFile (pcCommPort, // Pointer to the name of the port
GENERIC_READ | GENERIC_WRITE, // Access (read-write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING, // How to open the port
0, // Port attributes
NULL); // Handle to port with attribute
if (hCom == INVALID_HANDLE_VALUE) {
// Handle the error.
printf ("CreateFile failed with error %d.\n", GetLastError());
return INVALID_HANDLE_VALUE;
}
else {
if (debug) printf("Setting up port %s with baud=%d\n", pcCommPort, baud);
if (Setup_Port(hCom, baud) == 0) {
if (debug) printf ("Serial port %s successfully reconfigured.\n", pcCommPort);
} else
return INVALID_HANDLE_VALUE;
}
return hCom;
}
/*!
* Close a port with a serial or parallel port printer.
*/
void Shutdown_Port(HANDLE portH)
{
if (portH != NULL)
CloseHandle(portH);
}
/*!
* Setup the serial or parallel port currently selected with specific baud rate
*/
int Setup_Port(HANDLE hCom, int baud)
{
DCB dcb;
COMMTIMEOUTS CommTimeouts;
// Build on the current configuration, and skip setting the size
// of the input and output buffers with SetupComm.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -