ble.c 6.95 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
#include "att_api.h"
11
#include "trng.h"
12

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

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

schneider's avatar
schneider committed
20
21
#define WSF_BUF_POOLS 6
#define WSF_BUF_SIZE 0x1048
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
34
35
36
37
38
static wsfBufPoolDesc_t mainPoolDesc[WSF_BUF_POOLS] =
{
  {  16,  8 },
  {  32,  4 },
  {  64,  4 },
  { 128,  4 },
  { 256,  4 },
39
  { 512,  4 }
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
{
schneider's avatar
schneider committed
94
95
96
	uint8_t bdAddr[6] = { 0x02, 0x02, 0x44, 0x8B, 0x05, 0x00 };
	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
102
103
104
105
106
107
108
109
110
111
112
		bdAddr[0] = 0xCA;
		bdAddr[1] = 0x4D;
		bdAddr[2] = 0x10;
		TRNG_Read(MXC_TRNG, bdAddr + 3, 3);
		sprintf(buf,
			"%02x:%02x:%02x:%02x:%02x:%02x\n",
			bdAddr[0],
			bdAddr[1],
			bdAddr[2],
			bdAddr[3],
			bdAddr[4],
			bdAddr[5]);
113
114
115
116
117
		fs_write_file("mac.txt", buf, strlen(buf));
	} else {
		APP_TRACE_INFO1("mac file contents: %s", buf);
	}

schneider's avatar
schneider committed
118
119
120
121
122
123
124
125
126
127
	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;
	}

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

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

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

	lasttick = xTaskGetTickCount();

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

	while (1) {
276
		ulTaskNotifyTake(pdTRUE, portTICK_PERIOD_MS * 1000);
schneider's avatar
schneider committed
277
278
279
		wsfOsDispatcher();
		scheduleTimer();
	}
280
}