-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtx_updater.c
130 lines (96 loc) · 2.7 KB
/
tx_updater.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Update the firmware over Radio.
*/
#include "kl17.h"
#include "palawan.h"
#include "radio.h"
#include "murmur3.h"
#define REQUEST_FIRMWARE_DATA 64
int dhcpRequestAddress(int timeout_ms);
__attribute__((aligned(4)))
static uint8_t one_page[1024];
#define MURMUR_REQUEST 0x5592493f
#define MURMUR_RESPONSE 0x239b23a9
#define MURMUR_SEED 0xb62a238c
struct firmware_request {
uint32_t type;
uint32_t offset;
uint32_t length;
uint32_t bytes_per_packet;
} __attribute__((packed));
struct firmware_murmur_response {
uint32_t type;
uint32_t payload_size;
uint32_t offset;
uint8_t payload[32];
uint32_t murmur_sum;
} __attribute__((packed));
static const uint32_t app_flash_start = 0x00002800;
static const uint32_t app_flash_end = 0x00002800 + (1024 * 118);
static struct firmware_murmur_response response;
static int response_valid;
static void prot_get_firmware(uint8_t port,
uint8_t src,
uint8_t dst,
uint8_t length,
const void *data) {
const struct firmware_murmur_response *r = data;
uint32_t chk;
if (r->type != MURMUR_RESPONSE)
goto invalid_response;
if (length != sizeof(*r))
goto invalid_response;
MurmurHash3_x86_32(data, sizeof(*r) - 4, MURMUR_SEED, &chk);
if (chk != r->murmur_sum)
goto invalid_response;
int i;
for (i = 0; i < length; i++)
((uint8_t *)&response)[i] = ((uint8_t *)data)[i];
response_valid = 1;
return;
invalid_response:
return;
}
static int get_one_page(KRadioDevice *radio, uint8_t data[1024], int pagenum) {
struct firmware_request request = {
.type = MURMUR_REQUEST,
.offset = (pagenum * 1024),
.length = 1024,
.bytes_per_packet = 32,
};
/* Send a request for the data, and wait for it to come back */
radioSend(radio, 0, REQUEST_FIRMWARE_DATA, sizeof(request), &request);
/*
while (i < 1024) {
uint32_t addr = (pagenum * 1024) + i;
}
*/
return 0;
}
static void configure_pins(void)
{
/* LED */
PORTB->PCR[1] = (1 << 8) | (1 << 2);
FGPIOB->PDDR |= (1 << 1);
FGPIOB->PCOR = (1 << 1);
/* DIO0 */
PORTA->PCR[8] = (1 << 8) | (1 << 2);
FGPIOA->PDDR &= ~(1 << 8);
/* DIO1 */
PORTB->PCR[2] = (1 << 8) | (1 << 2);
FGPIOB->PDDR &= ~(1 << 2);
}
int updateTx(void) {
int pagenum;
configure_pins();
radioStart(radioDevice);
radioDumpFifo();
radioDumpData(1, 2);
while (dhcpRequestAddress(10) < 0)
;
radioSetHandler(radioDevice, REQUEST_FIRMWARE_DATA, prot_get_firmware);
for (pagenum = (app_flash_start / 1024); pagenum < (app_flash_end / 1024); pagenum++) {
get_one_page(radioDevice, one_page, pagenum);
}
return 0;
}