feeds: remove bluetooth-cc2652 feed

Remove the old and unused bluetooth-cc2652 feed which provided BLE
scanning and firmware flashing support for TI CC2652 chips.

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2025-10-19 00:00:00 +02:00
parent 207a592896
commit 82cb988e56
34 changed files with 0 additions and 8418 deletions

View File

@@ -1,29 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ble_scan
PKG_VERSION:=1.0
PKG_BUILD_DIR:= $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/ble_scan
SECTION:=base
CATEGORY:=Utilities
TITLE:=ble_scan
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Package/ble_scan/install
$(INSTALL_DIR) $(1)/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ble_scan $(1)/bin/
endef
define Package/ble_scan/extra_provides
echo "libc.so.6";
endef
$(eval $(call BuildPackage,ble_scan))

View File

@@ -1,47 +0,0 @@
#all: ble_scan
#ble_scan: ble_scan.o
# $(CC) $(LDFLAGS) ble_scan.o -o ble_scan
#blescan.o: ble_scan.c
# $(CC) $(CFLAGS) -c ble_scan.c
#clean:
# rm *.o ble_scan
#
#
# Author: Teunis van Beelen
#
# email: teuniz@protonmail.com
#
#
#CROSS-COMPILE:=../../../../../qsdk/staging_dir/toolchain-arm/bin/arm-openwrt-linux-
#CC:=$(CROSS-COMPILE)gcc
CC = gcc
CFLAGS = -Wall -Wextra -Wshadow -Wformat-nonliteral -Wformat-security -Wtype-limits -O2
objects = rs232.o
all: ble_scan
ble_scan : $(objects) ble_scan.o
$(CC) $(CFLAGS) $(objects) ble_scan.o -o ble_scan
ble_scan.o : ble_scan.c rs232.h
$(CC) $(CFLAGS) -c ble_scan.c -o ble_scan.o
rs232.o : rs232.h rs232.c
$(CC) $(CFLAGS) -c rs232.c -o rs232.o
clean :
$(RM) ble_scan $(objects) ble_scan.o
#
#
#
#

View File

@@ -1,387 +0,0 @@
/**************************************************
file: ble_scan.c
purpose: Send HCI command to do BLE scan
compile with the command: gcc ble_scan.c rs232.c -Wall -Wextra -o2 -o ble_scan
**************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
#include "rs232.h"
#define TX 0
#define RX 1
#define BUF_SIZE 4095
#define FULL_BUF_SIZE BUF_SIZE*4
//#define DEBUG
#ifdef DEBUG
#else
#endif
int print_hex(int mode, unsigned char *buf, int size);
int rx_pkt_parser(unsigned char *buf, int size);
struct rx_packet_h{
unsigned char rxType;
unsigned char rxEventCode;
unsigned char rxDataLen;
unsigned char Event[2];
unsigned char Status;
};
struct event_cmd_st_h{
unsigned char OpCode[2];
unsigned char DataLength;
};
struct event_scn_evnt_rep_h{
unsigned char EventId[4];
unsigned char AdvRptEventType;
unsigned char AddressType;
unsigned char Address[6];
unsigned char PrimaryPHY;
unsigned char SecondaryPHY;
unsigned char AdvSid;
unsigned char TxPower;
unsigned char RSSI;
unsigned char DirectAddrType;
unsigned char DirectAddr[6];
unsigned char PeriodicAdvInt[2];
unsigned char DataLength[2];
//unsigned char *DataPtr;
};
int main()
{
int cport_nr,bdrate,n;
//cport_nr=0, /* /dev/ttyS0 (COM1 on windows) */
//bdrate=9600; /* 9600 baud */
cport_nr=39, /* (ttyMSM1 : 39) */
bdrate=115200; /* 115200 baud */
#ifdef DEBUG
clock_t t;
#endif
char mode[]={'8','N','1',0};
unsigned char buf[BUF_SIZE];
unsigned char full_buf[FULL_BUF_SIZE];
int full_buf_ptr = 0;
unsigned char HCIExt_ResetSystemCmd[] = {0x01, 0x1D, 0xFC, 0x01, 0x00 };
int HCIExt_ResetSystemCmd_length = 5;
unsigned char GAP_DeviceInitCmd[] = {0x01, 0x00, 0xFE, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
int GAP_DeviceInitCmd_length = 12;
unsigned char GapScan_enableCmd[] = {0x01, 0x51, 0xFE, 0x06, 0x00, 0x00, 0xF4, 0x01, 0x28, 0x00 };
int GapScan_enableCmd_length = 10;
if(RS232_OpenComport(cport_nr, bdrate, mode, 0))
{
printf("Can not open comport\n");
return(0);
}
RS232_flushRXTX(cport_nr);
// send reset command
#ifdef DEBUG
t=clock();
print_hex(TX, HCIExt_ResetSystemCmd, HCIExt_ResetSystemCmd_length);
t=clock()-t;
printf("t=%ld\n",t); //60
#else
/* sleep for 60ms */
usleep(60000);
#endif
RS232_SendBuf(cport_nr, HCIExt_ResetSystemCmd, HCIExt_ResetSystemCmd_length);
/* sleep for 1 Second */
#ifdef DEBUG
t=clock();
#endif
usleep(1000000);
#ifdef DEBUG
t=clock()-t;
printf("CLOCKS_PER_SEC=%ld\n",t);
#endif
n = RS232_PollComport(cport_nr, buf, BUF_SIZE);
#ifdef DEBUG
t=clock();
print_hex(RX, buf, n);
t=clock()-t;
printf("t=%ld\n",t);
#else
/* sleep for 300ms */
usleep(300000);
#endif
// send device initial command
#ifdef DEBUG
t=clock();
print_hex(TX, GAP_DeviceInitCmd, GAP_DeviceInitCmd_length);
t=clock()-t;
printf("t=%ld\n",t);
#else
/* sleep for 250 ms */
usleep(250000);
#endif
RS232_SendBuf(cport_nr, GAP_DeviceInitCmd, GAP_DeviceInitCmd_length);
/* sleep for 0.5 Second */
usleep(500000);
n = RS232_PollComport(cport_nr, buf, BUF_SIZE);
#ifdef DEBUG
t=clock();
print_hex(RX, buf, n);
t=clock()-t;
printf("t=%ld\n",t);
#else
/* sleep for 500 ms */
usleep(500000);
#endif
// send scan command
#ifdef DEBUG
t=clock();
print_hex(TX, GapScan_enableCmd, GapScan_enableCmd_length);
t=clock()-t;
printf("t=%ld\n",t);
#else
/* sleep for 30ms */
usleep(30000);
#endif
RS232_SendBuf(cport_nr, GapScan_enableCmd, GapScan_enableCmd_length);
//read scan respone
while (n > 0)
{
/* sleep for 400 mS */
usleep(400000);
n = RS232_PollComport(cport_nr, buf, BUF_SIZE);
#ifdef DEBUG
t=clock();
print_hex(RX, buf, n);
t=clock()-t;
printf("t=%ld\n",t);
#endif
if (full_buf_ptr+n>FULL_BUF_SIZE)
{
#ifdef DEBUG
printf("buffer full. break.\n");
#endif
break;
}
memcpy(full_buf+full_buf_ptr, buf, n);
full_buf_ptr+=n;
#ifdef DEBUG
printf("n:%d, full_buf_ptr:%d\n",n, full_buf_ptr);
#endif
}
#ifdef DEBUG
print_hex(RX, full_buf, full_buf_ptr);
#endif
rx_pkt_parser( full_buf, full_buf_ptr);
#ifdef DEBUG
printf("n:%d, full_buf_ptr:%d\n",n, full_buf_ptr);
#endif
RS232_flushRXTX(cport_nr);
RS232_CloseComport(cport_nr);
return(0);
}
/**************************************************
Print buffer in HEX
**************************************************/
int print_hex(int mode, unsigned char *buf, int size)
{
int ii,jj;
if (mode == TX)
printf("TX: ");
else
printf("RX: ");
for(ii=0,jj=0; ii < size; ii++,jj++)
{
printf("%02X ",buf[ii]);
if (jj==15)
{
printf("\n");
jj = 0;
}
}
printf("\n");
return(0);
}
int rx_pkt_parser(unsigned char *buf, int size)
{
int pkt_index=0;
int pkt_size=0;
int temp_event=0;
int temp_EventId=0;
int total_device_count=0;
char szAddress[18];
struct rx_packet_h *rx_packet;
struct event_scn_evnt_rep_h *event_scn_evnt_rep;
#ifdef DEBUG
int dump_i=0;
unsigned char *pkt_ptr;
#endif
if(size<=0){printf("size error\n");return -1;}
printf("BLE scan start:\n");
rx_packet = (struct rx_packet_h *)(buf);
while(pkt_index<size)
{
#ifdef DEBUG
printf("--------------------------------------------------------------------\n");
printf("-Type : 0x%02X (%s)\n",rx_packet->rxType,rx_packet->rxType==0x4?"Event":"Unknown");
if(rx_packet->rxType!=0x4)
{
printf(" Type unknown, rxType:0x%02X, pkt_index:%d\n",rx_packet->rxType,pkt_index);
}
printf("-EventCode : 0x%02X (%s)\n",rx_packet->rxEventCode,rx_packet->rxEventCode==0xff?"HCI_LE_ExtEvent":"Unknown");
if(rx_packet->rxEventCode!=0xff)
{
printf(" EventCode unknown, rxEventCode:0x%02X, pkt_index:%d\n",rx_packet->rxEventCode,pkt_index);
}
printf("-Data Length : 0x%02X (%d) bytes(s)\n",rx_packet->rxDataLen,rx_packet->rxDataLen);
#endif
temp_event = (rx_packet->Event[1]<<8)+rx_packet->Event[0] ;
#ifdef DEBUG
printf(" Event : 0x%02X%02X (%d) ",rx_packet->Event[1],rx_packet->Event[0],temp_event);
if(temp_event==0x067F)
{
printf("(GAP_HCI_ExtentionCommandStatus)\n");
}
else if(temp_event==0x0600)
{
printf("(GAP_DeviceInitDone)\n");
}
else if(temp_event==0x0613)
{
printf("(GAP_AdvertiserScannerEvent)\n");
}
else
{
printf(" Event unknown, Event:0x%04X, pkt_index:%d\n",temp_event,pkt_index);
}
printf(" Status : 0x%02X (%d) (%s)\n",rx_packet->Status,rx_packet->Status,rx_packet->Status==0?"SUCCESS":"FAIL");
#endif
if(temp_event==0x0613)
{
event_scn_evnt_rep = (struct event_scn_evnt_rep_h *)(&(rx_packet->Status) + 1);
temp_EventId = (event_scn_evnt_rep->EventId[3]<<24) + (event_scn_evnt_rep->EventId[2]<<16) +
(event_scn_evnt_rep->EventId[1]<<8) + (event_scn_evnt_rep->EventId[0]) ;
#ifdef DEBUG
printf(" EventId : 0x%02X%02X%02X%02X (%d) ", event_scn_evnt_rep->EventId[3],
event_scn_evnt_rep->EventId[2],
event_scn_evnt_rep->EventId[1],
event_scn_evnt_rep->EventId[0],temp_EventId);
if(temp_EventId==0x00010000)
{
printf("(GAP_EVT_SCAN_ENABLED)\n");
}
else if(temp_EventId==0x00020000)
{
printf("(GAP_EVT_SCAN_DISABLED)\n");
}
else if(temp_EventId==0x00400000)
{
printf("(GAP_EVT_ADV_REPORT)\n");
}
else
{
printf(" EventId unknown, EventId:0x%08X, pkt_index:%d\n",temp_EventId,pkt_index);
}
#endif
if(temp_EventId==0x00400000)
{
sprintf(szAddress,"%02X:%02X:%02X:%02X:%02X:%02X", event_scn_evnt_rep->Address[5],
event_scn_evnt_rep->Address[4],
event_scn_evnt_rep->Address[3],
event_scn_evnt_rep->Address[2],
event_scn_evnt_rep->Address[1],
event_scn_evnt_rep->Address[0]);
#ifdef DEBUG
printf("%04d", total_device_count);
printf(" Address : %s", szAddress);
printf(" RSSI : 0x%02X (%d)(%d)",event_scn_evnt_rep->RSSI,event_scn_evnt_rep->RSSI,event_scn_evnt_rep->RSSI-256);
#else
printf(" Address: %s RSSI: %d", szAddress, event_scn_evnt_rep->RSSI-256);
#endif
printf("\n");
total_device_count++;
}
}
pkt_size = 3+rx_packet->rxDataLen;
#ifdef DEBUG
pkt_ptr = (unsigned char *)rx_packet;
printf(" <Info > Dump(Rx):");
for(dump_i=0; dump_i < pkt_size; dump_i++)
{
if (dump_i%16==0)
{
printf("\n");
printf("%04x:",dump_i);
}
printf("%02X ",pkt_ptr[dump_i]);
}
printf("\n");
#endif
pkt_index+=pkt_size;
#ifdef DEBUG
printf(" pkt_size:%d, pkt_index:%d\n",pkt_size,pkt_index);
#endif
rx_packet = (struct rx_packet_h *)(&(rx_packet->rxDataLen) + rx_packet->rxDataLen + 1);
}
printf("Total: %d Device found.\n",total_device_count);
return 0;
}

View File

@@ -1,879 +0,0 @@
/*
***************************************************************************
*
* Author: Teunis van Beelen
*
* Copyright (C) 2005 - 2021 Teunis van Beelen
*
* Email: teuniz@protonmail.com
*
***************************************************************************
*
* 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 3 of the License.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
***************************************************************************
*/
/* Last revision: February 9, 2021 */
/* For more info and how to use this library, visit: http://www.teuniz.net/RS-232/ */
#include "rs232.h"
#if defined(__linux__) || defined(__FreeBSD__) /* Linux & FreeBSD */
#define RS232_PORTNR 40
int Cport[RS232_PORTNR],
error;
struct termios new_port_settings,
old_port_settings[RS232_PORTNR];
const char *comports[RS232_PORTNR]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2","/dev/ttyS3","/dev/ttyS4","/dev/ttyS5",
"/dev/ttyS6","/dev/ttyS7","/dev/ttyS8","/dev/ttyS9","/dev/ttyS10","/dev/ttyS11",
"/dev/ttyS12","/dev/ttyS13","/dev/ttyS14","/dev/ttyS15","/dev/ttyUSB0",
"/dev/ttyUSB1","/dev/ttyUSB2","/dev/ttyUSB3","/dev/ttyUSB4","/dev/ttyUSB5",
"/dev/ttyAMA0","/dev/ttyAMA1","/dev/ttyACM0","/dev/ttyACM1",
"/dev/rfcomm0","/dev/rfcomm1","/dev/ircomm0","/dev/ircomm1",
"/dev/cuau0","/dev/cuau1","/dev/cuau2","/dev/cuau3",
"/dev/cuaU0","/dev/cuaU1","/dev/cuaU2","/dev/cuaU3",
"/dev/ttyMSM0","/dev/ttyMSM1"};
int RS232_OpenComport(int comport_number, int baudrate, const char *mode, int flowctrl)
{
int baudr,
status;
if((comport_number>=RS232_PORTNR)||(comport_number<0))
{
printf("illegal comport number\n");
return(1);
}
switch(baudrate)
{
case 50 : baudr = B50;
break;
case 75 : baudr = B75;
break;
case 110 : baudr = B110;
break;
case 134 : baudr = B134;
break;
case 150 : baudr = B150;
break;
case 200 : baudr = B200;
break;
case 300 : baudr = B300;
break;
case 600 : baudr = B600;
break;
case 1200 : baudr = B1200;
break;
case 1800 : baudr = B1800;
break;
case 2400 : baudr = B2400;
break;
case 4800 : baudr = B4800;
break;
case 9600 : baudr = B9600;
break;
case 19200 : baudr = B19200;
break;
case 38400 : baudr = B38400;
break;
case 57600 : baudr = B57600;
break;
case 115200 : baudr = B115200;
break;
case 230400 : baudr = B230400;
break;
case 460800 : baudr = B460800;
break;
#if defined(__linux__)
case 500000 : baudr = B500000;
break;
case 576000 : baudr = B576000;
break;
case 921600 : baudr = B921600;
break;
case 1000000 : baudr = B1000000;
break;
case 1152000 : baudr = B1152000;
break;
case 1500000 : baudr = B1500000;
break;
case 2000000 : baudr = B2000000;
break;
case 2500000 : baudr = B2500000;
break;
case 3000000 : baudr = B3000000;
break;
case 3500000 : baudr = B3500000;
break;
case 4000000 : baudr = B4000000;
break;
#endif
default : printf("invalid baudrate\n");
return(1);
break;
}
int cbits=CS8,
cpar=0,
ipar=IGNPAR,
bstop=0;
if(strlen(mode) != 3)
{
printf("invalid mode \"%s\"\n", mode);
return(1);
}
switch(mode[0])
{
case '8': cbits = CS8;
break;
case '7': cbits = CS7;
break;
case '6': cbits = CS6;
break;
case '5': cbits = CS5;
break;
default : printf("invalid number of data-bits '%c'\n", mode[0]);
return(1);
break;
}
switch(mode[1])
{
case 'N':
case 'n': cpar = 0;
ipar = IGNPAR;
break;
case 'E':
case 'e': cpar = PARENB;
ipar = INPCK;
break;
case 'O':
case 'o': cpar = (PARENB | PARODD);
ipar = INPCK;
break;
default : printf("invalid parity '%c'\n", mode[1]);
return(1);
break;
}
switch(mode[2])
{
case '1': bstop = 0;
break;
case '2': bstop = CSTOPB;
break;
default : printf("invalid number of stop bits '%c'\n", mode[2]);
return(1);
break;
}
/*
http://pubs.opengroup.org/onlinepubs/7908799/xsh/termios.h.html
http://man7.org/linux/man-pages/man3/termios.3.html
*/
Cport[comport_number] = open(comports[comport_number], O_RDWR | O_NOCTTY | O_NDELAY);
if(Cport[comport_number]==-1)
{
perror("unable to open comport ");
return(1);
}
/* lock access so that another process can't also use the port */
if(flock(Cport[comport_number], LOCK_EX | LOCK_NB) != 0)
{
close(Cport[comport_number]);
perror("Another process has locked the comport.");
return(1);
}
error = tcgetattr(Cport[comport_number], old_port_settings + comport_number);
if(error==-1)
{
close(Cport[comport_number]);
flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */
perror("unable to read portsettings ");
return(1);
}
memset(&new_port_settings, 0, sizeof(new_port_settings)); /* clear the new struct */
new_port_settings.c_cflag = cbits | cpar | bstop | CLOCAL | CREAD;
if(flowctrl)
{
new_port_settings.c_cflag |= CRTSCTS;
}
new_port_settings.c_iflag = ipar;
new_port_settings.c_oflag = 0;
new_port_settings.c_lflag = 0;
new_port_settings.c_cc[VMIN] = 0; /* block untill n bytes are received */
new_port_settings.c_cc[VTIME] = 0; /* block untill a timer expires (n * 100 mSec.) */
cfsetispeed(&new_port_settings, baudr);
cfsetospeed(&new_port_settings, baudr);
error = tcsetattr(Cport[comport_number], TCSANOW, &new_port_settings);
if(error==-1)
{
tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number);
close(Cport[comport_number]);
flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */
perror("unable to adjust portsettings ");
return(1);
}
/* http://man7.org/linux/man-pages/man4/tty_ioctl.4.html */
if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1)
{
tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number);
flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */
perror("unable to get portstatus");
return(1);
}
status |= TIOCM_DTR; /* turn on DTR */
status |= TIOCM_RTS; /* turn on RTS */
if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1)
{
tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number);
flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */
perror("unable to set portstatus");
return(1);
}
return(0);
}
int RS232_PollComport(int comport_number, unsigned char *buf, int size)
{
int n;
n = read(Cport[comport_number], buf, size);
if(n < 0)
{
if(errno == EAGAIN) return 0;
}
return(n);
}
int RS232_SendByte(int comport_number, unsigned char byte)
{
int n = write(Cport[comport_number], &byte, 1);
if(n < 0)
{
if(errno == EAGAIN)
{
return 0;
}
else
{
return 1;
}
}
return(0);
}
int RS232_SendBuf(int comport_number, unsigned char *buf, int size)
{
int n = write(Cport[comport_number], buf, size);
if(n < 0)
{
if(errno == EAGAIN)
{
return 0;
}
else
{
return -1;
}
}
return(n);
}
void RS232_CloseComport(int comport_number)
{
int status;
if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1)
{
perror("unable to get portstatus");
}
status &= ~TIOCM_DTR; /* turn off DTR */
status &= ~TIOCM_RTS; /* turn off RTS */
if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1)
{
perror("unable to set portstatus");
}
tcsetattr(Cport[comport_number], TCSANOW, old_port_settings + comport_number);
close(Cport[comport_number]);
flock(Cport[comport_number], LOCK_UN); /* free the port so that others can use it. */
}
/*
Constant Description
TIOCM_LE DSR (data set ready/line enable)
TIOCM_DTR DTR (data terminal ready)
TIOCM_RTS RTS (request to send)
TIOCM_ST Secondary TXD (transmit)
TIOCM_SR Secondary RXD (receive)
TIOCM_CTS CTS (clear to send)
TIOCM_CAR DCD (data carrier detect)
TIOCM_CD see TIOCM_CAR
TIOCM_RNG RNG (ring)
TIOCM_RI see TIOCM_RNG
TIOCM_DSR DSR (data set ready)
http://man7.org/linux/man-pages/man4/tty_ioctl.4.html
*/
int RS232_IsDCDEnabled(int comport_number)
{
int status;
ioctl(Cport[comport_number], TIOCMGET, &status);
if(status&TIOCM_CAR) return(1);
else return(0);
}
int RS232_IsRINGEnabled(int comport_number)
{
int status;
ioctl(Cport[comport_number], TIOCMGET, &status);
if(status&TIOCM_RNG) return(1);
else return(0);
}
int RS232_IsCTSEnabled(int comport_number)
{
int status;
ioctl(Cport[comport_number], TIOCMGET, &status);
if(status&TIOCM_CTS) return(1);
else return(0);
}
int RS232_IsDSREnabled(int comport_number)
{
int status;
ioctl(Cport[comport_number], TIOCMGET, &status);
if(status&TIOCM_DSR) return(1);
else return(0);
}
void RS232_enableDTR(int comport_number)
{
int status;
if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1)
{
perror("unable to get portstatus");
}
status |= TIOCM_DTR; /* turn on DTR */
if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1)
{
perror("unable to set portstatus");
}
}
void RS232_disableDTR(int comport_number)
{
int status;
if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1)
{
perror("unable to get portstatus");
}
status &= ~TIOCM_DTR; /* turn off DTR */
if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1)
{
perror("unable to set portstatus");
}
}
void RS232_enableRTS(int comport_number)
{
int status;
if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1)
{
perror("unable to get portstatus");
}
status |= TIOCM_RTS; /* turn on RTS */
if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1)
{
perror("unable to set portstatus");
}
}
void RS232_disableRTS(int comport_number)
{
int status;
if(ioctl(Cport[comport_number], TIOCMGET, &status) == -1)
{
perror("unable to get portstatus");
}
status &= ~TIOCM_RTS; /* turn off RTS */
if(ioctl(Cport[comport_number], TIOCMSET, &status) == -1)
{
perror("unable to set portstatus");
}
}
void RS232_flushRX(int comport_number)
{
tcflush(Cport[comport_number], TCIFLUSH);
}
void RS232_flushTX(int comport_number)
{
tcflush(Cport[comport_number], TCOFLUSH);
}
void RS232_flushRXTX(int comport_number)
{
tcflush(Cport[comport_number], TCIOFLUSH);
}
#else /* windows */
#define RS232_PORTNR 32
HANDLE Cport[RS232_PORTNR];
const char *comports[RS232_PORTNR]={"\\\\.\\COM1", "\\\\.\\COM2", "\\\\.\\COM3", "\\\\.\\COM4",
"\\\\.\\COM5", "\\\\.\\COM6", "\\\\.\\COM7", "\\\\.\\COM8",
"\\\\.\\COM9", "\\\\.\\COM10", "\\\\.\\COM11", "\\\\.\\COM12",
"\\\\.\\COM13", "\\\\.\\COM14", "\\\\.\\COM15", "\\\\.\\COM16",
"\\\\.\\COM17", "\\\\.\\COM18", "\\\\.\\COM19", "\\\\.\\COM20",
"\\\\.\\COM21", "\\\\.\\COM22", "\\\\.\\COM23", "\\\\.\\COM24",
"\\\\.\\COM25", "\\\\.\\COM26", "\\\\.\\COM27", "\\\\.\\COM28",
"\\\\.\\COM29", "\\\\.\\COM30", "\\\\.\\COM31", "\\\\.\\COM32"};
char mode_str[128];
int RS232_OpenComport(int comport_number, int baudrate, const char *mode, int flowctrl)
{
if((comport_number>=RS232_PORTNR)||(comport_number<0))
{
printf("illegal comport number\n");
return(1);
}
switch(baudrate)
{
case 110 : strcpy(mode_str, "baud=110");
break;
case 300 : strcpy(mode_str, "baud=300");
break;
case 600 : strcpy(mode_str, "baud=600");
break;
case 1200 : strcpy(mode_str, "baud=1200");
break;
case 2400 : strcpy(mode_str, "baud=2400");
break;
case 4800 : strcpy(mode_str, "baud=4800");
break;
case 9600 : strcpy(mode_str, "baud=9600");
break;
case 19200 : strcpy(mode_str, "baud=19200");
break;
case 38400 : strcpy(mode_str, "baud=38400");
break;
case 57600 : strcpy(mode_str, "baud=57600");
break;
case 115200 : strcpy(mode_str, "baud=115200");
break;
case 128000 : strcpy(mode_str, "baud=128000");
break;
case 256000 : strcpy(mode_str, "baud=256000");
break;
case 500000 : strcpy(mode_str, "baud=500000");
break;
case 921600 : strcpy(mode_str, "baud=921600");
break;
case 1000000 : strcpy(mode_str, "baud=1000000");
break;
case 1500000 : strcpy(mode_str, "baud=1500000");
break;
case 2000000 : strcpy(mode_str, "baud=2000000");
break;
case 3000000 : strcpy(mode_str, "baud=3000000");
break;
default : printf("invalid baudrate\n");
return(1);
break;
}
if(strlen(mode) != 3)
{
printf("invalid mode \"%s\"\n", mode);
return(1);
}
switch(mode[0])
{
case '8': strcat(mode_str, " data=8");
break;
case '7': strcat(mode_str, " data=7");
break;
case '6': strcat(mode_str, " data=6");
break;
case '5': strcat(mode_str, " data=5");
break;
default : printf("invalid number of data-bits '%c'\n", mode[0]);
return(1);
break;
}
switch(mode[1])
{
case 'N':
case 'n': strcat(mode_str, " parity=n");
break;
case 'E':
case 'e': strcat(mode_str, " parity=e");
break;
case 'O':
case 'o': strcat(mode_str, " parity=o");
break;
default : printf("invalid parity '%c'\n", mode[1]);
return(1);
break;
}
switch(mode[2])
{
case '1': strcat(mode_str, " stop=1");
break;
case '2': strcat(mode_str, " stop=2");
break;
default : printf("invalid number of stop bits '%c'\n", mode[2]);
return(1);
break;
}
if(flowctrl)
{
strcat(mode_str, " xon=off to=off odsr=off dtr=on rts=off");
}
else
{
strcat(mode_str, " xon=off to=off odsr=off dtr=on rts=on");
}
/*
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363145%28v=vs.85%29.aspx
http://technet.microsoft.com/en-us/library/cc732236.aspx
https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_dcb
*/
Cport[comport_number] = CreateFileA(comports[comport_number],
GENERIC_READ|GENERIC_WRITE,
0, /* no share */
NULL, /* no security */
OPEN_EXISTING,
0, /* no threads */
NULL); /* no templates */
if(Cport[comport_number]==INVALID_HANDLE_VALUE)
{
printf("unable to open comport\n");
return(1);
}
DCB port_settings;
memset(&port_settings, 0, sizeof(port_settings)); /* clear the new struct */
port_settings.DCBlength = sizeof(port_settings);
if(!BuildCommDCBA(mode_str, &port_settings))
{
printf("unable to set comport dcb settings\n");
CloseHandle(Cport[comport_number]);
return(1);
}
if(flowctrl)
{
port_settings.fOutxCtsFlow = TRUE;
port_settings.fRtsControl = RTS_CONTROL_HANDSHAKE;
}
if(!SetCommState(Cport[comport_number], &port_settings))
{
printf("unable to set comport cfg settings\n");
CloseHandle(Cport[comport_number]);
return(1);
}
COMMTIMEOUTS Cptimeouts;
Cptimeouts.ReadIntervalTimeout = MAXDWORD;
Cptimeouts.ReadTotalTimeoutMultiplier = 0;
Cptimeouts.ReadTotalTimeoutConstant = 0;
Cptimeouts.WriteTotalTimeoutMultiplier = 0;
Cptimeouts.WriteTotalTimeoutConstant = 0;
if(!SetCommTimeouts(Cport[comport_number], &Cptimeouts))
{
printf("unable to set comport time-out settings\n");
CloseHandle(Cport[comport_number]);
return(1);
}
return(0);
}
int RS232_PollComport(int comport_number, unsigned char *buf, int size)
{
int n;
/* added the void pointer cast, otherwise gcc will complain about */
/* "warning: dereferencing type-punned pointer will break strict aliasing rules" */
if(!ReadFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL))
{
return -1;
}
return(n);
}
int RS232_SendByte(int comport_number, unsigned char byte)
{
int n;
if(!WriteFile(Cport[comport_number], &byte, 1, (LPDWORD)((void *)&n), NULL))
{
return(1);
}
if(n<0) return(1);
return(0);
}
int RS232_SendBuf(int comport_number, unsigned char *buf, int size)
{
int n;
if(WriteFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL))
{
return(n);
}
return(-1);
}
void RS232_CloseComport(int comport_number)
{
CloseHandle(Cport[comport_number]);
}
/*
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363258%28v=vs.85%29.aspx
*/
int RS232_IsDCDEnabled(int comport_number)
{
int status;
GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status));
if(status&MS_RLSD_ON) return(1);
else return(0);
}
int RS232_IsRINGEnabled(int comport_number)
{
int status;
GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status));
if(status&MS_RING_ON) return(1);
else return(0);
}
int RS232_IsCTSEnabled(int comport_number)
{
int status;
GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status));
if(status&MS_CTS_ON) return(1);
else return(0);
}
int RS232_IsDSREnabled(int comport_number)
{
int status;
GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status));
if(status&MS_DSR_ON) return(1);
else return(0);
}
void RS232_enableDTR(int comport_number)
{
EscapeCommFunction(Cport[comport_number], SETDTR);
}
void RS232_disableDTR(int comport_number)
{
EscapeCommFunction(Cport[comport_number], CLRDTR);
}
void RS232_enableRTS(int comport_number)
{
EscapeCommFunction(Cport[comport_number], SETRTS);
}
void RS232_disableRTS(int comport_number)
{
EscapeCommFunction(Cport[comport_number], CLRRTS);
}
/*
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363428%28v=vs.85%29.aspx
*/
void RS232_flushRX(int comport_number)
{
PurgeComm(Cport[comport_number], PURGE_RXCLEAR | PURGE_RXABORT);
}
void RS232_flushTX(int comport_number)
{
PurgeComm(Cport[comport_number], PURGE_TXCLEAR | PURGE_TXABORT);
}
void RS232_flushRXTX(int comport_number)
{
PurgeComm(Cport[comport_number], PURGE_RXCLEAR | PURGE_RXABORT);
PurgeComm(Cport[comport_number], PURGE_TXCLEAR | PURGE_TXABORT);
}
#endif
void RS232_cputs(int comport_number, const char *text) /* sends a string to serial port */
{
while(*text != 0) RS232_SendByte(comport_number, *(text++));
}
/* return index in comports matching to device name or -1 if not found */
int RS232_GetPortnr(const char *devname)
{
int i;
char str[32];
#if defined(__linux__) || defined(__FreeBSD__) /* Linux & FreeBSD */
strcpy(str, "/dev/");
#else /* windows */
strcpy(str, "\\\\.\\");
#endif
strncat(str, devname, 16);
str[31] = 0;
for(i=0; i<RS232_PORTNR; i++)
{
if(!strcmp(comports[i], str))
{
return i;
}
}
return -1; /* device not found */
}

View File

@@ -1,85 +0,0 @@
/*
***************************************************************************
*
* Author: Teunis van Beelen
*
* Copyright (C) 2005 - 2021 Teunis van Beelen
*
* Email: teuniz@protonmail.com
*
***************************************************************************
*
* 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 3 of the License.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
***************************************************************************
*/
/* For more info and how to use this library, visit: http://www.teuniz.net/RS-232/ */
#ifndef rs232_INCLUDED
#define rs232_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <string.h>
#if defined(__linux__) || defined(__FreeBSD__)
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <sys/file.h>
#include <errno.h>
#else
#include <windows.h>
#endif
int RS232_OpenComport(int, int, const char *, int);
int RS232_PollComport(int, unsigned char *, int);
int RS232_SendByte(int, unsigned char);
int RS232_SendBuf(int, unsigned char *, int);
void RS232_CloseComport(int);
void RS232_cputs(int, const char *);
int RS232_IsDCDEnabled(int);
int RS232_IsRINGEnabled(int);
int RS232_IsCTSEnabled(int);
int RS232_IsDSREnabled(int);
void RS232_enableDTR(int);
void RS232_disableDTR(int);
void RS232_enableRTS(int);
void RS232_disableRTS(int);
void RS232_flushRX(int);
void RS232_flushTX(int);
void RS232_flushRXTX(int);
int RS232_GetPortnr(const char *);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View File

@@ -1,37 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=cc2652
PKG_VERSION:=1.0.0
PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/cc2652
SECTION:=utils
CATEGORY:=Utilities
TITLE:=cc2652 -- TI CC26x2 firmware upgrade tool
DEPENDS:=+libstdcpp +zlib
endef
define Package/cc2652/description
TI CC26x2 firmware upgrade tool
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Package/cc2652/install
$(INSTALL_DIR) $(1)/lib/firmware/cc2562
$(INSTALL_BIN) ./files/firmware/* $(1)/lib/firmware/cc2562
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/tisbl $(1)/usr/bin/
$(INSTALL_BIN) ./files/*.sh $(1)/usr/bin/
endef
$(eval $(call BuildPackage,cc2652))

View File

@@ -1,13 +0,0 @@
#!/bin/sh
if [ -f /sys/class/gpio/ble_enable/value ]; then
echo 1 > /sys/class/gpio/ble_enable/value
fi
echo 0 > /sys/class/gpio/ble_backdoor/value
echo 1 > /sys/class/gpio/ble_reset/value
echo 0 > /sys/class/gpio/ble_reset/value
sleep 1
echo 1 > /sys/class/gpio/ble_reset/value
sleep 1
echo 1 > /sys/class/gpio/ble_backdoor/value
tisbl /dev/ttyMSM1 115200 2652 /lib/firmware/cc2562/simple_broadcaster_bd9.bin

View File

@@ -1,13 +0,0 @@
#!/bin/sh
if [ -f /sys/class/gpio/ble_enable/value ]; then
echo 1 > /sys/class/gpio/ble_enable/value
fi
echo 0 > /sys/class/gpio/ble_backdoor/value
echo 1 > /sys/class/gpio/ble_reset/value
echo 0 > /sys/class/gpio/ble_reset/value
sleep 1
echo 1 > /sys/class/gpio/ble_reset/value
sleep 1
echo 1 > /sys/class/gpio/ble_backdoor/value
tisbl /dev/ttyMSM1 115200 2652 /lib/firmware/cc2562/ble5_host_test_bd9.bin

View File

@@ -1,10 +0,0 @@
#!/bin/sh
if [ -f /sys/class/gpio/ble_enable/value ]; then
echo 1 > /sys/class/gpio/ble_enable/value
fi
echo 1 > /sys/class/gpio/ble_backdoor/value
echo 1 > /sys/class/gpio/ble_reset/value
sleep 1
echo 1 > /sys/class/gpio/ble_reset/value
sleep 1

View File

@@ -1,13 +0,0 @@
#!/bin/sh
# com-wr.sh tty time command parser
# example com-wr.sh /dev/ttyMSM1 1 "\x01\x1D\xFC\x01\x00" | hexdump.sh --> send "\x01\x1D\xFC\x01\x00" to /dev/ttyMSM1 and then hexdump receive data until 100ms timeout
#command example "\x7E\x03\xD0\xAF und normaler Text"
tty=$1
time=$2
command=$3
parser=$4
stty -F $tty time $time
exec 99< $tty
echo -en $command > $tty
cat $tty
exec 99<&-

View File

@@ -1,28 +0,0 @@
#!/bin/sh
function iBeconScan() {
if [ "$#" -eq 4 ]; then
UUID=$1
MAJOR=$2
MINOR=$3
POWER=$4
else
UUID="\xE2\x0A\x39\xF4\x73\xF5\x4B\xC4\xA1\x2F\x17\xD1\xAD\x07\xA9\x61"
MAJOR="\x01\x23"
MINOR="\x45\x67"
POWER="\xC8"
fi
cc2562-wr.sh /dev/ttyMSM1 3 "\x01\x1D\xFC\x01\x00" > /dev/null # this command dealy time must >= 3, if small then 3, the following commands will be something wrong
cc2562-wr.sh /dev/ttyMSM1 1 "\x01\x00\xFE\x08\x01\x00\x00\x00\x00\x00\x00\x00" > /dev/null
cc2562-wr.sh /dev/ttyMSM1 1 "\x01\x3E\xFE\x15\x12\x00\xA0\x00\x00\xA0\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x7F\x01\x01\x00" > /dev/null
cc2562-wr.sh /dev/ttyMSM1 1 "\x09\x44\xFE\x23\x00\x00\x00\x1E\x00\x02\x01\x1A\x1A\xFF\x4C\x00\x02\x15${UUID}${MAJOR}${MINOR}${POWER}\x00" > /dev/null
cc2562-wr.sh /dev/ttyMSM1 1 "\x01\x3F\xFE\x04\x00\x00\x00\x00"
}
cc2562-reset.sh
while true
do
iBeconScan
sleep 1
done

View File

@@ -1,27 +0,0 @@
# Executable
EXE = tisbl
# Compiler, Linker Defines
#CC = g++
#CFLAGS = -w -O -Wno-deprecated -I. -fpermissive -std=gnu++0x
#CFLAGS = -I. -fpermissive -Wwrite-strings -lstdc++
CFLAGS = -I. -Wwrite-strings -std=gnu++0x -lstdc++ -fPIC
#CFLAGS = -I. -lstdc++ -Wwrite-strings -std=gnu++0x
#LIBS =
#LDFLAGS = $(LIBS)
# Compile and Assemble C++ Source Files into Object Files
%.o: %.cpp
$(CXX) $(CFLAGS) $(LDFLAGS) -c $< -o $@
# Source and Object files
SRC = $(wildcard *.cpp)
OBJ = $(patsubst %.cpp, %.o, $(SRC))
# Link all Object Files with external Libraries into Binaries
$(EXE): $(OBJ)
$(CC) $(CFLAGS) $(OBJ) $(LDFLAGS) -o $(EXE)
# $(CC) $(CFLAGS) $(OBJ) $(LDFLAGS) -o $(EXE) -lz
.PHONY: clean
clean:
-rm -f $(EXE) *.o

View File

@@ -1,13 +0,0 @@
#ifndef __DEBUG_H__
#define __DEBUG_H__
#include <stdio.h>
#define DEBUG 0
#if defined(DEBUG) && DEBUG > 0
#define DEBUG_PRINT(fmt, args...) fprintf(stderr, "$$%d:%s:%d:%s():" fmt, \
(int)time(NULL), __FILE__, __LINE__, __func__, ##args)
#else
#define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */
#endif
#endif // __DEBUG_H__

View File

@@ -1,257 +0,0 @@
/******************************************************************************
* Filename: sblAppEx.cpp
* Revised: $Date$
* Revision: $Revision$
*
* Description: Serial Bootloader Library application example.
* This example enumerates all COM devices and lets you
* select which port to connect to. The example assumes the
* connected device is a CC2538, CC2650 or CC2652 and programs
* a blinky onto the device. After programming the blinky,
* bootloader mode may be forced by
* - holding SELECT button on 06EB (for CC2538 and CC26x0 EMKs), or
* - holding BTN-1 on the device LaunchPad (for CC26x2 LPs)
* when resetting the chip.
*
* Copyright (C) 2013 - 2019 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include "serialib.h"
#include "sbllib.h"
#include <vector>
#include <iostream>
#include <fstream>
//#include <time.h>
using namespace std;
// Calculate crc32 checksum the way CC2538 and CC2650 does it.
int calcCrcLikeChip(const unsigned char *pData, unsigned long ulByteCount)
{
unsigned long d, ind;
unsigned long acc = 0xFFFFFFFF;
const unsigned long ulCrcRand32Lut[] =
{
0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC,
0x76DC4190, 0x6B6B51F4, 0x4DB26158, 0x5005713C,
0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C,
0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C
};
while ( ulByteCount-- )
{
d = *pData++;
ind = (acc & 0x0F) ^ (d & 0x0F);
acc = (acc >> 4) ^ ulCrcRand32Lut[ind];
ind = (acc & 0x0F) ^ (d >> 4);
acc = (acc >> 4) ^ ulCrcRand32Lut[ind];
}
return (acc ^ 0xFFFFFFFF);
}
/// Application status function (used as SBL status callback)
void appStatus(char *pcText, bool bError)
{
if(bError)
{
cerr << pcText;
}
else
{
cout << pcText;
}
}
/// Application progress function (used as SBL progress callback)
static void appProgress(uint32_t progress)
{
fprintf(stdout, "\r%d%% ", progress);
fflush(stdout);
}
// Defines
// Name Hex Dec
// ------------------------------- --------------- ---------------------------------
#define DEVICE_CC2538 0x2538 // 9528
#define DEVICE_CC26X0 0x2650 // 9808
#define DEVICE_CC2640R2 0x2640 // 9792
#define DEVICE_CC26X2 0x2652 // 9810
#define CC2538_FLASH_BASE 0x00200000
#define CC26XX_FLASH_BASE 0x00000000
// Application main function
// tisbl SerialDevNode baudRate deviceType firmware
int main(int argc, char *argv[])
{
// START: Program Configuration
/* UART baud rate. Default: 230400 */
uint32_t baudRate = 115200;
uint32_t deviceType = DEVICE_CC26X2;
SblDevice *pDevice = NULL; // Pointer to SblDevice object
char *SerialDevNode;
int32_t devStatus = -1; // Hold SBL status codes
std::string fileName; // File name to program
uint32_t byteCount = 0; // File size in bytes
uint32_t fileCrc, devCrc; // Variables to save CRC checksum
uint32_t devFlashBase; // Flash start address
static std::vector<char> pvWrite(1);// Vector to application firmware in.
static std::ifstream file; // File stream
// Set callback functions
SblDevice::setCallBackStatusFunction(&appStatus);
SblDevice::setCallBackProgressFunction(&appProgress);
// Select device
// deviceType FlashBase File
// DEVICE_CC2538 CC2538_FLASH_BASE blinky_backdoor_select_btn2538.bin
// DEVICE_CC26X0 CC26XX_FLASH_BASE blinky_backdoor_select_btn2650.bin
// DEVICE_CC2640R2 CC26XX_FLASH_BASE blinky_backdoor_select_btn2640r2.bin
// DEVICE_CC26X2 CC26XX_FLASH_BASE blinky_backdoor_select_btn26x2.bin
if(argc < 5) {
return -1;
}
SerialDevNode = argv[1];
baudRate = atoi(argv[2]);
deviceType = strtol(argv[3], NULL, 16);
fileName = argv[4];
switch(deviceType)
{
case DEVICE_CC2538:
devFlashBase = CC2538_FLASH_BASE;
break;
case DEVICE_CC26X0:
case DEVICE_CC2640R2:
case DEVICE_CC26X2:
devFlashBase = CC26XX_FLASH_BASE;
break;
}
printf("SerialDevNode=%s, baudRate=%d, deviceType=%04x, fileName=%s\n",SerialDevNode,baudRate,deviceType,fileName.c_str());
// Should SBL try to enable XOSC? (Not possible for CC26xx)
bool bEnableXosc = false;
if(deviceType == DEVICE_CC2538)
{
char answer[64];
cout << "Enable device CC2538 XOSC? (Y/N): ";
cin >> answer;
bEnableXosc = (answer[0] == 'Y' || answer[0] == 'y') ? true : false;
}
// Create SBL object
pDevice = SblDevice::Create(deviceType);
if(pDevice == NULL)
{
printf("No SBL device object.\n");
cout << "\n\nAn error occurred: " << pDevice->getLastStatus();
return -1;
}
// Connect to device
printf("Connecting (%s @ %d baud) ...\n", SerialDevNode, baudRate);
if(pDevice->connect(SerialDevNode, baudRate, bEnableXosc) != SBL_SUCCESS)
{
cout << "\n\nAn error occurred: " << pDevice->getLastStatus();
return -1;
}
// Read file
file.open(fileName.c_str(), std::ios::binary);
if(file.is_open())
{
// Get file size:
file.seekg(0, std::ios::end);
byteCount = (uint32_t)file.tellg();
file.seekg(0, std::ios::beg);
// Read data
pvWrite.resize(byteCount);
file.read((char*) &pvWrite[0], byteCount);
}
else
{
cout << "Unable to open file " << fileName.c_str();
cout << "\n\nAn error occurred: " << pDevice->getLastStatus();
return -1;
}
// Calculate file CRC checksum
fileCrc = calcCrcLikeChip((unsigned char *)&pvWrite[0], byteCount);
if(pDevice->calculateCrc32(devFlashBase, byteCount, &devCrc) != SBL_SUCCESS)
{
cout << "\n\nAn error occurred: " << pDevice->getLastStatus();
return -1;
}
printf ("pre-Comparing CRC: fileCrc=%x,devCrc=%x\n",fileCrc,devCrc);
if(fileCrc == devCrc) {
cout << "CRC is same, no need to upgrade\n";
pDevice->reset();
return 0;
}
// Erasing as much flash needed to program firmware.
cout << "Erasing flash ...\n";
if(pDevice->eraseFlashRange(devFlashBase, byteCount) != SBL_SUCCESS)
{
cout << "\n\nAn error occurred: " << pDevice->getLastStatus();
return -1;
}
// Writing file to device flash memory.
cout << "Writing flash ...\n";
if(pDevice->writeFlashRange(devFlashBase, byteCount, &pvWrite[0]) != SBL_SUCCESS)
{
cout << "\n\nAn error occurred: " << pDevice->getLastStatus();
return -1;
}
// Calculate CRC checksum of flashed content.
cout << "Calculating CRC on device ...\n";
if(pDevice->calculateCrc32(devFlashBase, byteCount, &devCrc) != SBL_SUCCESS)
{
cout << "\n\nAn error occurred: " << pDevice->getLastStatus();
return -1;
}
// Compare CRC checksums
printf ("Comparing CRC: fileCrc=%x,devCrc=%x\n",fileCrc,devCrc);
if(fileCrc == devCrc) printf("OK\n");
else printf("Mismatch!\n");
cout << "Resetting device ...\n";
pDevice->reset();
cout << "OK\n";
}

View File

@@ -1,673 +0,0 @@
/******************************************************************************
* Filename: sbl_device.cpp
* Revised: $Date$
* Revision: $Revision$
*
* Description: Serial Bootloader device file.
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <sbllib.h>
#include "sbl_device.h"
#include "sbl_device_cc2538.h"
#include "sbl_device_cc2650.h"
#include "sbl_device_cc2652.h"
#if 0
#include <ComPort.h>
#include <ComPortElement.h>
#else
#include "serialib.h"
#endif
#include <stdarg.h>
// Static variables
//
std::string SblDevice::sm_csLastError;
uint32_t SblDevice::sm_progress = 0;
tProgressFPTR SblDevice::sm_pProgressFunction = NULL;
tStatusFPTR SblDevice::sm_pStatusFunction = NULL;
uint32_t SblDevice::sm_chipType = 0;
//-----------------------------------------------------------------------------
/** \brief Constructor
*/
//-----------------------------------------------------------------------------
SblDevice::SblDevice()
{
m_pCom = NULL;
m_lastDeviceStatus = -1;
m_lastSblStatus = SBL_SUCCESS;
m_bCommInitialized = false;
m_deviceId = 0;
m_ramSize = 0;
m_flashSize = 0;
m_pageEraseSize = 0;
}
//-----------------------------------------------------------------------------
/** \brief Destructor
*/
//-----------------------------------------------------------------------------
SblDevice::~SblDevice()
{
if (m_pCom != nullptr)
{
delete m_pCom;
m_pCom = nullptr;
}
m_lastDeviceStatus = -1;
m_bCommInitialized = false;
m_ramSize = -1;
m_flashSize = -1;
}
//-----------------------------------------------------------------------------
/** \brief Create Serial Bootloader Device
*
* \param[in] ui32ChipType
* Chip type the object should be created for, e.g. 0x2650 for CC2650.
*/
//-----------------------------------------------------------------------------
/*static*/SblDevice *
SblDevice::Create(uint32_t ui32ChipType)
{
if (ui32ChipType == 0)
{
return NULL;
}
sm_chipType = ui32ChipType;
switch (ui32ChipType)
{
case 0x2538:
return (SblDevice *)new SblDeviceCC2538();
case 0x1350:
case 0x1310:
case 0x2670:
case 0x2650:
case 0x2640:
case 0x2630:
case 0x2620:
return (SblDevice *)new SblDeviceCC2650();
case 0x1312:
case 0x1352:
case 0x2642:
case 0x2652:
return (SblDevice *)new SblDeviceCC2652();
default:
return NULL;
}
}
#if 0
//-----------------------------------------------------------------------------
/** \brief Enumerate COM port devices
*
* \param[in/out] pComPortElements
* Pointer to array where enumerated COM devices are stored
* \param[in/out] numElements
* Maximum number of elements to enumerate. Is populated with number
* of devices enumerated.
*
* \return
*
*/
//-----------------------------------------------------------------------------
/*static*/uint32_t
SblDevice::enumerate(ComPortElement *pComPortElements, int &numElements)
{
ComPort com;
if (com.enumerate(pComPortElements, numElements) != ComPort::COMPORT_SUCCESS)
{
printf("Failed to enumerate COM devices.\n");
return SBL_ENUM_ERROR;
}
return SBL_SUCCESS;
}
#endif
//-----------------------------------------------------------------------------
/** \brief Connect to given port number at specified baud rate.
*
* \param[in] csPortNum
* String containing the COM port to use
* \param[in] ui32BaudRate
* Baud rate to use for talking to the device.
* \param[in] bEnableXosc (optional)
* If true, try to enable device XOSC. Defaults to false. This option is
* not available for all device types.
*
* \return
* Returns SBL_SUCCESS, ...
*/
//-----------------------------------------------------------------------------
uint32_t
SblDevice::connect(std::string csPortNum, uint32_t ui32BaudRate,
bool bEnableXosc/* = false*/)
{
DEBUG_PRINT("\n");
int retCode = SBL_SUCCESS;
//
// Check input arguments
//
if (csPortNum.empty() || ui32BaudRate == 0)
{
setState(SBL_ARGUMENT_ERROR, "Cannot connect. Port number '%s' or baud rate '%d' is invalid.\n",
csPortNum.c_str(), ui32BaudRate);
return SBL_ARGUMENT_ERROR;
}
// Try to connect to the specified port at the specified baud rate
if (m_pCom != NULL)
{
// Try to open port
#if 1
char result = m_pCom->openDevice(csPortNum.c_str(),ui32BaudRate);
if(result < 0)
{
setState(SBL_PORT_ERROR, "SBL: Unable to open %s. Error: %d.\n", csPortNum.c_str(), result);
return SBL_PORT_ERROR;
}
#else
if (int result = m_pCom->open(csPortNum,
ui32BaudRate,
SBL_DEFAULT_READ_TIMEOUT,
SBL_DEFAULT_WRITE_TIMEOUT) != ComPort::COMPORT_SUCCESS)
{
setState(SBL_PORT_ERROR, "SBL: Unable to open %s. Error: %d.\n", csPortNum.c_str(), result);
return SBL_PORT_ERROR;
}
#endif
m_csComPort = csPortNum;
m_baudRate = ui32BaudRate;
}
// Check if device is responding at the given baud rate
if ((retCode = initCommunication(bEnableXosc)) != SBL_SUCCESS)
{
return retCode;
}
//
// Read device ID
//
uint32_t tmp;
if ((retCode = readDeviceId(&tmp)) != SBL_SUCCESS)
{
setState(retCode, "Failed to read device ID during initial connect.\n");
return retCode;
}
//
// Read device flash size
//
if ((retCode = readFlashSize(&tmp)) != SBL_SUCCESS)
{
setState(retCode, "Failed to read flash size during initial connect.\n");
return retCode;
}
//
// Read device ram size
//
if ((retCode = readRamSize(&tmp)) != SBL_SUCCESS)
{
setState(retCode, "Failed to read RAM size during initial connect.\n");
return retCode;
}
return SBL_SUCCESS;
}
//-----------------------------------------------------------------------------
/** \brief Send auto baud.
*
* \param[out] bBaudSetOk
* True if response is ACK, false otherwise
*
* \return
* Returns SBL_SUCCESS, ...
*/
//-----------------------------------------------------------------------------
uint32_t
SblDevice::sendAutoBaud(bool &bBaudSetOk)
{
DEBUG_PRINT("\n");
bBaudSetOk = false;
//
// Send 0x55 0x55 and expect ACK
//
char pData[2];
memset(pData, 0x55, 2);
if (m_pCom->writeBytes(pData, 2) != 2)
{
setState(SBL_PORT_ERROR, "Communication initialization failed. Failed to send data.\n");
return SBL_PORT_ERROR;
}
if (getCmdResponse(bBaudSetOk, 2, true) != SBL_SUCCESS)
{
// No response received. Invalid baud rate?
setState(SBL_PORT_ERROR, "No response from device. Device may not be in bootloader mode. Reset device and try again.\nIf problem persists, check connection and baud rate.\n");
return SBL_PORT_ERROR;
}
return SBL_SUCCESS;
}
//-----------------------------------------------------------------------------
/** \brief Get ACK/NAK from the boot loader.
*
* \param[out] bAck
* True if response is ACK, false if response is NAK.
* \param[in] ui32MaxRetries (optional)
* How many times ComPort::readBytes() can time out before fail is issued.
* \param[in] bQuietTimeout (optional)
* Do not set error if no command response is received.
*
* \return
* Returns SBL_SUCCESS, ...
*/
//-----------------------------------------------------------------------------
uint32_t
SblDevice::getCmdResponse(bool &bAck,
uint32_t ui32MaxRetries/* = SBL_DEFAULT_RETRY_COUNT*/,
bool bQuietTimeout/* = false*/)
{
DEBUG_PRINT("\n");
unsigned char pIn[2];
memset(pIn, 0, 2);
uint32_t numBytes = 0;
uint32_t retry = 0;
bAck = false;
uint32_t bytesRecv = 0;
//
// Expect 2 bytes (ACK or NAK)
//
do
{
numBytes = m_pCom->readBytes(pIn, 2);
bytesRecv += numBytes;
retry++;
} while ((bytesRecv < 2) && (retry < ui32MaxRetries));
if (bytesRecv < 2)
{
if (!bQuietTimeout) setState(SBL_TIMEOUT_ERROR, "Timed out waiting for ACK/NAK. No response from device.\n");
return SBL_TIMEOUT_ERROR;
}
else
{
if (pIn[0] == 0x00 && pIn[1] == 0xCC)
{
bAck = true;
return setState(SBL_SUCCESS);
}
else if (pIn[0] == 0x00 && pIn[1] == 0x33)
{
return setState(SBL_SUCCESS);
}
else
{
setState(SBL_ERROR, "ACK/NAK not received. Expected 0x00 0xCC or 0x00 0x33, received 0x%02X 0x%02X. bytesRecv=%d\n", pIn[0], pIn[1], bytesRecv);
return SBL_ERROR;
}
}
return SBL_ERROR;
}
//-----------------------------------------------------------------------------
/** \brief Send command response (ACK/NAK).
*
* \param[in] bAck
* True if response is ACK, false if response is NAK.
* \return
* Returns SBL_SUCCESS, ...
*/
//-----------------------------------------------------------------------------
uint32_t
SblDevice::sendCmdResponse(bool bAck)
{
DEBUG_PRINT("\n");
//
// Send response
//
char pData[2];
pData[0] = 0x00;
pData[1] = (bAck) ? 0xCC : 0x33;
if (m_pCom->writeBytes(pData, 2) != 2)
{
setState(SBL_PORT_ERROR, "Failed to send ACK/NAK response over %s\n",
m_csComPort.c_str());
return SBL_PORT_ERROR;
}
return SBL_SUCCESS;
}
//-----------------------------------------------------------------------------
/** \brief Get response data from device.
*
* \param[out] pcData
* Pointer to where received data will be stored.
* \param[in|out] ui32MaxLen
* Max number of bytes that can be received. Is populated with the actual
* number of bytes received.
* \param[in] ui32MaxRetries (optional)
* How many times ComPort::readBytes() can time out before fail is issued.
* \return
* Returns SBL_SUCCESS, ...
*/
//-----------------------------------------------------------------------------
uint32_t
SblDevice::getResponseData(char *pcData, uint32_t &ui32MaxLen,
uint32_t ui32MaxRetries/* = SBL_DEFAULT_RETRY_COUNT*/)
{
DEBUG_PRINT("\n");
uint32_t numBytes = 0;
uint32_t retry = 0;
unsigned char pcHdr[2];
uint32_t numPayloadBytes;
uint8_t hdrChecksum, dataChecksum;
uint32_t bytesRecv = 0;
setState(SBL_SUCCESS);
//
// Read length and checksum
//
memset(pcHdr, 0, 2);
do
{
bytesRecv += m_pCom->readBytes(&pcHdr[bytesRecv], (2 - bytesRecv));
retry++;
} while ((bytesRecv < 2) && retry < ui32MaxRetries);
//
// Check that we've received 2 bytes
//
if (bytesRecv < 2)
{
setState(SBL_TIMEOUT_ERROR, "Timed out waiting for data header from device.\n");
return SBL_TIMEOUT_ERROR;
}
numPayloadBytes = pcHdr[0] - 2;
hdrChecksum = pcHdr[1];
//
// Check if length byte is too long.
//
if (numPayloadBytes > ui32MaxLen)
{
setState(SBL_ERROR, "Error: Device sending more data than expected. \nMax expected was %d, sent was %d.\n", (uint32_t)ui32MaxLen, (numPayloadBytes + 2));
#if 1
m_pCom->flushReceiver();
#endif
return SBL_ERROR;
}
//
// Read the payload data
//
bytesRecv = 0;
do
{
bytesRecv += m_pCom->readBytes(&pcData[bytesRecv], (numPayloadBytes - bytesRecv));
retry++;
} while (bytesRecv < numPayloadBytes && retry < ui32MaxRetries);
//
// Have we received what we expected?
//
if (bytesRecv < numPayloadBytes)
{
ui32MaxLen = bytesRecv;
setState(SBL_TIMEOUT_ERROR, "Timed out waiting for data from device.\n");
return SBL_TIMEOUT_ERROR;
}
//
// Verify data checksum
//
dataChecksum = generateCheckSum(0, pcData, numPayloadBytes);
if (dataChecksum != hdrChecksum)
{
setState(SBL_ERROR, "Checksum verification error. Expected 0x%02X, got 0x%02X.\n", hdrChecksum, dataChecksum);
return SBL_ERROR;
}
ui32MaxLen = bytesRecv;
return SBL_SUCCESS;
}
//-----------------------------------------------------------------------------
/** \brief Are we connected to the device?
*
* \return
* Returns true if connected to device.
* Returns false if not connected to device.
*/
//-----------------------------------------------------------------------------
bool
SblDevice::isConnected()
{
DEBUG_PRINT("\n");
if (!m_pCom)
{
return false;
}
return true;
}
//-----------------------------------------------------------------------------
/** \brief This function generates the bootloader protocol checksum.
*
* \param[in] ui32Cmd
* The bootloader command
* \param[in] pcData
* Pointer to the command data.
* \param[in] ui32DataLen
* Data length in bytes.
*
* \return
* Returns the generated checksum.
*/
//-----------------------------------------------------------------------------
uint8_t
SblDevice::generateCheckSum(uint32_t ui32Cmd, const char *pcData,
uint32_t ui32DataLen)
{
DEBUG_PRINT("\n");
uint8_t ui8CheckSum = (uint8_t)ui32Cmd;
for (uint32_t i = 0; i < ui32DataLen; i++)
{
ui8CheckSum += pcData[i];
}
return ui8CheckSum;
}
//-----------------------------------------------------------------------------
/** \brief This function sets the SBL status and the SBL error string.
*
* \param[in] ui32Status
* The new SBL status. SBL_SUCCESS, SBL_ERROR, ...
* \param[in] pcFormat
* 'printf' like format string.
* \param[in] ...
* Input variables to the \e pcFormat string.
*
* \return
* Returns SBL_SUCCESS, ...
*/
//-----------------------------------------------------------------------------
uint32_t
SblDevice::setState(const uint32_t &ui32Status, char *pcFormat, ...)
{
DEBUG_PRINT("\n");
va_list args;
char text[2048];
m_lastSblStatus = ui32Status;
// Attempt to do a sanity check. Not possible to say how long
// the formatted text will be, but if we reserve half the space for
// formatted arguments it should be sufficient.
if (strlen(pcFormat) > 2048 / 2) {
return SBL_ERROR;
}
va_start(args, pcFormat);
#if 0
vsprintf_s(text, pcFormat, args);
#else
vsprintf(text, pcFormat, args);
#endif
sm_csLastError = text;
va_end(args);
if (SblDevice::sm_pStatusFunction != NULL)
{
bool error = (m_lastSblStatus == SBL_SUCCESS) ? false : true;
sm_pStatusFunction((char *)sm_csLastError.c_str(), error);
}
return SBL_SUCCESS;
}
//-----------------------------------------------------------------------------
/** \brief Utility function for converting 4 elements in char array into
* 32 bit variable. Data are converted MSB, that is. \e pcSrc[0] is the
* most significant byte.
*
* \param pcSrc[in]
* A pointer to the source array.
*
* \return
* Returns the 32 bit variable.
*/
//-----------------------------------------------------------------------------
/*static */uint32_t
SblDevice::charArrayToUL(const char *pcSrc)
{
DEBUG_PRINT("\n");
uint32_t ui32Val = (unsigned char)pcSrc[3];
ui32Val += (((unsigned long)pcSrc[2]) & 0xFF) << 8;
ui32Val += (((unsigned long)pcSrc[1]) & 0xFF) << 16;
ui32Val += (((unsigned long)pcSrc[0]) & 0xFF) << 24;
return (ui32Val);
}
//-----------------------------------------------------------------------------
/** \brief Utility function for splitting 32 bit variable into char array
* (4 elements). Data are converted MSB, that is, \e pcDst[0] is the
* most significant byte.
*
* \param[in] ui32Src
* The 32 bit variable to convert.
*
* \param[out] pcDst
* Pointer to the char array where the data will be stored.
*
* \return
* void
*/
//-----------------------------------------------------------------------------
/*static */void
SblDevice::ulToCharArray(const uint32_t ui32Src, char *pcDst)
{
DEBUG_PRINT("\n");
// MSB first
pcDst[0] = (uint8_t)(ui32Src >> 24);
pcDst[1] = (uint8_t)(ui32Src >> 16);
pcDst[2] = (uint8_t)(ui32Src >> 8);
pcDst[3] = (uint8_t)(ui32Src >> 0);
}
//-----------------------------------------------------------------------------
/** \brief Utility function for swapping the byte order of a 4B char array.
*
* \param[in|out] pcArray
* The char array to byte swap.
*
* \return
* void
*/
//-----------------------------------------------------------------------------
/*static */void
SblDevice::byteSwap(char *pcArray)
{
DEBUG_PRINT("\n");
uint8_t tmp[2] = { (uint8_t)pcArray[0], (uint8_t)pcArray[1] };
pcArray[0] = pcArray[3];
pcArray[1] = pcArray[2];
pcArray[2] = tmp[1];
pcArray[3] = tmp[0];
}
//-----------------------------------------------------------------------------
/** \brief This functions sets the SBL progress.
*
* \param[in] ui32Progress
* The current progress, typically in percent [0-100].
*
* \return
* void
*/
//-----------------------------------------------------------------------------
/*static*/uint32_t
SblDevice::setProgress(uint32_t ui32Progress)
{
DEBUG_PRINT("\n");
if (sm_pProgressFunction)
{
sm_pProgressFunction(ui32Progress);
}
sm_progress = ui32Progress;
return SBL_SUCCESS;
}

View File

@@ -1,143 +0,0 @@
#ifndef __SBL_DEVICE_H__
#define __SBL_DEVICE_H__
/******************************************************************************
* Filename: sbl_device.h
* Revised: $Date$
* Revision: $Revision$
*
* Description: Serial Bootloader device header file.
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include "serialib.h"
//
// Typedefs for callback functions to report status and progress to application
//
typedef void (*tStatusFPTR)(char *pcText, bool bError);
typedef void (*tProgressFPTR)(uint32_t ui32Value);
class SblDevice
{
public:
// Constructor
~SblDevice();
// Static functions
static SblDevice *Create(uint32_t ui32ChipType);
virtual uint32_t connect(std::string csPortNum, uint32_t ui32BaudRate, bool bEnableXosc = false);
virtual uint32_t ping() = 0;
virtual uint32_t readStatus(uint32_t *pui32Status) = 0;
virtual uint32_t readDeviceId(uint32_t *pui32DeviceId) = 0;
virtual uint32_t readFlashSize(uint32_t *pui32FlashSize) = 0;
virtual uint32_t readRamSize(uint32_t *pui32RamSize) = 0;
virtual uint32_t run(uint32_t ui32Address) { (void)ui32Address; return SBL_UNSUPPORTED_FUNCTION; };
virtual uint32_t reset() = 0;
virtual uint32_t eraseFlashRange(uint32_t ui32StartAddress, uint32_t ui32ByteCount) { (void)ui32StartAddress; (void)ui32ByteCount; return 0; };
virtual uint32_t writeFlashRange(uint32_t ui32StartAddress, uint32_t ui32ByteCount, const char *pcData) { (void)ui32StartAddress; (void)ui32ByteCount; (void)pcData; return 0; };
virtual uint32_t readMemory32(uint32_t ui32StartAddress, uint32_t ui32UnitCount, uint32_t *pui32Data) = 0;
virtual uint32_t readMemory8(uint32_t ui32StartAddress, uint32_t ui32UnitCount, char *pcData) = 0;
virtual uint32_t writeMemory32(uint32_t ui32StartAddress, uint32_t ui32UnitCount, const uint32_t *pui32Data) = 0;
virtual uint32_t writeMemory8(uint32_t ui32StartAddress, uint32_t ui32UnitCount, const char *pcData) = 0;
virtual uint32_t calculateCrc32(uint32_t ui32StartAddress, uint32_t ui32ByteCount, uint32_t *pui32Crc) = 0;
// CC2650 specific
virtual uint32_t eraseFlashBank(){ return SBL_UNSUPPORTED_FUNCTION; };
virtual uint32_t setCCFG(uint32_t ui32Field, uint32_t ui32FieldValue) { (void)ui32Field; (void)ui32FieldValue; return SBL_UNSUPPORTED_FUNCTION; };
// CC2538 specific
virtual uint32_t setXosc() { return SBL_UNSUPPORTED_FUNCTION; };
// Utility functions
bool isConnected();
uint32_t getDeviceId() { return m_deviceId; }
uint32_t getFlashSize() { return m_flashSize; }
uint32_t getRamSize() { return m_ramSize; }
uint32_t getBaudRate() { return m_baudRate; }
uint32_t getLastStatus() {return m_lastSblStatus; }
uint32_t getLastDeviceStatus() { return m_lastDeviceStatus; }
uint32_t getPageEraseSize() { return m_pageEraseSize; }
static std::string &getLastError(void) { return sm_csLastError;}
static uint32_t getProgress() { return sm_progress; }
static uint32_t setProgress(uint32_t ui32Progress);
static void setCallBackStatusFunction(tStatusFPTR pSf) {sm_pStatusFunction = pSf; }
static void setCallBackProgressFunction(tProgressFPTR pPf) {sm_pProgressFunction = pPf; }
protected:
// Constructor
SblDevice();
virtual uint32_t initCommunication(bool bSetXosc) = 0;
virtual uint32_t sendCmd(uint32_t ui32Cmd, const char *pcSendData = NULL, uint32_t ui32SendLen = 0) = 0;
virtual uint32_t sendAutoBaud(bool &bBaudSetOk);
virtual uint32_t getCmdResponse(bool &bAck, uint32_t ui32MaxRetries = SBL_DEFAULT_RETRY_COUNT, bool bQuiet = false);
virtual uint32_t sendCmdResponse(bool bAck);
virtual uint32_t getResponseData(char *pcData, uint32_t &ui32MaxLen, uint32_t ui32MaxRetries = SBL_DEFAULT_RETRY_COUNT);
virtual uint8_t generateCheckSum(uint32_t ui32Cmd, const char *pcData, uint32_t ui32DataLen);
virtual uint32_t addressToPage(uint32_t ui32Address) = 0;
virtual bool addressInRam(uint32_t ui32StartAddress, uint32_t ui32ByteCount = 1) = 0;
virtual bool addressInFlash(uint32_t ui32StartAddress, uint32_t ui32ByteCount = 1) = 0;
virtual uint32_t getBootloaderEnableAddress() = 0;
uint32_t setState(const uint32_t &ui32Status) { m_lastSblStatus = ui32Status; return m_lastSblStatus;}
uint32_t setState(const uint32_t &ui32Status, char *pcFormat, ...);
// Utility
static uint32_t charArrayToUL(const char *pcSrc);
static void ulToCharArray(const uint32_t ui32Src, char *pcDst);
static void byteSwap(char *pcArray);
serialib *m_pCom;
std::string m_csComPort;
bool m_bCommInitialized;
uint32_t m_baudRate;
static uint32_t sm_chipType;
uint32_t m_deviceId;
uint32_t m_flashSize;
uint32_t m_ramSize;
uint32_t m_pageEraseSize;
// Status and progress variables
int32_t m_lastDeviceStatus;
int32_t m_lastSblStatus;
static uint32_t sm_progress;
static std::string sm_csLastError;
static tProgressFPTR sm_pProgressFunction;
static tStatusFPTR sm_pStatusFunction;
private:
};
#endif // __SBL_DEVICE_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,126 +0,0 @@
#ifndef __SBL_DEVICE_CC2538_H__
#define __SBL_DEVICE_CC2538_H__
/******************************************************************************
* Filename: sbl_device_cc2538.h
* Revised: $Date$
* Revision: $Revision$
*
* Description: Serial Bootloader for CC2538 header file.
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <sbl_device.h>
//
// For more information about the CC2538 serial bootloader interface,
// please refer to the CC2538 ROM User's guide (http://www.ti.com/lit/swru333)
//
#define SBL_CC2538_PAGE_ERASE_SIZE 2048
#define SBL_CC2538_FLASH_START_ADDRESS 0x00200000
#define SBL_CC2538_RAM_START_ADDRESS 0x20000000
#define SBL_CC2538_ACCESS_WIDTH_4B 4
#define SBL_CC2538_ACCESS_WIDTH_1B 1
#define SBL_CC2538_PAGE_ERASE_TIME_MS 20
#define SBL_CC2538_MAX_BYTES_PER_TRANSFER 252
#define SBL_CC2538_DIECFG0 0x400D3014
#define SBL_CC2538_BL_CONFIG_PAGE_OFFSET 2007
#define SBL_CC2538_BL_CONFIG_ENABLED_BM 0x10
class SblDeviceCC2538 : public SblDevice
{
public:
SblDeviceCC2538(); // Constructor
~SblDeviceCC2538(); // Destructor
enum {
CMD_PING = 0x20,
CMD_DOWNLOAD = 0x21,
CMD_RUN = 0x22,
CMD_GET_STATUS = 0x23,
CMD_SEND_DATA = 0x24,
CMD_RESET = 0x25,
CMD_ERASE = 0x26,
CMD_CRC32 = 0x27,
CMD_GET_CHIP_ID = 0x28,
CMD_SET_XOSC = 0x29,
CMD_MEMORY_READ = 0x2A,
CMD_MEMORY_WRITE = 0x2B,
};
enum {
CMD_RET_SUCCESS = 0x40,
CMD_RET_UNKNOWN_CMD = 0x41,
CMD_RET_INVALID_CMD = 0x42,
CMD_RET_INVALID_ADR = 0x43,
CMD_RET_FLASH_FAIL = 0x44,
};
protected:
// Virtual functions from SblDevice
uint32_t ping();
uint32_t readStatus(uint32_t *pui32Status);
uint32_t readDeviceId(uint32_t *pui32DeviceId);
uint32_t readFlashSize(uint32_t *pui32FlashSize);
uint32_t readRamSize(uint32_t *pui32RamSize);
uint32_t run(uint32_t ui32Address);
uint32_t reset();
uint32_t eraseFlashRange(uint32_t ui32StartAddress, uint32_t ui32ByteCount);
uint32_t writeFlashRange(uint32_t ui32StartAddress, uint32_t ui32ByteCount, const char *pcData);
uint32_t readMemory32(uint32_t ui32StartAddress, uint32_t ui32UnitCount, uint32_t *pui32Data);
uint32_t readMemory8(uint32_t ui32StartAddress, uint32_t ui32UnitCount, char *pcData);
uint32_t writeMemory32(uint32_t ui32StartAddress, uint32_t ui32UnitCount, const uint32_t *pui32Data);
uint32_t writeMemory8(uint32_t ui32StartAddress, uint32_t ui32UnitCount, const char *pcData);
uint32_t calculateCrc32(uint32_t ui32StartAddress, uint32_t ui32ByteCount, uint32_t *pui32Crc);
uint32_t sendCmd(uint32_t ui32Cmd, const char *pcSendData = NULL, uint32_t ui32SendLen = 0);
uint32_t addressToPage(uint32_t ui32Address);
bool addressInRam(uint32_t ui32StartAddress, uint32_t ui32ByteCount = 1);
bool addressInFlash(uint32_t ui32StartAddress, uint32_t ui32ByteCount = 1);
uint32_t setXosc();
private:
uint32_t initCommunication(bool bSetXosc);
uint32_t cmdDownload(uint32_t ui32Address, uint32_t ui32Size);
uint32_t cmdSendData(const char *pcData, uint32_t ui32ByteCount);
uint32_t getBootloaderEnableAddress();
std::string getCmdString(uint32_t ui32Cmd);
std::string getCmdStatusString(uint32_t ui32Status);
};
#endif // __SBL_DEVICE_CC2538_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,153 +0,0 @@
#ifndef __SBL_DEVICE_CC2650_H__
#define __SBL_DEVICE_CC2650_H__
/******************************************************************************
* Filename: sbl_device_cc2650.h
* Revised: $Date: 2013-07-26 09:53:42 +0200 (fr, 26 jul 2013) $
* Revision: $Revision: 26971 $
*
* Description: Serial Bootloader for CC2650 header file.
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <sbl_device.h>
#define SBL_CC2650_PAGE_ERASE_SIZE 4096
#define SBL_CC2650_FLASH_START_ADDRESS 0x00000000
#define SBL_CC2650_RAM_START_ADDRESS 0x20000000
#define SBL_CC2650_ACCESS_WIDTH_32B 1
#define SBL_CC2650_ACCESS_WIDTH_8B 0
#define SBL_CC2650_PAGE_ERASE_TIME_MS 20
#define SBL_CC2650_MAX_BYTES_PER_TRANSFER 252
#define SBL_CC2650_MAX_MEMWRITE_BYTES 247
#define SBL_CC2650_MAX_MEMWRITE_WORDS 61
#define SBL_CC2650_MAX_MEMREAD_BYTES 253
#define SBL_CC2650_MAX_MEMREAD_WORDS 63
#define SBL_CC2650_FLASH_SIZE_CFG 0x4003002C
#define SBL_CC2650_RAM_SIZE_CFG 0x40082250
#define SBL_CC2650_BL_CONFIG_PAGE_OFFSET 0xFDB
#define SBL_CC2650_BL_CONFIG_ENABLED_BM 0xC5
#define SBL_CC2650_BL_WORK_MEMORY_START 0x20000000
#define SBL_CC2650_BL_WORK_MEMORY_END 0x2000016F
#define SBL_CC2650_BL_STACK_MEMORY_START 0x20000FC0
#define SBL_CC2650_BL_STACK_MEMORY_END 0x20000FFF
class SblDeviceCC2650 : public SblDevice
{
public:
SblDeviceCC2650(); // Constructor
~SblDeviceCC2650(); // Destructor
enum {
CMD_PING = 0x20,
CMD_DOWNLOAD = 0x21,
CMD_GET_STATUS = 0x23,
CMD_SEND_DATA = 0x24,
CMD_RESET = 0x25,
CMD_SECTOR_ERASE = 0x26,
CMD_CRC32 = 0x27,
CMD_GET_CHIP_ID = 0x28,
CMD_MEMORY_READ = 0x2A,
CMD_MEMORY_WRITE = 0x2B,
CMD_BANK_ERASE = 0x2C,
CMD_SET_CCFG = 0x2D,
};
/* Early samples had different command IDs */
enum
{
REV1_CMD_BANK_ERASE = 0x2A,
REV1_CMD_SET_CCFG = 0x2B,
REV1_CMD_MEMORY_READ = 0x2C,
REV1_CMD_MEMORY_WRITE = 0x2D,
};
enum {
CMD_RET_SUCCESS = 0x40,
CMD_RET_UNKNOWN_CMD = 0x41,
CMD_RET_INVALID_CMD = 0x42,
CMD_RET_INVALID_ADR = 0x43,
CMD_RET_FLASH_FAIL = 0x44,
};
protected:
// Virtual functions from SblDevice
uint32_t ping();
uint32_t readStatus(uint32_t *pui32Status);
uint32_t readDeviceId(uint32_t *pui32DeviceId);
virtual uint32_t readFlashSize(uint32_t *pui32FlashSize);
virtual uint32_t readRamSize(uint32_t *pui32RamSize);
uint32_t reset();
uint32_t eraseFlashRange(uint32_t ui32StartAddress, uint32_t ui32ByteCount);
uint32_t writeFlashRange(uint32_t ui32StartAddress, uint32_t ui32ByteCount, const char *pcData);
uint32_t readMemory32(uint32_t ui32StartAddress, uint32_t ui32UnitCount, uint32_t *pui32Data);
uint32_t readMemory8(uint32_t ui32StartAddress, uint32_t ui32UnitCount, char *pcData);
uint32_t writeMemory32(uint32_t ui32StartAddress, uint32_t ui32UnitCount, const uint32_t *pui32Data);
uint32_t writeMemory8(uint32_t ui32StartAddress, uint32_t ui32UnitCount, const char *pcData);
uint32_t calculateCrc32(uint32_t ui32StartAddress, uint32_t ui32ByteCount, uint32_t *pui32Crc);
uint32_t sendCmd(uint32_t ui32Cmd, const char *pcSendData = NULL, uint32_t ui32SendLen = 0);
std::string getCmdString(uint32_t ui32Cmd);
uint32_t addressToPage(uint32_t ui32Address);
bool addressInRam(uint32_t ui32StartAddress, uint32_t ui32ByteCount = 1);
bool addressInFlash(uint32_t ui32StartAddress, uint32_t ui32ByteCount = 1);
uint32_t convertCmdForEarlySamples(uint32_t ui32Cmd);
virtual uint32_t getBootloaderEnableAddress();
// CC2650 specific
uint32_t eraseFlashBank();
uint32_t setCCFG(uint32_t ui32Field, uint32_t ui32FieldValue);
// Device revision. Used internally by SBL to handle early samples with different command IDs.
uint32_t m_deviceRev;
private:
uint32_t initCommunication(bool bSetXosc);
uint32_t cmdDownload(uint32_t ui32Address, uint32_t ui32Size);
uint32_t cmdSendData(const char *pcData, uint32_t ui32ByteCount);
std::string getCmdStatusString(uint32_t ui32Status);
bool addressInBLWorkMemory(uint32_t ui32StartAddr, uint32_t ui32ByteCount = 1);
};
#endif // __SBL_DEVICE_CC2650_H__

View File

@@ -1,330 +0,0 @@
/******************************************************************************
* Filename: sbl_device_cc2652.cpp
* Revised: $Date$
* Revision: $Revision$
*
* Description: Serial Bootloader device file for CC13x2/CC26x2
*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <sbllib.h>
#include "sbl_device.h"
#include "sbl_device_cc2652.h"
#include "serialib.h"
//-----------------------------------------------------------------------------
/** \brief Constructor
*/
//-----------------------------------------------------------------------------
SblDeviceCC2652::SblDeviceCC2652() : SblDeviceCC2650()
{
DEBUG_PRINT("\n");
m_pageEraseSize = SBL_CC2652_PAGE_ERASE_SIZE;
}
//-----------------------------------------------------------------------------
/** \brief Destructor
*/
//-----------------------------------------------------------------------------
SblDeviceCC2652::~SblDeviceCC2652()
{
DEBUG_PRINT("\n");
}
//-----------------------------------------------------------------------------
/** \brief This function reads device FLASH size in bytes.
*
* \param[out] pui32FlashSize
* Pointer to where FLASH size is stored.
* \return
* Returns SBL_SUCCESS, ...
*/
//-----------------------------------------------------------------------------
uint32_t
SblDeviceCC2652::readFlashSize(uint32_t *pui32FlashSize)
{
DEBUG_PRINT("\n");
uint32_t retCode = SBL_SUCCESS;
//
// Read CC2652 DIECFG0 (contains FLASH size information)
//
uint32_t addr = SBL_CC2652_FLASH_SIZE_CFG;
uint32_t value;
if ((retCode = readMemory32(addr, 1, &value)) != SBL_SUCCESS)
{
setState((tSblStatus)retCode, "Failed to read device FLASH size: %s", getLastError().c_str());
return retCode;
}
//
// Calculate flash size (The number of flash sectors are at bits [7:0])
//
value &= 0xFF;
*pui32FlashSize = value*SBL_CC2652_PAGE_ERASE_SIZE;
m_flashSize = *pui32FlashSize;
return SBL_SUCCESS;
}
//-----------------------------------------------------------------------------
/** \brief This function reads device RAM size in bytes.
*
* \param[out] pui32RamSize
* Pointer to where RAM size is stored.
* \return
* Returns SBL_SUCCESS, ...
*/
//-----------------------------------------------------------------------------
uint32_t
SblDeviceCC2652::readRamSize(uint32_t *pui32RamSize)
{
DEBUG_PRINT("\n");
int retCode = SBL_SUCCESS;
uint32_t addr = SBL_CC2652_RAM_SIZE_CFG;
uint32_t value;
if ((retCode = readMemory32(addr, 1, &value)) != SBL_SUCCESS)
{
setState(retCode, "Failed to read device RAM size: %s", getLastError().c_str());
return retCode;
}
uint32_t ramSizeInfo = (value & CHIP_SRAM_SIZE_INFO_M) >> CHIP_SRAM_SIZE_INFO_S;
m_ramSize = calculateRamSize(ramSizeInfo);
if (*pui32RamSize != NULL)
{
*pui32RamSize = m_ramSize;
}
return retCode;
}
//-----------------------------------------------------------------------------
/** \brief Calculate RAM size.
*
* \param[in] ramSizeInfo
* Register value for RAM size configuration (TOP:PRCM:RAMHWOPT).
* The argument is optional and the default value is 3 (RAM size 80 KB)
* \returns uint32_t
* Ram size
*/
//-----------------------------------------------------------------------------
uint32_t SblDeviceCC2652::calculateRamSize(uint32_t ramSizeInfo)
{
DEBUG_PRINT("\n");
uint32_t ramSize;
switch (ramSizeInfo)
{
case 0:
ramSize = (32 * 1024);
break;
case 1:
ramSize = (48 * 1024);
break;
case 2:
ramSize = (64 * 1024);
break;
case 3:
default:
ramSize = (80 * 1024);
break;
}
return ramSize;
}
//-----------------------------------------------------------------------------
/** \brief This function returns the FLASH address of the bootloader enable
* configuration.
*
* \return
* Returns true if the address/range is within the device RAM.
*/
//-----------------------------------------------------------------------------
uint32_t SblDeviceCC2652::getBootloaderEnableAddress()
{
DEBUG_PRINT("\n");
return SBL_CC2652_FLASH_START_ADDRESS + getFlashSize() - getPageEraseSize() + SBL_CC2652_BL_CONFIG_PAGE_OFFSET;
}
//-----------------------------------------------------------------------------
/** \brief This function returns a string with the device command name of
* \e ui32Cmd.
*
* \param[out] ui32Cmd
* The serial bootloader command.
* \return
* Returns std::string with name of device command.
*/
//-----------------------------------------------------------------------------
std::string
SblDeviceCC2652::getCmdString(uint32_t ui32Cmd)
{
DEBUG_PRINT("\n");
std::string cmd = SblDeviceCC2650::getCmdString(ui32Cmd);
if (cmd.find("Unknown") != std::string::npos)
{
switch (ui32Cmd)
{
case SblDeviceCC2652::CMD_DOWNLOAD_CRC: cmd = "CMD_DOWNLOAD_CRC"; break;
default: cmd = "Unknown command"; break;
}
}
return cmd;
}
//-----------------------------------------------------------------------------
/** \brief This function sends the CC2652 download CRC command and handles the
* device response.
*
* \param[in] ui32Address
* The start address in CC2652 flash.
* \param[in] ui32Size
* Number of bytes to be sent.
* \param[in] ui32Crc
* Total number of bytes to be programmed.
*
* \return
* Returns SBL_SUCCESS if command and response was successful.
*/
//-----------------------------------------------------------------------------
uint32_t SblDeviceCC2652::cmdDownloadCrc(uint32_t ui32Address, uint32_t ui32Size, uint32_t ui32Crc)
{
DEBUG_PRINT("\n");
int retCode = SBL_SUCCESS;
bool bSuccess = false;
//
// Check input arguments
//
if (!addressInFlash(ui32Address, ui32Size) &&
!addressInRam(ui32Address, ui32Size))
{
setState(SBL_ARGUMENT_ERROR, "Specified address range (0x%08X + %d bytes) is not in device FLASH nor RAM.\n", ui32Address, ui32Size);
return SBL_ARGUMENT_ERROR;
}
//
// Generate payload
// - 4B Program address
// - 4B Program data
// - 4B CRC
//
char pcPayload[12];
ulToCharArray(ui32Address, &pcPayload[0]);
ulToCharArray(ui32Size, &pcPayload[4]);
ulToCharArray(ui32Crc, &pcPayload[8]);
//
// Send command
//
if ((retCode = sendCmd(SblDeviceCC2652::CMD_DOWNLOAD_CRC, pcPayload, 12) != SBL_SUCCESS))
{
return retCode;
}
//
// Receive command response (ACK/NAK)
//
if ((retCode = getCmdResponse(bSuccess)) != SBL_SUCCESS)
{
return retCode;
}
//
// Return command response
//
return (bSuccess) ? SBL_SUCCESS : SBL_ERROR;
}
//-----------------------------------------------------------------------------
/** \brief Send command.
*
* \param[in] ui32Cmd
* The command to send.
* \param[in] pcSendData
* Pointer to the data to send with the command.
* \param[in] ui32SendLen
* The number of bytes to send from \e pcSendData.
* \return
* Returns SBL_SUCCESS, ...
*/
//-----------------------------------------------------------------------------
uint32_t
SblDeviceCC2652::sendCmd(uint32_t ui32Cmd, const char *pcSendData/* = NULL*/,
uint32_t ui32SendLen/* = 0*/)
{
DEBUG_PRINT("\n");
unsigned char pktLen = ui32SendLen + 3; // +3 => <1B Length>, <1B checksum>, <1B cmd>
std::vector<char> pvPkt((pktLen));
unsigned char pktSum = generateCheckSum(ui32Cmd, pcSendData, ui32SendLen);
//
// Build packet
//
pvPkt.at(0) = pktLen;
pvPkt.at(1) = pktSum;
pvPkt.at(2) = (unsigned char)ui32Cmd;
if (ui32SendLen)
{
memcpy(&pvPkt[3], pcSendData, ui32SendLen);
}
//
// Send packet
//
if (m_pCom->writeBytes(&pvPkt[0], pvPkt.size()) < 1)
{
setState(SBL_PORT_ERROR, "\nWriting to device failed (Command 0x%04x:'%s').\n", ui32Cmd,getCmdString(ui32Cmd).c_str());
return SBL_PORT_ERROR;
}
//
// Empty and deallocate vector
//
pvPkt.clear();
std::vector<char>().swap(pvPkt);
return SBL_SUCCESS;
}

View File

@@ -1,77 +0,0 @@
#ifndef __SBL_DEVICE_CC2652_H__
#define __SBL_DEVICE_CC2652_H__
/******************************************************************************
* Filename: sbl_device_cc2652.h
* Revised: $Date$
* Revision: $Revision$
*
* Description: Serial Bootloader for CC13x2/CC26x2 header file.
*
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include "sbl_device_cc2650.h"
#define SBL_CC2652_PAGE_ERASE_SIZE 8192
#define SBL_CC2652_FLASH_SIZE_CFG 0x4003002C
#define SBL_CC2652_RAM_SIZE_CFG 0x40082250
#define SBL_CC2652_RAM_SIZE_CFG 0x40082250
#define SBL_CC2652_FLASH_START_ADDRESS SBL_CC2650_FLASH_START_ADDRESS
#define SBL_CC2652_BL_CONFIG_PAGE_OFFSET 0x1FDB
#define CHIP_SRAM_SIZE_INFO 0x40082250
#define CHIP_SRAM_SIZE_INFO_M 0x00000003
#define CHIP_SRAM_SIZE_INFO_S 0
class SblDeviceCC2652 : public SblDeviceCC2650
{
public:
SblDeviceCC2652(); // Constructor
~SblDeviceCC2652(); // Destructor
enum {
CMD_DOWNLOAD_CRC = 0x2F,
};
protected:
uint32_t readFlashSize(uint32_t *pui32FlashSize);
uint32_t readRamSize(uint32_t *pui32RamSize);
uint32_t calculateRamSize(uint32_t ramSizeInfo);
uint32_t getBootloaderEnableAddress();
private:
std::string getCmdString(uint32_t ui32Cmd);
uint32_t sendCmd(uint32_t ui32Cmd, const char *pcSendData = NULL, uint32_t ui32SendLen = 0);
uint32_t cmdDownloadCrc(uint32_t ui32Address, uint32_t ui32Size, uint32_t uiCrc);
};
#endif // __SBL_DEVICE_CC2652_H__

View File

@@ -1,66 +0,0 @@
#ifndef __SBL_EB_INFO_H__
#define __SBL_EB_INFO_H__
/******************************************************************************
* Filename: sbl_eb_info.h
* Revised: $Date: 2013-07-09 15:06:47 +0200 (Tue, 09 Jul 2013) $
* Revision: $Revision: 26800 $
*
* Description: Serial Bootloader EB info class header file.
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <string.h>
class SblEbInfo
{
public:
enum
{
DEVICE_NAME_SIZE = 15,
EB_PORT_SIZE = 16,
DESCRIPTION_SIZE = 256
};
char ebPort[EB_PORT_SIZE]; // E.g. COM42
char ebDescription[DESCRIPTION_SIZE];
char devName[DEVICE_NAME_SIZE]; // E.g. CC2538 for CC2650
SblEbInfo& operator = (const SblEbInfo& other) {
strncpy(ebPort, other.ebPort, EB_PORT_SIZE);
strncpy(ebDescription, other.ebDescription, DESCRIPTION_SIZE);
strncpy(devName, other.devName, DEVICE_NAME_SIZE);
return *this;
}
};
#endif // __SBL_EB_INFO_H__

View File

@@ -1,39 +0,0 @@
/******************************************************************************
* Filename: sbllib.cpp
* Revised: $Date$
* Revision: $Revision$
*
* Description: Serial Bootloader Library main file.
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/

View File

@@ -1,69 +0,0 @@
#ifndef __SBLLIB_H__
#define __SBLLIB_H__
/******************************************************************************
* Filename: sbllib.h
* Revised: $Date$
* Revision: $Revision$
*
* Description: Serial Bootloader Library header file.
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include <string>
#include <stdint.h>
#include "debug.h"
#define SBL_MAX_DEVICES 20
#define SBL_DEFAULT_RETRY_COUNT 1
#define SBL_DEFAULT_READ_TIMEOUT 100 // in ms
#define SBL_DEFAULT_WRITE_TIMEOUT 200 // in ms
typedef enum {
SBL_SUCCESS = 0,
SBL_ERROR,
SBL_ARGUMENT_ERROR,
SBL_TIMEOUT_ERROR,
SBL_PORT_ERROR,
SBL_ENUM_ERROR,
SBL_UNSUPPORTED_FUNCTION,
} tSblStatus;
#include "serialib.h"
#include "sbl_device.h"
#include "sbl_device_cc2538.h"
#include "sbl_device_cc2650.h"
#include "sbl_device_cc2652.h"
#include "sbl_eb_info.h"
#endif // __SBLLIB_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,220 +0,0 @@
/*!
\file serialib.h
\brief Header file of the class serialib. This class is used for communication over a serial device.
\author Philippe Lucidarme (University of Angers)
\version 2.0
\date december the 27th of 2019
This Serial library is used to communicate through serial port.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER 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 THE SOFTWARE.
This is a licence-free software, it can be used by anyone who try to build a better world.
*/
#ifndef SERIALIB_H
#define SERIALIB_H
// Used for TimeOut operations
#include <sys/time.h>
// Include for windows
#if defined (_WIN32) || defined (_WIN64)
// Accessing to the serial port under Windows
#include <windows.h>
#endif
// Include for Linux
#ifdef __linux__
#include <stdlib.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <termios.h>
#include <string.h>
#include <iostream>
// File control definitions
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <vector>
#endif
/*! To avoid unused parameters */
#define UNUSED(x) (void)(x)
/*! \class serialib
\brief This class is used for communication over a serial device.
*/
class serialib
{
public:
//_____________________________________
// ::: Constructors and destructors :::
// Constructor of the class
serialib ();
// Destructor
~serialib ();
//_________________________________________
// ::: Configuration and initialization :::
// Open a device
char openDevice (const char *Device,const unsigned int Bauds);
// Close the current device
void closeDevice();
//___________________________________________
// ::: Read/Write operation on characters :::
// Write a char
char writeChar (char);
// Read a char (with timeout)
char readChar (char *pByte,const unsigned int timeOut_ms=0);
//________________________________________
// ::: Read/Write operation on strings :::
// Write a string
char writeString (const char *String);
// Read a string (with timeout)
int readString ( char *receivedString,
char finalChar,
unsigned int maxNbBytes,
const unsigned int timeOut_ms=0);
// _____________________________________
// ::: Read/Write operation on bytes :::
// Write an array of bytes
int writeBytes (const void *Buffer, const unsigned int NbBytes);
// Read an array of byte (with timeout)
int readBytes (void *buffer,unsigned int maxNbBytes,const unsigned int timeOut_ms=100, unsigned int sleepDuration_us=100);
// _________________________
// ::: Special operation :::
// Empty the received buffer
char flushReceiver();
// Return the number of bytes in the received buffer
int available();
// _________________________
// ::: Access to IO bits :::
// Set CTR status (Data Terminal Ready, pin 4)
bool DTR(bool status);
bool setDTR();
bool clearDTR();
// Set RTS status (Request To Send, pin 7)
bool RTS(bool status);
bool setRTS();
bool clearRTS();
// Get RI status (Ring Indicator, pin 9)
bool isRI();
// Get DCD status (Data Carrier Detect, pin 1)
bool isDCD();
// Get CTS status (Clear To Send, pin 8)
bool isCTS();
// Get DSR status (Data Set Ready, pin 9)
bool isDSR();
// Get RTS status (Request To Send, pin 7)
bool isRTS();
// Get CTR status (Data Terminal Ready, pin 4)
bool isDTR();
private:
// Read a string (no timeout)
int readStringNoTimeOut (char *String,char FinalChar,unsigned int MaxNbBytes);
// Current DTR and RTS state (can't be read on WIndows)
bool currentStateRTS;
bool currentStateDTR;
#if defined (_WIN32) || defined( _WIN64)
// Handle on serial device
HANDLE hSerial;
// For setting serial port timeouts
COMMTIMEOUTS timeouts;
#endif
#ifdef __linux__
int fd;
#endif
};
/*! \class timeOut
\brief This class can manage a timer which is used as a timeout.
*/
// Class timeOut
class timeOut
{
public:
// Constructor
timeOut();
// Init the timer
void initTimer();
// Return the elapsed time since initialization
unsigned long int elapsedTime_ms();
private:
// Used to store the previous time (for computing timeout)
struct timeval previousTime;
};
#endif // serialib_H