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

#include "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>

schneider's avatar
schneider committed
19
#define FACTOR  2
schneider's avatar
schneider committed
20
#define WSF_BUF_POOLS 6
schneider's avatar
schneider committed
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] =
{
schneider's avatar
schneider committed
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);
Hauke Mehrtens's avatar
Hauke Mehrtens committed
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 99 100
	int result = fs_read_text_file("mac.txt", buf, sizeof(buf));

	if (result == -1) {
		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 164
	//printf("WsfTimerNotify\n");
	// TODO: Can we do this without waking up the task?
	// xTimerChangePeriodFromISR exists
	notify();
165
}
schneider's avatar
schneider committed
166
/*************************************************************************************************/
167 168
void wsf_ble_signal_event(void)
{
schneider's avatar
schneider committed
169 170
	//printf("wsf_ble_signal_event\n");
	notify();
171
}
schneider's avatar
schneider committed
172
/*************************************************************************************************/
173 174 175 176 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
#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;
	}
}
/*************************************************************************************************/
204
static void scheduleTimer(void)
205
{
schneider's avatar
schneider committed
206 207 208 209 210 211 212 213 214
	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");
215 216 217 218 219 220 221
		/* 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
222 223 224 225 226 227 228 229
		if (timerWakeup != NULL) {
			xTimerChangePeriod(
				timerWakeup,
				pdMS_TO_TICKS(time_to_next_expire),
				0
			);
			//printf("insert done\n");
		} else {
230
			LOG_ERR("ble", "Could not create timer");
schneider's avatar
schneider committed
231 232
		}
	} else {
233
		APP_TRACE_INFO0("No timer running");
schneider's avatar
schneider committed
234
	}
235
}
schneider's avatar
schneider committed
236 237
/*************************************************************************************************/
void vBleTask(void *pvParameters)
238
{
239
	ble_task_id = xTaskGetCurrentTaskHandle();
Rahix's avatar
Rahix committed
240 241 242 243 244 245

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

schneider's avatar
schneider committed
246 247
	WsfInit();
	StackInit();
248
	BbBleDrvSetTxPower(0);
schneider's avatar
schneider committed
249 250 251 252 253 254 255 256 257 258
	setAddress();

	NVIC_SetPriority(BTLE_SFD_TO_IRQn, 2);
	NVIC_SetPriority(BTLE_TX_DONE_IRQn, 2);
	NVIC_SetPriority(BTLE_RX_RCVD_IRQn, 2);
	AppInit();
	BleStart();
	AttsDynInit();

	bleuart_init();
Hauke Mehrtens's avatar
Hauke Mehrtens committed
259
	bleFileTransfer_init();
260
	bleCard10_init();
schneider's avatar
schneider committed
261 262 263 264 265 266 267 268 269 270 271 272

	lasttick = xTaskGetTickCount();

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

	while (1) {
273
		ulTaskNotifyTake(pdTRUE, portTICK_PERIOD_MS * 1000);
schneider's avatar
schneider committed
274 275 276
		wsfOsDispatcher();
		scheduleTimer();
	}
277
}