feat: cc2640r2l_2in66_ssd1680a_296x152. (#16)

This commit is contained in:
susabolca
2024-07-10 20:26:54 +08:00
committed by GitHub
parent 0fadcdc20f
commit f0e3c62481
7 changed files with 1488 additions and 3 deletions

BIN
doc/2in66_bwr.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -10,6 +10,10 @@ cc2640r2 电子标签改电子时钟固件.
- cc2640r2l_2in13_ssd1680_250x122
![cc2640r2l_2in13_ssd1680_250x122](doc/2in13_bwr.jpg)
- cc2640r2l_2in66_ssd1680a_296x152
![cc2640r2l_2in66_ssd1680a_296x152](doc/2in66_bwr.jpg)
- cc2640r2l_2in9_ssd1680a_296x128 **主要支持**

603
src/app/epd_2in66.c Normal file
View File

@@ -0,0 +1,603 @@
// EPD 2in9 SSD1680A 296x152
#define EPD_SSD1680A
#define EPD_WIDTH 296
#define EPD_HEIGHT 152
#include <ti/drivers/PIN.h>
#include <ti/sysbios/hal/Seconds.h> // Seconds_get
//#include <ti/sysbios/knl/Task.h> // System_sleep
#include <xdc/runtime/System.h> // snprintf
#include <driverlib/aon_batmon.h> // battery & temp
#include <util.h>
#include "epd_driver.h"
#include <time.h> // time
#include <stdint.h> // uint8_t
#include <string.h> // memset
// OBD
#include "OneBitDisplay.h"
#include "font16.h"
#include "font24.h"
#include "font24zh.h"
#include "font80.h"
// One Bit Display
OBDISP obd = {0};
extern const uint8_t ucMirror[];
#if 0
/*
* <int.frac> format size (3.8) bits.
* int for 0-3 voltage
* frac each means 1/256 of ONE voltage
*/
#define INTFRAC_V(x) (x>>8)
#define INTFRAC_mV(x) ((x&0xff)*1000/256)
#define INTFRAC2MV(x) (INTFRAC_mV(x)+(INTFRAC_V(x)*1000))
#endif
// https://www.mdpi.com/2072-666X/12/5/578
#define _VS(x) x<<6
#define VSS _VS(0b00)
#define VSH1 _VS(0b01)
#define VSL _VS(0b10)
#define VSH2 _VS(0b11)
#if 0
/* the LUT lots of values are zeros, use a lite version instead.
*/
static const uint8_t lut_full_bwr[] = {
// 0: LUTC x 7
// RP A B C D SRAB SRCD
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
// 56: LUTR x 7
0x1, VSL|0x2f, 0x0, VSH2|0x3f, 0x0, 0x1, 0xa,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
// 112: LUTW x 7
0x1, VSL|0x3f, 0x0, 0x0, 0x0, 0x2, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
// 168: LUTB x 7
0x1, VSH1|0x2f, 0x0, 0x0, 0x0, 0x1, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
// FR
0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz
// XON
0x0, 0x0,
// EOPT VGH VSH1 VSH2 VSL VCOM
// 3F 03 04 2C
// 22 -20v 15v 3v -15v
0x22, 0x17, 0x41, 0x94, 0x32, 0x36
};
static void EPD_2IN9_Lut(const unsigned char *lut)
{
EPD_SSD_SendCommand(0x32);
for(int i=0; i<227; i++) {
EPD_SSD_SendData(lut[i]);
}
// gate voltage
EPD_SSD_SendCommand(0x3F);
EPD_SSD_SendData(*(lut+227));
EPD_SSD_SendCommand(0x03);
EPD_SSD_SendData(*(lut+228));
// source voltage
EPD_SSD_SendCommand(0x04);
EPD_SSD_SendData(*(lut+229)); // VSH
EPD_SSD_SendData(*(lut+230)); // VSH2
EPD_SSD_SendData(*(lut+231)); // VSL
EPD_SSD_SendCommand(0x2C);
EPD_SSD_SendData(*(lut+232));
}
#endif
/* LUT lite is small than LUT used in SSD1680A, only 35 bytes.
* lut_lite_fast_bw is default lut for clock display,
* lut_lite_gray8_bwr is default lut for BLE display.
*/
#define LUT_LITE_LEN 35
// LUT for clock fast display. (only black/white)
static const uint8_t lut_lite_fast_bw[LUT_LITE_LEN] = {
// RP A B C D SRAB SRCD
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // LUTC
0x0, VSL|0x3f, 0x0, VSH2|0x3f, 0x0, 0x0, 0x0, // LUTR
0x1, VSL|0x3f, 0x0, 0x0, 0x0, 0x2, 0x0, // LUTW
0x1, VSH1|0x1f, 0x0, 0x0, 0x0, 0x1, 0x0, // LUTB
// FR
0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz
// EOPT VGH VSH1 VSH2 VSL VCOM
// 3F 03 04 2C
// 22 -20v 15v 3v -15v
0x22, 0x17, 0x41, 0x94, 0x32, 0x36
};
// LUT for BLE Gray display (8 steps)
static const uint8_t lut_lite_gray8_bwr[LUT_LITE_LEN] = {
// RP A B C D SRAB SRCD
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // LUTC
0x1, VSH2|0x3f, 0x0, 0x0, 0x0, 0x1, 0x0, // LUTR
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // LUTW
0x1, VSH1|0x03, 0x0, 0x0, 0x0, 0x1, 0x0, // LUTB
// FR
0x04, // 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz
// EOPT VGH VSH1 VSH2 VSL VCOM
// 3F 03 04 2C
// 22 -20v 15v 3.0v -15v
0x22, 0x17, 0x41, 0x94, 0x32, 0x36
};
static void EPD_2IN9_Lut(const unsigned char *lut)
{
// SSD1680A uses 233 LUT.
// 0, wareform setting
EPD_SSD_SendCommand(0x32);
for (int j=0; j<4; j++) { // LUT0-3
// wave setting
for (int i=0; i<7; i++) {
EPD_SSD_SendData(lut[j*7+i]);
}
// no config
for (int i=0; i<7*7; i++) {
EPD_SSD_SendData(0x00);
}
}
// 4 * (7+49) = 224
// 224, FR
// 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz
EPD_SSD_SendData(lut[28]);
// 225, XON
EPD_SSD_SendData(0x00);
EPD_SSD_SendData(0x00);
// EOPT VGH VSH1 VSH2 VSL VCOM
// 3F 03 04 2C
// 22 -20v 15v 3v -15v
// 0x22, 0x17, 0x41, 0x94, 0x32, 0x36
// 227, gate voltage
EPD_SSD_SendCommand(0x3F);
EPD_SSD_SendData(lut[29]);
EPD_SSD_SendCommand(0x03);
EPD_SSD_SendData(lut[30]);
// 229, source voltage
EPD_SSD_SendCommand(0x04);
EPD_SSD_SendData(lut[31]); // VSH
EPD_SSD_SendData(lut[32]); // VSH2
EPD_SSD_SendData(lut[33]); // VSL
// 232, VCOM
EPD_SSD_SendCommand(0x2C);
EPD_SSD_SendData(lut[34]);
}
static void EPD_2IN9_Lut_ById(int idx)
{
uint8_t buf[LUT_LITE_LEN];
const uint8_t *lut = buf;
int rc = EPD_SNV_LoadLut(idx, buf, LUT_LITE_LEN);
if (rc != SUCCESS) {
// load default if no lut found.
switch (idx) {
case 0:
lut = lut_lite_fast_bw;
break;
case 1:
lut = lut_lite_gray8_bwr;
break;
default:
lut = NULL;
break;
}
}
if (lut) {
EPD_2IN9_Lut(lut);
}
}
static void EPD_2IN9_SoftReset()
{
EPD_SSD_SendCommand(0x12); // soft reset
EPD_SSD_WaitBusy(100);
}
static int8_t EPD_2IN9_ReadTemp()
{
int8_t rc;
//EPD_SSD_SendCommand(0x12); // soft reset
//EPD_SSD_WaitBusy(100);
// Border Waveform
EPD_SSD_SendCommand(0x3C);
EPD_SSD_SendData(0x05);
// Temperature sensor control
EPD_SSD_SendCommand(0x18);
EPD_SSD_SendData(0x80); // 80: internal sensor 48: external sensor
// Display update control
EPD_SSD_SendCommand(0x22);
EPD_SSD_SendData(0xb1); // full: 0xf7
// Master Activation
EPD_SSD_SendCommand(0x20);
EPD_SSD_WaitBusy(100);
// read temperature
EPD_SSD_SendCommand(0x1b);
rc = EPD_SSD_ReadData();
return rc;
}
static void EPD_2IN9_LoadImage(uint8_t *image, int size, uint8_t cmd)
{
EPD_SSD_SendCommand(cmd);
for (int i = 0; i < size; i++) {
EPD_SSD_SendData(image[i]);
}
}
static void EPD_2IN9_BWR(int width, int height, int left, int top)
{
// left up corner
int w0 = left;
int h0 = top/8;
// right bottom corner
int w1 = w0 + width - 1;
int h1 = h0 + height/8 - 1;
// soft reset
//EPD_SSD_SendCommand(0x12);
//EPD_SSD_WaitBusy(100);
// Border Waveform
EPD_SSD_SendCommand(0x3C);
EPD_SSD_SendData(0x05);
// Driver output control
EPD_SSD_SendCommand(0x01);
EPD_SSD_SendData(0x28); // mux=0x128(296)
EPD_SSD_SendData(0x01);
EPD_SSD_SendData(0x01); // gd=0, sm=0, tb=1
EPD_SSD_SendCommand(0x11); //data entry mode
EPD_SSD_SendData(0x07); // am=1, id=11
// Set RAM X Address Start/End
EPD_SSD_SendCommand(0x44);
EPD_SSD_SendData(h0 & 0xff);
EPD_SSD_SendData(h1 & 0xff);
// Set RAM Y Address Start/End
EPD_SSD_SendCommand(0x45); //set Ram-Y address start/end position
EPD_SSD_SendData(w0 & 0xff);
EPD_SSD_SendData(w0 >> 8);
EPD_SSD_SendData(w1 & 0xff);
EPD_SSD_SendData(w1 >> 8);
// Temperature sensor control
EPD_SSD_SendCommand(0x18);
EPD_SSD_SendData(0x80); // 80: internal sensor 48: external sensor
}
void EPD_2IN9_WriteRam(uint8_t *image, int width, int height, int left, int top, uint8_t is_red)
{
// data size in bytes
int size = width*height/8;
// Set Ram X address
EPD_SSD_SendCommand(0x4E);
EPD_SSD_SendData(top & 0xff);
// Set Ram Y address
EPD_SSD_SendCommand(0x4F);
EPD_SSD_SendData(left & 0xff);
EPD_SSD_SendData(left >> 8);
const uint8_t reg = is_red ? 0x26 : 0x24; // BW: 0x24, Red: 0x26
if (image) {
EPD_2IN9_LoadImage(image, size, reg);
} else {
EPD_SSD_SendCommand(reg);
for (int i = 0; i < size; i++) {
EPD_SSD_SendData(is_red ? 0x00 : 0xff);
}
}
}
void EPD_2IN9_Display(uint8_t reg)
{
EPD_SSD_SendCommand(0x22);
EPD_SSD_SendData(reg);
EPD_SSD_SendCommand(0x20);
}
void EPD_2IN9_Sleep(void)
{
EPD_SSD_SendCommand(0x10); //enter deep sleep
EPD_SSD_SendData(0x01); // 01: mode 1, 11: mode 2
}
void EPD_2IN9_Clear(void)
{
// wakeup EPD
EPD_SSD_Reset();
// soft reset
EPD_2IN9_SoftReset();
// clear
EPD_2IN9_BWR(EPD_WIDTH, EPD_HEIGHT, 0, 0);
EPD_2IN9_WriteRam(NULL, EPD_WIDTH, EPD_HEIGHT, 0, 0, 0);
EPD_2IN9_WriteRam(NULL, EPD_WIDTH, EPD_HEIGHT, 0, 0, 1);
// display
EPD_2IN9_Display(0xf7); // c7: by REG f7: by OTP b1: no display
// wait & sleep
EPD_SSD_WaitBusy(15 * 1000);
EPD_2IN9_Sleep();
}
void EPD_2IN9_Update_Clock(void)
{
time_t now;
time(&now);
// adjust TZ offset
now += utc_offset_mins * 60;
// get localtime
struct tm *l = localtime(&now);
if (clock_last == l->tm_min) {
return;
}
// full update on first start and midnight.
bool full_upd = (clock_last > 60 || (l->tm_hour == 0 && l->tm_min == 0)) ? true : false;
// clock started.
clock_last = l->tm_min;
// wakeup EPD
EPD_SSD_Reset();
// create obd
char buf[32];
obdCreateVirtualDisplay(&obd, EPD_WIDTH, 128, epd_buffer);
// soft reset
EPD_2IN9_SoftReset();
// ==== PAGE 1 ====
obdFill(&obd, 0, 0);
// date
System_snprintf(buf, 32, "%u-%02u-%02u", 1900+l->tm_year, l->tm_mon+1, l->tm_mday);
obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_24, 2, 22, buf, 1);
// week
#if 1 // in chinese
{
char fmt[] = {0x37, 0x38, 0x30 + l->tm_wday, '\0'}; // chinese week day
obdWriteStringCustom(&obd, (GFXfont *)&Hei24pt, 158, 20, fmt, 1);
}
#else
const char *wstr[]={"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
System_snprintf(buf, 32, "%u-%02u-%02u %s", 1900+l->tm_year, l->tm_mon+1, l->tm_mday, wstr[l->tm_wday]);
obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_24, 2, 22, buf, 1);
#endif
// temp
epd_temperature = EPD_2IN9_ReadTemp();
const char fmt[] = {'%', '3', 'u', 0xb0, 'c', '\0'}; // degrees celsius
System_snprintf(buf, 32, fmt, epd_temperature);
obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_24, 236, 22, buf, 1);
// time
System_snprintf(buf, 32, "%02d:%02d", l->tm_hour, l->tm_min);
obdWriteStringCustom(&obd, (GFXfont *)&DSEG7_Classic_Regular_80, 10, 123, buf, 1);
// endian and invent
for (int i=0; i<sizeof(epd_buffer); i++) {
uint8_t c = epd_buffer[i];
epd_buffer[i] = ~ucMirror[c];
}
// full update every 30 mins
EPD_2IN9_BWR(EPD_WIDTH, EPD_HEIGHT, 0, 0);
EPD_2IN9_WriteRam(epd_buffer, EPD_WIDTH, 128, 0, 0, 0);
EPD_2IN9_WriteRam(NULL, EPD_WIDTH, 128, 0, 0, 1);
// ==== PAGE 2 ====
obdFill(&obd, 0, 0);
// BLE dev name
extern void getBleAdvName(char* buf);
getBleAdvName(buf);
obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_16, 2, 24, buf, 1);
// battery voltage
uint8_t v = EPD_BATT_Percent();
System_snprintf(buf, 32, "%3u%%", v);
obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_16, 250, 24, buf, 1);
// endian and invent
for (int i=0; i<sizeof(epd_buffer); i++) {
uint8_t c = epd_buffer[i];
epd_buffer[i] = ~ucMirror[c];
}
//EPD_2IN9_BWR(EPD_WIDTH, 24, 0, 128);
EPD_2IN9_WriteRam(epd_buffer, EPD_WIDTH, 24, 0, 128/8, 0);
EPD_2IN9_WriteRam(NULL, EPD_WIDTH, 24, 0, 128/8, 1);
// load lut
if (!full_upd) EPD_2IN9_Lut_ById(0);
// show
EPD_2IN9_Display(full_upd ? 0xf7 : 0xc7); // c7: by REG f7: by OTP b1: no display
//need_sleep = 1;
EPD_SSD_WaitBusy(15 * 1000);
EPD_2IN9_Sleep();
return;
}
void EPD_2IN9_Update_Image()
{
//static uint8_t last_step = 0;
uint8_t step = epd_step;
switch (step) {
case EPD_CMD_CLR:
EPD_2IN9_Clear();
break;
case EPD_CMD_MODE:
EPD_2IN9_Clear();
break;
case EPD_CMD_RST: // reset
// wakeup EPD
EPD_SSD_Reset();
// soft reset
EPD_2IN9_SoftReset();
// ready BWR
EPD_2IN9_BWR(EPD_WIDTH, EPD_HEIGHT, 0, 0);
//EPD_2IN9_Lut(lut_lite_gray8_bwr);
break;
case EPD_CMD_BW: { // write BW ram
uint8_t top = epd_step_data[0];
if (top == 1) {
EPD_2IN9_WriteRam(epd_buffer, EPD_WIDTH, 24, 0, 128/8, 0);
} else {
EPD_2IN9_WriteRam(epd_buffer, EPD_WIDTH, 128, 0, 0, 0);
}
break;
}
case EPD_CMD_RED: { // write Red ram
uint8_t top = epd_step_data[0];
if (top == 1) {
EPD_2IN9_WriteRam(epd_buffer, EPD_WIDTH, 24, 0, 128/8, 1);
} else {
EPD_2IN9_WriteRam(epd_buffer, EPD_WIDTH, 128, 0, 0, 1);
}
break;
}
case EPD_CMD_FILL: { // write ram with color
uint8_t color = epd_step_data[0];
if (color == 1) { // red
memset(epd_buffer, 0xff, EPD_WIDTH*EPD_HEIGHT/8);
EPD_2IN9_WriteRam(epd_buffer, EPD_WIDTH, EPD_HEIGHT, 0, 0, 1);
} else {
memset(epd_buffer, 0, EPD_WIDTH*EPD_HEIGHT/8);
EPD_2IN9_WriteRam(epd_buffer, EPD_WIDTH, EPD_HEIGHT, 0, 0, 0);
}
break;
}
case EPD_CMD_DP: { // master
// display lut select
uint8_t dpm = epd_step_data[0];
if (dpm == 1) { // lut1
EPD_2IN9_Lut_ById(0);
} else if (dpm == 2) { // lut2
EPD_2IN9_Lut_ById(1);
} else if (dpm == 3) { // lut3
EPD_2IN9_Lut_ById(2);
} else if (dpm == 0xff) { // user ble lut
EPD_2IN9_Lut(ble_data);
}
// otherwise using full lut.
EPD_2IN9_Display(dpm ? 0xc7: 0xf7); // fast display
EPD_SSD_WaitBusy(15 * 1000);
EPD_2IN9_Sleep();
break;
}
}
// done
if (step == epd_step) {
epd_step = EPD_CMD_NC;
}
}
int EPD_SSD_Update(void)
{
if (epd_mode == EPD_MODE_IMG) {
EPD_2IN9_Update_Image();
// stop tick clock
return 0;
}
// default mode
EPD_2IN9_Update_Clock();
// need tick clock
return 1;
}
void EPD_SSD_Init(void)
{
EPD_SSD_Reset();
// if the rtc ahead 10 seconds per day (24 hours)
// ICALL still using 0x8000 (32768 ticks) for 1 seconds,
// (0x8000 + x) / 0x8000 = (24 * 3600) / (24 * 3600 - 10)
// 32768 * 10 / (24 * 3600) = 3.793
RTC_SetCollaborate(epd_rtc_collab);
}

View File

@@ -318,6 +318,10 @@ int8_t RTC_GetCollaborate( void )
#include "epd_2in9_bw.c"
#elif defined(EPD_2IN66_SSD1680A)
#include "epd_2in66.c"
#else
#error "EPD not support."
@@ -372,23 +376,25 @@ void EPD_Command(const uint8_t *cmd, int cmd_len)
// write BW ram
case EPD_CMD_BW:
epd_step_data[0] = cmd[1]; // top
need_update = 1;
break;
// write RED ram
case EPD_CMD_RED:
epd_step_data[0] = cmd[1]; // top
need_update = 1;
break;
// Display
case EPD_CMD_DP:
epd_step_data[0] = cmd[1];
epd_step_data[0] = cmd[1]; // lut
need_update = 1;
break;
// fill ram with color
case EPD_CMD_FILL:
epd_step_data[0] = cmd[1];
epd_step_data[0] = cmd[1]; // color
need_update = 1;
break;
@@ -494,7 +500,7 @@ void EPD_Init()
LED_Blink(EPD_LED1_PIN, 10);
// test LUT size, different EPD has different LUT size.
//lut_size = EPD_SSD_LutDetect();
lut_size = EPD_SSD_LutDetect();
#if 0
uint8_t buf[16] = {'a', 'b', 'c', 'd', };

View File

@@ -0,0 +1,260 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectSpec>
<import spec="cc2640r2_stack_library.projectspec"/>
<project
name="cc2640r2_2in66_ssd1680a_296x152_app"
device="CC2640R2F"
cgtVersion="16.9"
connection="common/targetdb/connections/TIXDS110_Connection.xml"
toolChain="TI"
linkerCommandFile="cc26xx_app.cmd"
preBuildStep=""
postBuildStep="${CG_TOOL_HEX} -order MS --memwidth=8 --romwidth=8 --intel -o ${ProjName}.hex ${ProjName}.out"
description=""
launchWizard="false"
references="cc2640r2_stack_library"
>
<!-- Project properties -->
<property name="type" value="rtsc"/>
<property name="products" value=""/>
<property name="xdcToolsVersion" value="3.50.02.20"/>
<property name="target" value="ti.targets.arm.elf.M3"/>
<property name="platform" value="ti.platforms.simplelink:CC2640R2F"/>
<property name="buildProfile" value="release"/>
<property name="isHybrid" value="true"/>
<property name="configuroOptions" value="--compileOptions ${COMPILER_FLAGS} --xdcpath ${SRC_BLE_DIR}/../../../source;${SRC_BLE_DIR}/../../../kernel/tirtos/packages;${SRC_BLE_DIR}"/>
<configuration
name="FlashROM_StackLibrary"
compilerBuildOptions="
--cmd_file=${SRC_BLE_DIR}/config/build_components.opt
--cmd_file=${SRC_BLE_DIR}/config/factory_config.opt
--cmd_file=${WORKSPACE_LOC}/cc2640r2_stack_library/TOOLS/build_config.opt
-mv7M3 -O2 --opt_for_speed=0 --code_state=16 --abi=eabi -me -g --c99 --gcc --gen_func_subsections=on --display_error_number --diag_wrap=off
-DDeviceFamily_CC26X0R2
-DCACHE_AS_RAM
-DBOARD_DISPLAY_USE_LCD=0
-DBOARD_DISPLAY_USE_UART=0
-DBOARD_DISPLAY_USE_UART_ANSI=1
-DEPD_2IN66_SSD1680A
-DCC2640R2_LAUNCHXL
-DCC26XX
-DCC26XX_R2
-DICALL_EVENTS
-DICALL_JT
-DICALL_LITE
-DICALL_MAX_NUM_ENTITIES=7
-DICALL_MAX_NUM_TASKS=4
-DICALL_STACK0_ADDR
-DPOWER_SAVING
-DRF_SINGLEMODE
-DSTACK_LIBRARY
-DTBM_ACTIVE_ITEMS_ONLY
-DUSE_ICALL
-DDisplay_DISABLE_ALL
-Dxdc_runtime_Assert_DISABLE_ALL
-Dxdc_runtime_Log_DISABLE_ALL
-I${PROJECT_LOC}/Application
-I${PROJECT_LOC}/Startup
-I${PROJECT_LOC}/PROFILES
-I${PROJECT_LOC}/Include
-I${CG_TOOL_ROOT}/include
-I${SRC_BLE_DIR}/controller/cc26xx_r2/inc
-I${SRC_BLE_DIR}/inc
-I${SRC_BLE_DIR}/rom
-I${SRC_BLE_DIR}/common/cc26xx
-I${SRC_BLE_DIR}/icall/inc
-I${SRC_BLE_DIR}/inc
-I${SRC_BLE_DIR}/target
-I${SRC_BLE_DIR}/hal/src/target/_common
-I${SRC_BLE_DIR}/hal/src/target/_common/cc26xx
-I${SRC_BLE_DIR}/hal/src/inc
-I${SRC_BLE_DIR}/heapmgr
-I${SRC_BLE_DIR}/icall/src/inc
-I${SRC_BLE_DIR}/osal/src/inc
-I${SRC_BLE_DIR}/services/src/saddr
-I${SRC_BLE_DIR}/services/src/sdata
-I${SRC_BLE_DIR}/../../../source/ti/devices/cc26x0r2"
linkerBuildOptions="
-l${SRC_BLE_DIR}/../../../source/ti/devices/cc26x0r2/driverlib/bin/ccs/driverlib.lib
-l${SRC_BLE_DIR}/../../../kernel/tirtos/packages/ti/dpl/lib/dpl_cc26x0r2.aem3
-l${SRC_BLE_DIR}/../../../source/ti/drivers/lib/drivers_cc26x0r2.aem3
-l${SRC_BLE_DIR}/../../../source/ti/drivers/rf/lib/rf_singleMode_cc26x0r2.aem3
-l${SRC_BLE_DIR}/../../../source/ti/display/lib/display.aem3
-l${SRC_BLE_DIR}/../../../source/ti/grlib/lib/grlib.aem3
-l${SRC_BLE_DIR}/../../../source/ti/mw/lcd/lib/lcd.aem3
-l${WORKSPACE_LOC}/cc2640r2_stack_library/FlashROM_Library/ble_r2.symbols
-l${WORKSPACE_LOC}/cc2640r2_stack_library/FlashROM_Library/lib_linker.cmd
-l${WORKSPACE_LOC}/cc2640r2_stack_library/FlashROM_Library/cc2640r2_stack_library.lib
-l${SRC_BLE_DIR}/common/cc26xx/ccs/cc26xx_app.cmd
-x
--define=CC26X0ROM=2
--define=CACHE_AS_RAM=1
--diag_suppress=16002-D
--diag_suppress=10247-D
--diag_suppress=10325-D
--diag_suppress=10229-D
--diag_suppress=16032-D"
/>
<configuration
name="FlashROM_StackLibrary_RCOSC"
compilerBuildOptions="
--cmd_file=${SRC_BLE_DIR}/config/build_components.opt
--cmd_file=${SRC_BLE_DIR}/config/factory_config.opt
--cmd_file=${WORKSPACE_LOC}/cc2640r2_stack_library/TOOLS/build_config.opt
-mv7M3 -O4 --opt_for_speed=0 --code_state=16 --abi=eabi -me -g --c99 --gcc --gen_func_subsections=on --display_error_number --diag_wrap=off
-DDeviceFamily_CC26X0R2
-DBOARD_DISPLAY_USE_LCD=0
-DBOARD_DISPLAY_USE_UART=0
-DBOARD_DISPLAY_USE_UART_ANSI=1
-DCC2640R2_LAUNCHXL
-DCC26XX
-DCC26XX_R2
-DICALL_EVENTS
-DICALL_JT
-DICALL_LITE
-DICALL_MAX_NUM_ENTITIES=7
-DICALL_MAX_NUM_TASKS=4
-DICALL_STACK0_ADDR
-DPOWER_SAVING
-DRF_SINGLEMODE
-DSTACK_LIBRARY
-DTBM_ACTIVE_ITEMS_ONLY
-DUSE_ICALL
-DUSE_RCOSC
-DDisplay_DISABLE_ALL
-Dxdc_runtime_Assert_DISABLE_ALL
-Dxdc_runtime_Log_DISABLE_ALL
-I${PROJECT_LOC}/Application
-I${PROJECT_LOC}/Startup
-I${PROJECT_LOC}/PROFILES
-I${PROJECT_LOC}/Include
-I${CG_TOOL_ROOT}/include
-I${SRC_BLE_DIR}/controller/cc26xx_r2/inc
-I${SRC_BLE_DIR}/inc
-I${SRC_BLE_DIR}/rom
-I${SRC_BLE_DIR}/common/cc26xx
-I${SRC_BLE_DIR}/common/cc26xx/rcosc
-I${SRC_BLE_DIR}/icall/inc
-I${SRC_BLE_DIR}/inc
-I${SRC_BLE_DIR}/target
-I${SRC_BLE_DIR}/hal/src/target/_common
-I${SRC_BLE_DIR}/hal/src/target/_common/cc26xx
-I${SRC_BLE_DIR}/hal/src/inc
-I${SRC_BLE_DIR}/heapmgr
-I${SRC_BLE_DIR}/icall/src/inc
-I${SRC_BLE_DIR}/osal/src/inc
-I${SRC_BLE_DIR}/services/src/saddr
-I${SRC_BLE_DIR}/services/src/sdata
-I${SRC_BLE_DIR}/../../../source/ti/devices/cc26x0r2"
linkerBuildOptions="
-l${SRC_BLE_DIR}/../../../source/ti/devices/cc26x0r2/driverlib/bin/ccs/driverlib.lib
-l${SRC_BLE_DIR}/../../../kernel/tirtos/packages/ti/dpl/lib/dpl_cc26x0r2.aem3
-l${SRC_BLE_DIR}/../../../source/ti/drivers/lib/drivers_cc26x0r2.aem3
-l${SRC_BLE_DIR}/../../../source/ti/drivers/rf/lib/rf_singleMode_cc26x0r2.aem3
-l${SRC_BLE_DIR}/../../../source/ti/display/lib/display.aem3
-l${SRC_BLE_DIR}/../../../source/ti/grlib/lib/grlib.aem3
-l${SRC_BLE_DIR}/../../../source/ti/mw/lcd/lib/lcd.aem3
-l${WORKSPACE_LOC}/cc2640r2_stack_library/FlashROM_Library/ble_r2.symbols
-l${WORKSPACE_LOC}/cc2640r2_stack_library/FlashROM_Library/lib_linker.cmd
-l${WORKSPACE_LOC}/cc2640r2_stack_library/FlashROM_Library/cc2640r2_stack_library.lib
-l${SRC_BLE_DIR}/common/cc26xx/ccs/cc26xx_app.cmd
-x
--define=CC26X0ROM=2
--diag_suppress=16002-D
--diag_suppress=10247-D
--diag_suppress=10325-D
--diag_suppress=10229-D
--diag_suppress=16032-D"
/>
<pathVariable name="SDK_ROOT" path="C:\ti\simplelink_cc2640r2_sdk_1_40_00_45" scope="project"/>
<pathVariable name="EXAMPLE_BLE_ROOT" path="../.." scope="project"/>
<pathVariable name="SRC_BLE_DIR" path="${SDK_ROOT}/source/ti/ble5stack" scope="project"/>
<!-- Application Folder -->
<file path="EXAMPLE_BLE_ROOT/src/app/epd_2in66.c" openOnCreation="" excludeFromBuild="true" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/epd_driver.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/epd_driver.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/OneBitDisplay.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/OneBitDisplay.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/obd.inl" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/font8.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/font16.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/font16zh.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/font24.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/font24zh.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/font30.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/font40.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/font60.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/font64.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/font80.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/task_ble.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/task_ble.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/task_epd.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/task_epd.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/common/cc26xx/util.c" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/common/cc26xx/util.h" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/common/cc26xx/rcosc/rcosc_calibration.c" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/common/cc26xx/rcosc/rcosc_calibration.h" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="Application" createVirtualFolders="true" applicableConfigurations="FlashROM_StackLibrary_RCOSC"/>
<!-- Drivers/ECC Folder -->
<file path="SRC_BLE_DIR/common/cc26xx/ecc/ECCROMCC26XX.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Drivers/ECC" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/common/cc26xx/ecc/ECCROMCC26XX.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Drivers/ECC" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<!-- Drivers/TRNG Folder -->
<file path="SRC_BLE_DIR/hal/src/target/_common/TRNGCC26XX.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Drivers/TRNG" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/hal/src/target/_common/TRNGCC26XX.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Drivers/TRNG" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<!-- ICall Folder -->
<file path="SRC_BLE_DIR/icall/src/icall.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="ICall" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/icall/src/inc/icall.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="ICall" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/icall/inc/icall_addrs.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="ICall" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/icall/src/icall_cc2650.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="ICall" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/icall/src/icall_platform.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="ICall" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/icall/src/icall_user_config.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="ICall" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<!-- ICallBLE Folder -->
<file path="SRC_BLE_DIR/icall/app/ble_user_config.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="ICallBLE" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/icall/inc/ble_user_config.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="ICallBLE" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/icall/app/icall_api_lite.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="ICallBLE" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/icall/inc/icall_ble_apimsg.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="ICallBLE" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<!-- Include Folder -->
<file path="SRC_BLE_DIR/inc/gap.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Include" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/profiles/roles/gapbondmgr.h" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="Include" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/inc/gapgattserver.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Include" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/inc/gatt.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Include" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/inc/hci.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Include" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/osal/src/inc/osal_snv.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Include" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<!-- PROFILES Folder -->
<file path="SRC_BLE_DIR/profiles/dev_info/cc26xx/devinfoservice.c" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="PROFILES" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/profiles/dev_info/devinfoservice.h" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="PROFILES" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/inc/gatt_profile_uuid.h" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="PROFILES" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/host/gatt_uuid.c" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="PROFILES" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/inc/gatt_uuid.h" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="PROFILES" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/host/gattservapp_util.c" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="PROFILES" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/profiles/roles/cc26xx/peripheral.c" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="PROFILES" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/profiles/roles/cc26xx/peripheral.h" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="PROFILES" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/epd_service.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="PROFILES" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/epd_service.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="PROFILES" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<!-- Startup Folder -->
<file path="EXAMPLE_BLE_ROOT/src/target/board.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Startup" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/target/CC2640R2_LAUNCHXL.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Startup" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/target/CC2640R2_LAUNCHXL.h" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Startup" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/tirtos/iar/config/ccfg_app_ble.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Startup" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary"/>
<file path="SRC_BLE_DIR/common/cc26xx/rcosc/ccfg_app_ble_rcosc.c" openOnCreation="" excludeFromBuild="false" action="copy" targetDirectory="Startup" createVirtualFolders="true" applicableConfigurations="FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/src/app/main.c" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="Startup" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<!-- TOOLS Folder -->
<file path="EXAMPLE_BLE_ROOT/tirtos/ccs/config/app_ble.cfg" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="TOOLS" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="SRC_BLE_DIR/common/cc26xx/ccs/cc26xx_app.cmd" openOnCreation="" excludeFromBuild="true" action="copy" targetDirectory="TOOLS" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
<file path="EXAMPLE_BLE_ROOT/tirtos/ccs/config/ccs_compiler_defines.bcfg" openOnCreation="" excludeFromBuild="false" action="link" targetDirectory="TOOLS" createVirtualFolders="true" applicableConfigurations="FlashROM"/>
<file path="EXAMPLE_BLE_ROOT/tirtos/ccs/config/ccs_linker_defines.cmd" openOnCreation="" excludeFromBuild="true" action="link" targetDirectory="TOOLS" createVirtualFolders="true" applicableConfigurations="FlashROM, FlashROM_StackLibrary, FlashROM_StackLibrary_RCOSC"/>
</project>
</projectSpec>

View File

@@ -0,0 +1,612 @@
<html lang="zh-CN">
<head>
<style>
div {
padding: 12px;
margin: 2 auto;
}
</style>
</head>
<body>
<script>
let bleDevice;
let gattServer;
let Theservice;
let epdService;
let epochCharacter;
async function sleep(ms) {
await new Promise(resolve => setTimeout(resolve, ms));
}
async function doConnect() {
if (gattServer != null && gattServer.connected) {
if (bleDevice != null && bleDevice.gatt.connected)
bleDevice.gatt.disconnect();
}
else {
bleDevice = await navigator.bluetooth.requestDevice({
filters: [{ namePrefix: ['C26_'] }],
optionalServices: [
0xfff0,
],
//acceptAllDevices: true
});
await bleDevice.addEventListener('gattserverdisconnected', disconnect);
await connect();
}
}
async function connect() {
if (epochCharacter == null) {
info("Connect to " + bleDevice.name)
gattServer = await bleDevice.gatt.connect();
info('> Found GATT server');
epdService = await gattServer.getPrimaryService(0xfff0);
info('> Found EPD service');
epochCharacter = await epdService.getCharacteristic(0xfff1);
document.getElementById("btnConnect").innerHTML = 'Disconnect';
document.getElementById('etagFn').style.visibility = '';
}
}
function disconnect() {
bleDevice = null;
epdService = null;
epochCharacter = null;
info('Disconnected.');
document.getElementById("btnConnect").innerHTML = 'Connect';
document.getElementById('etagFn').style.visibility = 'hidden';
}
async function doSetTime() {
var epoch = Date.now() / 1000 | 0;
var buf = new ArrayBuffer(4);
var arr = new Uint32Array(buf);
arr[0] = epoch;
await epochCharacter.writeValueWithResponse(arr);
info("Write unix epoch: " + epoch);
}
async function doReadEtag() {
var host_epoch = Date.now() / 1000 | 0;
// read current time
var chr = await epdService.getCharacteristic(0xfff1);
var epoch = (await chr.readValue()).getUint32(0, 1);
// read time zone
var chr = await epdService.getCharacteristic(0xfff2);
var tz_min = (await chr.readValue()).getInt32(0, 1);
info(`# host time: ${host_epoch}, diff (${epoch - host_epoch}) seconds.`);
info(`# etag time: ${epoch}, tz: ${tz_min} minutes of UTC.`);
// battery
var chr = await epdService.getCharacteristic(0xfff3);
var batt = (await chr.readValue()).getUint16(0, 1);
// Temperature
var chr = await epdService.getCharacteristic(0xfff4);
var temp = (await chr.readValue()).getInt8(0, 1);
info(`# etag sensor: battery(${batt}mv), temperature(${temp}'C). `);
// RTC Collaborate
var chr = await epdService.getCharacteristic(0xfff5);
var rtc_collab = (await chr.readValue()).getInt8(0, 1);
info(`# rtc collab: ${rtc_collab} every 1 second.`);
}
async function doRtcCollab() {
var col = prompt("对 32.768kHz 晶振补偿频漂,走时快补偿负数,走时慢补偿正数。可选范围 (-8 ~ 8)", 0);
if (col == null || col < -8 || col > 8) return;
var chr = await epdService.getCharacteristic(0xfff5);
var buf = new ArrayBuffer(1);
var arr = new Int8Array(buf);
arr[0] = parseInt(col);
await chr.writeValueWithResponse(arr);
info(`write RTC collabration: ${col}`);
}
async function doTest() {
var chr = await epdService.getCharacteristic(0xfffe);
var buf = new ArrayBuffer(62);
var arr = new Int8Array(buf);
for (var i = 0; i < arr.length; i++) {
arr[i] = i % 8;
}
await chr.writeValueWithResponse(arr);
info(`> write ${arr.length} bytes.`)
//var out = await chr.readValue();
//console.log(out);
}
async function doCmd(cmd, data) {
const epdCmd = {
EPD_CMD_CLR: 1,
EPD_CMD_MODE: 2,
EPD_CMD_BUF: 3,
EPD_CMD_BUF_CONT: 4,
EPD_CMD_LUT: 5,
EPD_CMD_RST: 6,
EPD_CMD_BW: 7,
EPD_CMD_RED: 8,
EPD_CMD_DP: 9,
EPD_CMD_FILL: 10,
EPD_CMD_BUF_PUT: 11,
EPD_CMD_BUF_GET: 12,
EPD_CMD_SNV_WRITE: 13,
EPD_CMD_SNV_READ: 14,
EPD_CMD_SAVE_CFG: 15,
};
var chr = await epdService.getCharacteristic(0xfffe);
switch (cmd) {
case 'read': {
var data = await chr.readValue();
return data;
}
case 'clr':
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_CLR]));
break;
case 'mode':
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_MODE, data == 'image'?0x01:0x00]));
break;
case 'buf':
for (var i = 0; i < data.length; i += 60) {
let arr = [(i == 0 ? epdCmd.EPD_CMD_BUF : epdCmd.EPD_CMD_BUF_CONT)];
arr.push(...data.slice(i, i + 60));
//console.log(arr);
await chr.writeValueWithResponse(Uint8Array.from(arr));
//info(`> buf at ${i} size ${arr.length}`)
}
break;
case 'lut':
let arr = [epdCmd.EPD_CMD_LUT];
arr.push(...data);
await chr.writeValueWithResponse(Uint8Array.from(arr));
break;
case 'rst':
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_RST]));
break;
case 'bw':
// write to bw ram
data = data || 0;
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_BW, data]));
break;
case 'red':
// write to bw ram
data = data || 0;
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_RED, data]));
break;
case 'fill':
// fill ram with black(0) or red(1)
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_FILL, data == 'red' ? 0x01:0x00]));
break;
case 'dp':
// show
let lut = 0;
switch (data) {
case 'gray8':
lut = 2;
break;
case 'user':
lut = 0xff;
break;
case 'full':
default:
lut = 0;
}
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_DP, lut]));
break;
case 'snv_read':
// SNV index, read length
console.log(`snv read ${data}`);
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_SNV_READ, ...data]));
break;
case 'snv_write':
// SNV index
console.log(`snv write ${data}`);
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_SNV_WRITE, data]));
break;
case 'buf_get':
// buffer index
console.log(`buf get ${data}`);
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_BUF_GET, data]));
break;
case 'buf_put':
// buffer index, data ...
console.log(`buf put ${data}`);
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_BUF_PUT, ...data]));
break;
case 'save_cfg':
await chr.writeValueWithResponse(Uint8Array.from([epdCmd.EPD_CMD_SAVE_CFG]));
break;
}
info (`> epdCmd.${cmd} done.`)
}
async function doCmdRead(snvId, size) {
var out = [];
// request SNV read
await doCmd('snv_read', [snvId, size]);
// pull data
for (var i=0; i<size; ) {
await doCmd('buf_get', i);
var data = new Uint8Array((await doCmd('read')).buffer);
if (data.byteLength == 0) {
break;
}
// first byte is the data index
i += data.byteLength - 1;
// add data to out, except the first byte.
out.push(...data.slice(1));
}
return out;
}
let ram_bw = [];
let ram_red = [];
function doImageGrey(type) {
const canvas = document.getElementById('canvas');
ram_bw = canvas2grey8(canvas, 'bw');
ram_red = canvas2grey8(canvas, 'red');
}
var step = 0;
async function doUploadImageGray8() {
await doCmd('clr');
await sleep(15*1000);
doImageGrey();
for (var i = 0; i < 8; i++) {
await doCmd('rst');
await sleep(2000);
await doUploadImageRam8('bw');
await doUploadImageRam8('red');
await doCmd('dp', 'gray8');
await sleep(8000);
step++;
}
step = 0;
info('> Upload done.')
}
async function doUploadImage(type) {
if (type == 'gray8') {
await doUploadImageGray8();
} else {
await doCmd('rst');
await sleep(2000);
await doUploadImageRam2('bw');
await doUploadImageRam2('red');
await doCmd('dp', 'full');
await sleep(15*1000);
}
}
// for screen larger than 296x128, should split to pages.
async function doCmdBuffers(type, arr) {
let step = 296*128/8;
let page = 0;
for (var i = 0; i < arr.length; i += step) {
let buffer = [];
buffer.push(...arr.slice(i, i + step));
await doCmd('buf', buffer);
await doCmd(type, page++);
}
}
async function doUploadImageRam2(type = 'bw') {
const canvas = document.getElementById('canvas');
var arr = canvas2bytes(canvas, type = type);
//await doCmd('buf', arr);
//await doCmd(type)
await doCmdBuffers(type, arr);
}
async function doUploadImageRam8(type = 'bw') {
var ram = type == 'bw' ? ram_bw : ram_red;
// grey byte to bit
var arr = [];
var buffer = [];
for (var x = 0; x < ram.length; x++) {
const n = ram[x] > step ? 1 : 0;
if (type == 'bw') {
buffer.push(n ? 0 : 1);
} else {
buffer.push(n ? 1 : 0);
}
if (buffer.length == 8) {
arr.push(parseInt(buffer.join(''), 2));
buffer = [];
}
}
info(`> write ram ${type} size ${arr.length}, step ${step}`);
console.log(arr);
//await doCmd('buf', arr);
//await doCmd(type)
await doCmdBuffers(type, arr);
}
function info(logTXT) {
var today = new Date();
var time = ("0" + today.getHours()).slice(-2) + ":" + ("0" + today.getMinutes()).slice(-2) + ":" + ("0" + today.getSeconds()).slice(-2) + " : ";
document.getElementById("log").innerHTML += time + logTXT + '<br>';
console.log(time + logTXT);
while ((document.getElementById("log").innerHTML.match(/<br>/g) || []).length > 10) {
var logs_br_position = document.getElementById("log").innerHTML.search("<br>");
document.getElementById("log").innerHTML = document.getElementById("log").innerHTML.substring(logs_br_position + 4);
}
}
async function load_image() {
const image_file = document.getElementById('image_file');
if (image_file.files.length > 0) {
const file = image_file.files[0];
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const image = new Image();
image.src = URL.createObjectURL(file);
image.onload = function (event) {
URL.revokeObjectURL(this.src);
ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height);
//convert_dithering()
}
}
}
function clear_canvas() {
if (confirm('确认清除屏幕?')) {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext("2d");
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}
function canvas2bytes(canvas, type = 'bw') {
const ctx = canvas.getContext("2d");
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const arr = [];
let buffer = [];
for (let y = 0; y < canvas.height; y += 8) {
for (let x = 0; x < canvas.width; x++) {
for (let a = 0; a < 8; a++) {
const i = (canvas.width * (y + a) + x) * 4;
if (type !== 'red') {
// 1 for white, 0 for black
// black : 0, 0, 0
buffer.push(imageData.data[i] === 0 && imageData.data[i + 1] === 0 && imageData.data[i + 2] === 0 ? 0 : 1);
} else {
// 1 for red, 0 for white
buffer.push(imageData.data[i] > 0 && imageData.data[i + 1] === 0 && imageData.data[i + 2] === 0 ? 1 : 0);
}
}
arr.push(parseInt(buffer.join(''), 2));
buffer = [];
}
}
return arr;
}
function canvas2grey8(canvas, type = 'bw') {
// each px = 4bit black + 4bit red.
const ctx = canvas.getContext("2d");
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const arr = [];
let buffer = [];
for (let y = 0; y < canvas.height; y += 8) {
for (let x = 0; x < canvas.width; x++) {
for (let a = 0; a < 8; a++) {
const i = (canvas.width * (y + a) + x) * 4;
const R = imageData.data[i];
const G = imageData.data[i + 1];
const B = imageData.data[i + 2];
let grey = 0; // white
if (R == 255 && G != 255 && B != 255) { // red
grey = (type == 'bw') ? 0 : (510 + 62 - G - B) >> 6;
} else { // gray
grey = (type == 'bw') ? (255 + 31 - R) >> 5 : 0;
}
arr.push(grey);
}
}
}
return arr;
}
async function doMyLut() {
const O = 0b00000000; // VSS
const B = 0b01000000; // VSH1 for Black
const W = 0b10000000; // VSL for white
const R = 0b11000000; // VSH2 for Red
const lut_gray8 = [
// RP A B C D SRAB SRCD
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // LUTC
0x01, R | 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, // LUTR
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // LUTW
0x01, B | 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, // LUTB
0x01, B | 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, // LUTB
];
await doCmd('lut', lut_gray8);
}
async function doFill(color) {
await doCmd('rst');
await sleep(2000);
await doCmd('fill', color);
await doCmd('dp', 'full');
await sleep(15*1000);
}
async function doSnvRead(type) {
var chr = await epdService.getCharacteristic(0xfffe);
if (type == 'cfg') {
await doCmd('snv_read', 0x01);
await doCmd('buf_get', 0x00);
var a = await chr.readValue();
console.log(a);
}
}
async function doSnvWrite() {
//var chr = await epdService.getCharacteristic(0xfffe);
await doCmd('buf_put', 0x00);
await doCmd('snv_write', 0x80);
}
async function doSnvCfg() {
var data = await doCmdRead(0x80, 32);
// data to hex string in '0x02x' format, should a zero in front of single digit.
var out = data.map(x => (x < 16 ? '0' : '') + x.toString(16)).join(' ');
console.log(out);
}
async function doLutWrite() {
var lutId = document.getElementById('lutId').value;
lutId = parseInt(lutId);
var lut = eval(document.getElementById('lut').value);
info(lutId);
info(lut);
await doCmd('buf_put', [0, ...lut]);
await doCmd('snv_write', 0x80+lutId);
}
async function doLutRead() {
var lutId = document.getElementById('lutId').value;
lutId = parseInt(lutId);
try {
var data = await doCmdRead(0x80+lutId, 35);
} catch (e) {
info(e);
document.getElementById('lut').value = '[]';
return;
}
console.log(data);
var out = '[\n';
// split data to every 7 bytes a group
for (var i = 0; i < data.length; i += 7) {
var d = data.slice(i, i + 7);
out += d.map(x => '0x' + x.toString(16)).join(', ');
out += ',\n';
}
out += ']';
document.getElementById('lut').value = out;
}
</script>
<div>
<label> Choose </label>
<button id="btnConnect" type="button" onclick="doConnect()">Connect</button>
</div>
<div id="etagFn" style="visibility:hidden;">
<button type="button" onclick="doCmd('mode', 'clock')">时钟模式</button>
<button id="btnReadEtag" type="button" onclick="doReadEtag()">ReadEtag</button>
<button id="btnSetTime" type="button" onclick="doSetTime()">SetTime</button>
<button id="btnRtcCollab" type="button" onclick="doRtcCollab()">RtcCollab</button>
<button id="btnTest" type="button" onclick="doTest()">Test</button>
<button type="button" onclick="doCmd('save_cfg')">保存设置</button>
</div>
<div>
<button type="button" onclick="doCmd('mode', 'image')">图片模式</button>
<button type="button" onclick="doCmd('rst')">rst</button>
<button type="button" onclick="doCmd('bw')">bw</button>
<button type="button" onclick="doCmd('red')">red</button>
<button type="button" onclick="doCmd('dp', 'full')">dp</button>
<button type="button" onclick="doMyLut()">LUT</button>
</div>
<div>
<button type="button" onclick="doCmd('clr')">清屏</button>
<button type="button" onclick="doFill('black')">全黑</button>
<button type="button" onclick="doFill('red')">全红</button>
</div>
<div id="canvas-box">
<input type="file" id="image_file" onchange="load_image()" accept=".png,.jpg,.bmp,.webp,.gif">
<br>
<canvas id="canvas" width="296" height="152" style="border: black solid 1px;"></canvas>
<br>
<button onclick="doUploadImage('full')">默认刷新</button>
<button onclick="doUploadImage('gray8')">8级灰度</button>
<select id="imgLutId">
<option value="1">LUT1 (FastRefresh)</option>
<option value="2">LUT2 (Grey 8 BWR)</option>
<option value="3">LUT3 (User)</option>
</select>
<button onclick="alert('TBD')">LUT刷新</button>
<br>
</div>
<div>
<textarea type="text" id="lut", rows="20", cols="80">
// Fast Refresh LUT(Lite) for SSD1680a BWR.
const VSS = 0b00<<6;
const VSH1= 0b01<<6;
const VSL = 0b10<<6;
const VSH2= 0b11<<6;
[
//RP A B C D SRAB SRCD
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // LUTC
0x1, VSL|0x2f, 0x0, VSH2|0x3f, 0x0, 0x2, 0xa, // LUTR
0x1, VSL|0x3f, 0x0, 0x0, 0x0, 0x2, 0x0, // LUTW
0x1, VSH1|0x2f, 0x0, 0x0, 0x0, 0x1, 0x0, // LUTB
//FR 2: 50hz, 3: 75Hz, 4: 100Hz, 5: 125Hz
0x04,
//EOPT VGH VSH1 VSH2 VSL VCOM
// -20v 15v 3v -15v
0x22, 0x17, 0x41, 0x94, 0x32, 0x36
];
</textarea>
<br>
<select id="lutId">
<option value="1">LUT1 (FastRefresh)</option>
<option value="2">LUT2 (Grey 8 BWR)</option>
<option value="3">LUT3 (User)</option>
</select>
<button type="button" onclick="doLutWrite()">写入</button>
<button type="button" onclick="doLutRead()">读出</button>
</div>
<div id="log">
CC2640R2-ETAG Webtool. <br>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB