ble.c 6.87 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
20
#define WSF_BUF_POOLS 6
#define WSF_BUF_SIZE 0x1048
21

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

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

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

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

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

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

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

schneider's avatar
schneider committed
70
	return FALSE;
71
}
72
/*************************************************************************************************/
73
74
static void WsfInit(void)
{
75
	uint32_t bytesUsed __attribute__((unused));
schneider's avatar
schneider committed
76
77
78
79
80
81
82
83
84
	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);
85
86
87

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

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

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

schneider's avatar
schneider committed
114
115
116
117
118
119
120
121
122
	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;
	}
123
		
124
125
126
127
128
129
130
131
132
133
	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
134
	HciVsSetBdAddr(bdAddr);
135
}
schneider's avatar
schneider committed
136
/*************************************************************************************************/
137
static void vTimerCallback(xTimerHandle pxTimer)
138
{
schneider's avatar
schneider committed
139
140
141
142
143
144
	//printf("wake\n");
	int tick = xTaskGetTickCount();
	//printf("WsfTimerUpdate(%d)\n", tick - lasttick);
	WsfTimerUpdate(tick - lasttick);
	lasttick = tick;
	//printf("done\n");
145
}
schneider's avatar
schneider committed
146
/*************************************************************************************************/
147
148
149
static void notify(void)
{
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
schneider's avatar
schneider committed
150
151
152
153
154
155
	if (xPortIsInsideInterrupt()) {
		vTaskNotifyGiveFromISR(ble_task_id, &xHigherPriorityTaskWoken);
		portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
	} else {
		xTaskNotifyGive(ble_task_id);
	}
156
}
schneider's avatar
schneider committed
157
/*************************************************************************************************/
158
159
void WsfTimerNotify(void)
{
schneider's avatar
schneider committed
160
161
162
163
	//printf("WsfTimerNotify\n");
	// TODO: Can we do this without waking up the task?
	// xTimerChangePeriodFromISR exists
	notify();
164
}
schneider's avatar
schneider committed
165
/*************************************************************************************************/
166
167
void wsf_ble_signal_event(void)
{
schneider's avatar
schneider committed
168
169
	//printf("wsf_ble_signal_event\n");
	notify();
170
}
schneider's avatar
schneider committed
171
/*************************************************************************************************/
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
#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;
	}
}
/*************************************************************************************************/
203
static void scheduleTimer(void)
204
{
schneider's avatar
schneider committed
205
206
207
208
209
210
211
212
213
	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");
214
215
216
217
218
219
220
		/* 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
221
222
223
224
225
226
227
228
		if (timerWakeup != NULL) {
			xTimerChangePeriod(
				timerWakeup,
				pdMS_TO_TICKS(time_to_next_expire),
				0
			);
			//printf("insert done\n");
		} else {
229
			LOG_ERR("ble", "Could not create timer");
schneider's avatar
schneider committed
230
231
		}
	} else {
232
		APP_TRACE_INFO0("No timer running");
schneider's avatar
schneider committed
233
	}
234
}
schneider's avatar
schneider committed
235
236
/*************************************************************************************************/
void vBleTask(void *pvParameters)
237
{
238
	ble_task_id = xTaskGetCurrentTaskHandle();
Rahix's avatar
Rahix committed
239
240
241
242
243
244

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

schneider's avatar
schneider committed
245
246
	WsfInit();
	StackInit();
247
	BbBleDrvSetTxPower(0);
schneider's avatar
schneider committed
248
249
250
251
252
253
254
255
256
257
	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
258
	bleFileTransfer_init();
259
	bleCard10_init();
schneider's avatar
schneider committed
260
261
262
263
264
265
266
267
268
269
270
271

	lasttick = xTaskGetTickCount();

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

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