ble.c 7.5 KB
Newer Older
1
#include "epicardium.h"
2 3
#include "modules/log.h"

4
#include "fs/fs_util.h"
5 6 7
#include "wsf_types.h"
#include "wsf_buf.h"
#include "wsf_trace.h"
schneider's avatar
schneider committed
8
#include "ble_api.h"
9
#include "hci_vs.h"
10 11
#include "att_api.h"

12 13 14
#include "FreeRTOS.h"
#include "timers.h"

15 16
#include <stdio.h>
#include <string.h>
17 18
#include <stdbool.h>

19
#define FACTOR 2
schneider's avatar
schneider committed
20
#define WSF_BUF_POOLS 6
21
#define WSF_BUF_SIZE (0x1048 * FACTOR)
22

schneider's avatar
schneider committed
23 24
uint32_t SystemHeapSize = WSF_BUF_SIZE;
uint32_t SystemHeap[WSF_BUF_SIZE / 4];
25
uint32_t SystemHeapStart;
26

27 28 29
/* Task ID for the ble handler */
static TaskHandle_t ble_task_id = NULL;

30
/*! Default pool descriptor. */
schneider's avatar
schneider committed
31
/* clang-format off */
32 33
static wsfBufPoolDesc_t mainPoolDesc[WSF_BUF_POOLS] =
{
34 35 36 37 38 39
  {  16,  8*FACTOR },
  {  32,  4*FACTOR },
  {  64,  4*FACTOR },
  { 128,  4*FACTOR },
  { 256,  4*FACTOR },
  { 512,  4*FACTOR }
40
};
schneider's avatar
schneider committed
41 42 43 44 45
/* clang-format on */

static StaticTimer_t x;
static TimerHandle_t timerWakeup = NULL;
static int lasttick              = 0;
46

47
/*! \brief  Stack initialization for app. */
48 49
extern void StackInit(void);
extern void AppInit(void);
schneider's avatar
schneider committed
50
extern void bleuart_init(void);
51
extern void bleFileTransfer_init(void);
52
extern void bleCard10_init(void);
53
extern void BbBleDrvSetTxPower(int8_t power);
54

55 56
/*************************************************************************************************/
void PalSysAssertTrap(void)
57
{
schneider's avatar
schneider committed
58 59
	while (1) {
	}
60
}
61 62
/*************************************************************************************************/
static bool_t myTrace(const uint8_t *pBuf, uint32_t len)
63
{
schneider's avatar
schneider committed
64
	extern uint8_t wsfCsNesting;
65

schneider's avatar
schneider committed
66 67 68 69
	if (wsfCsNesting == 0) {
		fwrite(pBuf, len, 1, stdout);
		return TRUE;
	}
70

schneider's avatar
schneider committed
71
	return FALSE;
72
}
73
/*************************************************************************************************/
74 75
static void WsfInit(void)
{
76
	uint32_t bytesUsed __attribute__((unused));
schneider's avatar
schneider committed
77 78 79 80 81 82 83 84 85
	WsfTimerInit();

	SystemHeapStart = (uint32_t)&SystemHeap;
	memset(SystemHeap, 0, sizeof(SystemHeap));
	//printf("SystemHeapStart = 0x%x\n", SystemHeapStart);
	//printf("SystemHeapSize = 0x%x\n", SystemHeapSize);

	WsfTraceRegisterHandler(myTrace);
	WsfTraceEnable(TRUE);
86 87 88

	bytesUsed = WsfBufInit(WSF_BUF_POOLS, mainPoolDesc);
	APP_TRACE_INFO1("bytesUsed = %u", (unsigned int)bytesUsed);
89
}
schneider's avatar
schneider committed
90
/*************************************************************************************************/
91
/* TODO: We need a source of MACs */
92
static void setAddress(void)
93
{
94
	uint8_t bdAddr[6] = { 0xCA, 0x4D, 0x10, 0x00, 0x00, 0x00 };
schneider's avatar
schneider committed
95 96
	char buf[32];

97 98
	int result = fs_read_text_file("mac.txt", buf, sizeof(buf));

99
	if (result < 0) {
100
		APP_TRACE_INFO0("mac.txt not found, generating random MAC");
101
		epic_trng_read(bdAddr + 3, 3);
102 103 104 105 106 107 108 109
		sprintf(buf,
			"%02x:%02x:%02x:%02x:%02x:%02x\n",
			bdAddr[0],
			bdAddr[1],
			bdAddr[2],
			bdAddr[3],
			bdAddr[4],
			bdAddr[5]);
110 111 112 113 114
		fs_write_file("mac.txt", buf, strlen(buf));
	} else {
		APP_TRACE_INFO1("mac file contents: %s", buf);
	}

schneider's avatar
schneider committed
115 116 117 118 119 120 121 122 123
	int a, b, c, d, e, f;
	if (sscanf(buf, "%x:%x:%x:%x:%x:%x", &a, &b, &c, &d, &e, &f) == 6) {
		bdAddr[0] = f;
		bdAddr[1] = e;
		bdAddr[2] = d;
		bdAddr[3] = c;
		bdAddr[4] = b;
		bdAddr[5] = a;
	}
124

125 126 127 128 129 130 131 132 133 134
	LOG_INFO(
		"ble",
		"Setting MAC address to %02X:%02X:%02X:%02X:%02X:%02X",
		bdAddr[5],
		bdAddr[4],
		bdAddr[3],
		bdAddr[2],
		bdAddr[1],
		bdAddr[0]
	);
schneider's avatar
schneider committed
135
	HciVsSetBdAddr(bdAddr);
136
}
schneider's avatar
schneider committed
137
/*************************************************************************************************/
138
static void vTimerCallback(xTimerHandle pxTimer)
139
{
schneider's avatar
schneider committed
140 141 142 143 144 145
	//printf("wake\n");
	int tick = xTaskGetTickCount();
	//printf("WsfTimerUpdate(%d)\n", tick - lasttick);
	WsfTimerUpdate(tick - lasttick);
	lasttick = tick;
	//printf("done\n");
146
}
schneider's avatar
schneider committed
147
/*************************************************************************************************/
148 149 150
static void notify(void)
{
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
schneider's avatar
schneider committed
151 152 153 154 155 156
	if (xPortIsInsideInterrupt()) {
		vTaskNotifyGiveFromISR(ble_task_id, &xHigherPriorityTaskWoken);
		portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
	} else {
		xTaskNotifyGive(ble_task_id);
	}
157
}
schneider's avatar
schneider committed
158
/*************************************************************************************************/
159 160
void WsfTimerNotify(void)
{
schneider's avatar
schneider committed
161 162 163
	//printf("WsfTimerNotify\n");
	// TODO: Can we do this without waking up the task?
	// xTimerChangePeriodFromISR exists
164
	NVIC->STIR = RSV11_IRQn;
165
}
schneider's avatar
schneider committed
166
/*************************************************************************************************/
167 168
void wsf_ble_signal_event(void)
{
schneider's avatar
schneider committed
169
	//printf("wsf_ble_signal_event\n");
170 171 172 173 174
	NVIC->STIR = RSV11_IRQn;
}
/*************************************************************************************************/
void RSV11_IRQHandler(void)
{
schneider's avatar
schneider committed
175
	notify();
176
}
schneider's avatar
schneider committed
177
/*************************************************************************************************/
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
#define BLEMAXCFGBYTES 100
bool ble_shall_start(void)
{
	int bleConfigFile = epic_file_open("ble.txt", "r");
	if (bleConfigFile < 0) {
		LOG_INFO("ble", "can not open ble.txt -> BLE is not started");
		epic_file_close(bleConfigFile);
		return false;
	}

	char cfgBuf[BLEMAXCFGBYTES + 1];
	int readNum = epic_file_read(bleConfigFile, cfgBuf, BLEMAXCFGBYTES);
	epic_file_close(bleConfigFile);
	if (readNum < 0) {
		LOG_WARN("ble", "can not read ble.txt -> BLE is not started");
		return false;
	}
	cfgBuf[readNum] = '\0';

	char bleActiveStr[]              = "active=true";
	cfgBuf[sizeof(bleActiveStr) - 1] = '\0';

	if (strcmp(cfgBuf, "active=true") != 0) {
		LOG_INFO("ble", "BLE is disabled.");
		return false;
	} else {
		LOG_INFO("ble", "BLE is enabled.");
		return true;
	}
}
/*************************************************************************************************/
209
static void scheduleTimer(void)
210
{
schneider's avatar
schneider committed
211 212 213 214 215 216 217 218 219
	bool_t timerRunning;
	wsfTimerTicks_t time_to_next_expire;

	vTimerCallback(NULL);
	time_to_next_expire = WsfTimerNextExpiration(&timerRunning);

	if (timerRunning) {
		//printf("time_to_next_expire = %d\n", time_to_next_expire);
		//printf("change period\n");
220 221 222 223 224 225 226
		/* We need to make sure not to schedule a 0 ticks timer.
		 * Maybe it would also be enough to simply call the dispatcher
		 * in this case... */
		if (time_to_next_expire == 0) {
			time_to_next_expire = 1;
		}

schneider's avatar
schneider committed
227 228 229 230 231 232 233 234
		if (timerWakeup != NULL) {
			xTimerChangePeriod(
				timerWakeup,
				pdMS_TO_TICKS(time_to_next_expire),
				0
			);
			//printf("insert done\n");
		} else {
235
			LOG_ERR("ble", "Could not create timer");
schneider's avatar
schneider committed
236 237
		}
	} else {
238
		APP_TRACE_INFO0("No timer running");
schneider's avatar
schneider committed
239
	}
240
}
schneider's avatar
schneider committed
241 242
/*************************************************************************************************/
void vBleTask(void *pvParameters)
243
{
244
	ble_task_id = xTaskGetCurrentTaskHandle();
245 246 247 248 249 250

	/*
	 * Delay BLE startup by a bit because it locks up Epicardium otherwise.
	 */
	vTaskDelay(pdMS_TO_TICKS(500));

251 252 253 254 255 256
	/* We are going to execute FreeRTOS functions from callbacks
	 * coming from this interrupt. Its priority needs to be
	 * reduced to allow this. */
	NVIC_SetPriority(RSV11_IRQn, 2);
	NVIC_EnableIRQ(RSV11_IRQn);

schneider's avatar
schneider committed
257
	WsfInit();
258 259 260 261
	taskENTER_CRITICAL();
	/* Critical section to prevent a loop in iq_capture2 / meas_freq in
	 * /home/maxim/Documents/src/BLE/mcbusw/Hardware/Micro/ME14/Firmware/trunk/NDALibraries/BTLE/phy/dbb/prot/ble/pan2g5/afe/max32665/board_config.c:275
	 * if BHI160 and -Ddebug_prints=true is enabled*/
schneider's avatar
schneider committed
262
	StackInit();
263
	taskEXIT_CRITICAL();
264
	BbBleDrvSetTxPower(0);
schneider's avatar
schneider committed
265 266 267 268 269 270 271
	setAddress();

	AppInit();
	BleStart();
	AttsDynInit();

	bleuart_init();
272
	bleFileTransfer_init();
273
	bleCard10_init();
schneider's avatar
schneider committed
274 275 276 277 278 279 280 281 282 283 284 285

	lasttick = xTaskGetTickCount();

	timerWakeup = xTimerCreateStatic(
		"timerWakeup",    /* name */
		pdMS_TO_TICKS(1), /* period/time */
		pdFALSE,          /* auto reload */
		NULL,             /* timer ID */
		vTimerCallback,
		&x); /* callback */

	while (1) {
286
		ulTaskNotifyTake(pdTRUE, portTICK_PERIOD_MS * 1000);
schneider's avatar
schneider committed
287 288 289
		wsfOsDispatcher();
		scheduleTimer();
	}
290
}