⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c.svn-base

📁 通过并口就能对CC2430 烧写程序
💻 SVN-BASE
字号:
/* * 2430prg - Programming CC2430 devices using the CC2430 cable project * * Copyright Otávio Ribeiro @ 2007 * otavio@otavio.eng.br * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU Library General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA */#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <string.h>#include <stdio.h>#include <limits.h>#include <signal.h>#include <sys/resource.h>#include "config.h"#include "driver.h"#include "cc2430.h"#include "parport.h"#ifdef ENABLE_NLS#  include <libintl.h>#  undef _#  define _(String) dgettext (PACKAGE, String)#else#  define _(String) (String)#endif#define PARPORT_DEFAULT_DEVICE "/dev/parport0"#define FLAG_BULK_ERASE			0x01#define FLAG_PROTECT			0x02#define FLAG_USE_IO				0x04#define FLAG_USE_PPDEV			0x08enum input_format {	FORMAT_BIN = 1,	FORMAT_HEX};enum option {	OPT_DEV = 0,	OPT_BULK_ERASE,	OPT_PROTECT,	OPT_CHECK,	OPT_VERSION,	OPT_HELP,	OPT_READ,	OPT_FILE_FORMAT,	OPT_DEBUG,	OPT_IO_PORT,	OPT_UNKNOWN};enum param {	no_argument,	required_argument,	optional_algument};struct available_file_format {	enum input_format format_id;	char* format;};static struct available_file_format formats[] = {	{FORMAT_BIN,"bin"},	{FORMAT_HEX,"hex"},	{0,NULL}};struct available_option {	char* option;	enum option option_id;	enum param param_info;};static struct available_option options[] = {	{"-d",OPT_DEV,required_argument},			//overwrite the default parallel port device	{"-a",OPT_IO_PORT,optional_algument},		//parallel port io address to be used with a direct access	{"-e",OPT_BULK_ERASE,no_argument}, 			//if protected, bulk erase the device before programming	{"-p",OPT_PROTECT,no_argument},				//after programming, protected the device	{"-c",OPT_CHECK,no_argument},				//only check the cable and devie without programming anything	{"-r",OPT_READ,no_argument},				//try to read the device to the file instead writing	{"-f",OPT_FILE_FORMAT,required_argument},	//input file format	{"-t",OPT_DEBUG,no_argument},				//test mode used to debug our software	{"--version",OPT_VERSION,no_argument},		//show the version message	{"--help",OPT_HELP,no_argument},			//show the help message	{"-v",OPT_VERSION,no_argument},				//show the version message	{"-h",OPT_HELP,no_argument},				//show the version message	{"",OPT_UNKNOWN,no_argument},				//unknown option	{NULL,0,0},};enum mode {	OP_READ,	OP_WRITE,	OP_CHECK,	OP_DEBUG};struct chip_ids {	unsigned char id;	char* name;};static struct chip_ids ids[] = {	{0x01,"CC1110"},	{0x85,"CC2430"},	{0x89,"CC2431"},	{0x81,"CC2510"},	{0x91,"CC2511"},	{0x00,NULL},};//// what we have to do//static enum mode todo;//// parport device name//static char device_name[PATH_MAX];//// io port address//unsigned int pport_address;//// file name0//static char file_name[PATH_MAX];//// flags//static unsigned char flags;//// input file format//static enum input_format format;//// binary data to write or read//static char* binary_content = NULL;//// binary content size//unsigned long int content_length = 0;int _off = 0;void __exit(int sig){	_off = 1;	printf("\n\nexiting...\n\n");}//// Check and print chip information//static char check_chip_id(unsigned char chip_id){	int i = 0;	struct chip_ids* sIds = ids;	while(sIds[i].name != NULL){		if(chip_id == sIds[i].id){			printf(_("%s found...\n"),sIds[i].name);			return i;		}		i++;	}		printf(_("ERROR: Invalid chip ID\n"));	return -1;}//// Show version message//static void show_version_message(){	printf(_("2430prg version 1.0\n"				"Copywrite (C) Otávio Ribeiro <otavio@otavio.eng.br> @ 2007\n\n"));}//// Show usage message//static void show_usage_message(){	printf(_("2430prg [options]... FILE\n"				"Copywrite (C) Otávio Ribeiro <otavio@otavio.eng.br> @ 2007\n\n"				"-d\t\tOverwrite the default parallel port device to use - ppdev device name\n"				"-a\t\tParallel port address, to be used with direct accress only\n"				"  \t\tAddress 0x378 is used by default\n"				"-e\t\tbulk erase the device before programming it\n"				"-p\t\tafter programming the device protect it from reading\n"				"-c\t\tjust check the device without read or write on it\n"				"-f\t\tinput file format\n"				"  \t\tbin - binary file format\n"				"  \t\thex - intel hexadecimal file format\n"				"-t\t\ttest mode - use it to debug\n"				"-v\t\tshow the version of this software\n"				"-h\t\tshow this message\n\n"));}static struct available_option* find_option(char* str){	struct available_option *option = NULL;	int i = 0;		while(options[i].option != NULL){		if(strcmp(options[i].option,str) == 0 || (options[i].option_id == OPT_UNKNOWN && str[0] == '-') ){			option = &options[i];			break;		}		i++;	}		return option;}static unsigned char find_file_format(char* param){	int i = 0;	while(formats[i].format != NULL){		if(strcmp(formats[i].format,param) == 0){			return formats[i].format_id;		}		i++;	}	return 0;}//// Parses the command line options send to us//static int parse_main_options(int argc, char** argv){	int i = 1;	char* str, *param;	struct available_option* option;		if(argc <= 1){		show_usage_message();		return -1;	} else {		for(i = 1; i < argc; i++){			str = argv[i];			if(str == NULL)				continue;			option = find_option(str);			if(option == NULL){				strcpy(file_name, str);				continue;			}						param = argv[i+1];			if(param == NULL || option->param_info != required_argument || (find_option(param) != NULL && i == argc-1)){				param = NULL;			} else {				i++;			}						if(option == NULL){				printf(_("the option %s is not a valid option. Use --help to see all available options.\n"),str);				return -1;			}			if(option->param_info == required_argument && param == NULL){				printf(_("the option %s requires an argument. Use --help to see all available options.\n"),str);				return -1;			}						switch(option->option_id){				case OPT_DEV:					strcpy(device_name,param);					flags |= FLAG_USE_PPDEV;					break;								case OPT_IO_PORT:					flags |= FLAG_USE_IO;					if(param == NULL)						pport_address = 0x378;					else						pport_address = atoi(param);											break;									case OPT_BULK_ERASE:					flags |= FLAG_BULK_ERASE;					break;								case OPT_PROTECT:					flags |= FLAG_PROTECT;					break;									case OPT_READ:					todo = OP_READ;					break;									case OPT_CHECK:					todo = OP_CHECK;					break;									case OPT_DEBUG:					todo = OP_DEBUG;					break;									case OPT_FILE_FORMAT:					format = find_file_format(param);					if(format == 0){						printf(_("Invalid file format. Use --help to check the availables formats."));						return -1;					}					break;				case OPT_VERSION:					show_version_message();					return -1;								case OPT_HELP:					show_usage_message();					return -1;								case OPT_UNKNOWN:					printf(_("unknown parameter %s. Ignored...\n"),str);					break;								default:					return -1;			}		}	}		if( (flags & FLAG_USE_IO) && (flags & FLAG_USE_PPDEV) ){		printf(_("The options -a and -d can not be used together.\nUse --help to see how to use this software\n"));		return -1;	}	if( ( (flags & FLAG_PROTECT) || (flags & FLAG_BULK_ERASE)  ) && (todo == OP_CHECK || todo == OP_DEBUG)){		printf(_("The options -e and -p are incompatible with -c.\nUse --help to see how to use this software\n"));		return -1;	}		if( ( (flags & FLAG_PROTECT) || (flags & FLAG_BULK_ERASE)  ) && (todo == OP_CHECK || todo == OP_DEBUG)){		printf(_("The options -e and -p are incompatible with -c.\nUse --help to see how to use this software\n"));		return -1;	}	if(file_name[0] == 0 && todo != OP_CHECK && todo != OP_DEBUG){		printf(_("You must provide a file name. Use --help to see how to use this software.\n"));		return -1;	}		return 0;}static int read_file(char* file_name){	FILE * fp;	long int file_len;	char * content;	size_t read;	int ret = 0;		if((fp = fopen(file_name,"r")) == NULL){		printf(_("Error opening file: %s\n"),file_name);		return -1;	}		fseek(fp,0,SEEK_END);	file_len = ftell(fp);	fseek(fp,0,SEEK_SET);		content = (char*)malloc(file_len);		read = fread(content,sizeof(char),file_len,fp);	if(read == file_len){		if(format == FORMAT_BIN){			binary_content = content;			content_length = file_len;		} else if(format == FORMAT_HEX){			printf(_("HEX file format not implemented\n"));			ret = -1;		}	} else {		printf(_("Error reading file.\n"));		ret = -1;	}		if(format != FORMAT_BIN || ret != 0)		free(content);		fclose(fp);	return ret;}static char verify_content(){	char ret = 1;	char* buffer;	unsigned long int len = content_length;		//	// check only the first 32Kb	//	if(len >= 0x8000){		len = 0x7FFF;	}		buffer = malloc(len);		//	// Read the content from device flash memory	//	if(cc2430_read_content(&buffer,						len,						0,						0) >= len){									if(memcmp(buffer,binary_content,len) == 0)			ret = 0;						}			free(buffer);	return ret;}static unsigned long int write_to_device(){	int ret = 0;		if(binary_content == NULL)		return 0;			//	// enable the 32MHz clock	//	if(cc2430_init_clock()){		printf(_("Error enabling the 32MHz clock\n"));		return 0;	}			//	// set up flash timing	//	if(cc2430_set_flash_timing(FLASH_32MHZ) != FLASH_32MHZ){		printf(_("Error enabling the flash timer\n"));		return 0;	}		ret = cc2430_write_content(binary_content,							content_length,							4,							512,							0);		return ret;}void debug_device(){ 	unsigned int jmp_addr = 0x0000; 	char * msg; 	unsigned char status, discard; 	unsigned short int pc;	//	// enable the 32MHz clock	//	if(cc2430_init_clock()){		printf(_("Error enabling the 32MHz clock\n"));		return 0;	}			msg = malloc(256); 	//set PC to 0x0000 	cc2430_send_inst3(0x02,HIWORD(jmp_addr),LOWORD(jmp_addr),&discard);		//ljmp 0x0000 	 	do{	 	//start executing our code		printf("resuming...\n");		cc2430_resume();				//wait for a breakpoint to read the message		do{			cc2430_get_status(&status);		} while( !(status & 0x20) && _off != 1);				pc = cc2430_get_pc();				if(_off != 1){			printf("reading message\n");			cc2430_read_debug_string(&msg,255,0xE000);			printf("debug message --> %s\n",msg);		}				pc++; 		cc2430_send_inst3(0x02,HIWORD(pc),LOWORD(pc),&discard);		//ljmp PC+1		  	} while(_off != 1); 	 	free(msg);}int main(int argc, char** argv){	cc2430_cable_status cable_status;	unsigned short int chip_info;	unsigned char chip_id, chip_revision, status;	void * drv_param;		//	// Setup with the default parallel port device.	// That can be overwrited later using the command line.	//	strcpy(device_name,PARPORT_DEFAULT_DEVICE);	flags = 0;	todo = OP_WRITE;	format = FORMAT_BIN;		//	// No file name	//	file_name[0] = 0;	if(parse_main_options(argc,argv) < 0)		return -1;		//	// All C applications, by default are started with 'C' locale by default.	// The next call inform the libc to use the system environment locale.	//	setlocale(LC_ALL,"");		signal(SIGINT,__exit);	signal(SIGHUP,__exit);	signal(SIGQUIT,__exit);	signal(SIGTERM,__exit);		//	// Setup the gettext domain to look for messages catalog	//#ifdef ENABLE_NLS	bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);	textdomain(GETTEXT_PACKAGE);#endif	     printf(_("2430prg initializing\n"));        if(flags & FLAG_USE_IO){    	printf(_("2430prg using direct access I/O driver on port: 0x%x\n"),pport_address);    	parport_register(io_driver);    	drv_param = &pport_address;    } else {	    	printf(_("2430prg using PPDEV driver on device: %s\n"),device_name);    	parport_register(ppdev_driver);    	drv_param = device_name;    }		if(!parport_open(drv_param))		printf(_("error opening parallel port..\n"));			if(!parport_init())			printf(_("error initializing parallel port..\n"));		// check if the cable is connected	if(!parport_detect_cable(&cable_status)){		printf(_("error detecting the CC2430 cable\n"));		goto exit;	}		// cable version		if(cable_status.version != 0 ){		printf(_("CC2430 cable has been found\n"));		if(cable_status.version == 1)			printf(_("CC2430 cable version 1.0 found\n"));	} else {		printf(_("CC2430 cable not connected\n"));			goto exit;	}	printf(_("Detecting CC2430 device type. Please Wait...\n"));		// start the CC2430 debug mode	if(!parport_start_debug_mode()){		printf(_("error entering in debug mode\n"));		goto exit;	}		//get the chip info	chip_info = cc2430_get_chip_info();		chip_revision = chip_info & 0xFF;	chip_id = (chip_info >> 8) & 0xFF;		if(check_chip_id(chip_id) < 0){		goto exit;	}		printf(_("Chip revision = %d\n"),chip_revision);		if(cc2430_get_status(&status)){		printf(_("error reading debug status register\n"));		goto exit;	}		printf(_("Debug Status = 0x%x\n"),status);		switch(todo){		case OP_DEBUG:			debug_device();			break;					case OP_READ:			break;				case OP_WRITE:					if(flags & FLAG_BULK_ERASE){				printf(_("Erasing device\n"));				if(cc2430_chip_erase()){					printf(_("Error erasing device\n"));					goto exit;				}								do{					if(cc2430_get_status(&status)){						printf(_("error reading debug status register\n"));						goto exit;					}					usleep(1);				} while(!(status & 0x80));			}					printf(_("reading file %s \n"),file_name);			if(read_file(file_name)){				printf(_("Error trying to read file: %s\n"),file_name);				goto exit;			}						printf(_("Writing binary data to device\n"));			if(write_to_device() < content_length){				printf(_("Error writing binary data to device\n"));				goto exit;			} 						printf(_("Verifying data...\n"));			if(verify_content()){				printf(_("Verification error. The data wrote to device is different from file.\n"));				goto exit;			}						//			// reset the device and run the uploaded code			//			parport_reset();						break;					default:			break;	}									exit:	if(binary_content != NULL){		free(binary_content);	}	parport_close();	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -