EVE 1.0
platform.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <core/clk.h>
4 #include <lib/assert.h>
5 #include <nrf_soc.h>
6 #include <nrf_nvic.h>
7 #include <app_error.h>
8 #include <ble.h>
9 #include <debug-uart.h>
10 #include <core/work.h>
11 #include <ble/ble.h>
12 #include <toc/toc-app.h>
13 #include "platform.h"
14 
15 /* Disable debug spam from the module */
16 #ifndef NDEBUG
17  #define NDEBUG
18 #endif
19 
20 /** The macro provides debug print functionality */
21 #ifdef NDEBUG
22  #define PRINTD(FORMAT, args...) do {} while (0)
23 #else
24  #define PRINTD(FORMAT, args...) printf(FORMAT, ##args)
25 #endif
26 
27 extern uint32_t __data_start__;
28 
29 // TODO: HACK!!!
30 extern void eve_dm_init(void);
31 
32 // TODO: HACK!!!
33 extern bool EveBleServiceEnabled;
34 
35 static void BleWorkCb(struct work_t *Work);
36 
37 static struct work_t BleWork;
38 
39 static bool SoftdeviceEnabled;
40 
41 void SOFTDEVICE_EVT_IRQHandler(void) __attribute__ ((section(".text"),interrupt));
42 
43 #define SOFTDEVICE_EVT_IRQ SWI2_EGU2_IRQn
44 #define SOFTDEVICE_EVT_IRQHandler SWI2_EGU2_IRQHandler
45 
46 static void softdevice_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
47 {
48  __disable_irq();
49  dbg_panic();
50  printf("Softdevice fault handler: error %d @ 0x%.8X (info: %d)\n",
51  (unsigned) id, (unsigned) pc, (unsigned) info);
52  dbg_drain();
53 
54  register uint32_t r_id __ASM("r0") = id;
55  register uint32_t r_pc __ASM("r1") = pc;
56  register uint32_t r_info __ASM("r2") = info;
57  __ASM volatile ("BKPT #0x00" : : "r" (r_id), "r" (r_pc), "r" (r_info));
58  while(1);
59 }
60 
61 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name)
62 {
63  __disable_irq();
64  dbg_panic();
65  printf("Software error handler: error 0x%.8X in %s:%d\n",
66  (unsigned) error_code, (const char *) p_file_name, (unsigned) line_num);
67  dbg_drain();
68 
69  register uint32_t r_error_code __ASM("r0") = error_code;
70  register uint32_t r_line_num __ASM("r1") = line_num;
71  register const char *r_p_file_name __ASM("r2") = (const void *) p_file_name;
72  __ASM volatile ("BKPT #0x00" : : "r" (r_error_code), "r" (r_line_num), "r" (r_p_file_name));
73  while(1);
74 }
75 
76 void app_error_handler_bare(uint32_t error_code)
77 {
78  __disable_irq();
79  dbg_panic();
80  printf("Software error handler: error 0x%.8X\n", (unsigned) error_code);
81  dbg_drain();
82 
83  register uint32_t r_error_code __ASM("r0") = error_code;
84  __ASM volatile ("BKPT #0x00" : : "r" (r_error_code));
85  while(1);
86 }
87 
88 uint32_t EvePlatformInitEx(const ble_enable_params_t *BleEnableParams, const nrf_clock_lf_cfg_t *ClockConfig)
89 {
90  uint32_t app_ram_base = (uint32_t) &__data_start__;
91  uint32_t err_code;
92  clk_init();
93 
94  BleWork = WORK_INIT_TYPED(BleWork, BleWorkCb);
95 
96  eve_dm_init();
97 
98  err_code = sd_softdevice_enable(ClockConfig, softdevice_fault_handler);
99  if (err_code != 0)
100  {
101  printf("%s: Cannot enable softdevice: error %d\n", __func__, (unsigned) err_code);
102  return err_code;
103  }
104 
105  SoftdeviceEnabled = true;
106 
107  err_code = sd_nvic_EnableIRQ(SOFTDEVICE_EVT_IRQ);
108  APP_ERROR_CHECK(err_code);
109 
110  if (BleEnableParams)
111  {
112  ble_enable_params_t ble_enable_params = *BleEnableParams;
113  err_code = sd_ble_enable(&ble_enable_params, &app_ram_base);
114  if (err_code != 0)
115  {
116  if (err_code == NRF_ERROR_NO_MEM)
117  {
118  printf("%s: Not enough memory for BLE: %d bytes extra required\n", __func__,
119  (unsigned) (app_ram_base - (uint32_t) &__data_start__));
120  }
121  else
122  {
123  printf("%s: Cannot enable BLE: error %d\n", __func__, (unsigned) err_code);
124  }
125  return err_code;
126  }
127 
128  APP_ERROR_CHECK_BOOL(app_ram_base <= (uint32_t) &__data_start__);
129  if (app_ram_base != (uint32_t) &__data_start__)
130  printf("%s: %d bytes can be added to RAM segment.\n", __func__,
131  (unsigned) ((uint32_t) &__data_start__ - app_ram_base));
132  }
133  return 0;
134 }
135 
136 bool softdevice_handler_is_enabled(void)
137 {
138  return SoftdeviceEnabled;
139 }
140 
141 static uint32_t ble_event_buffer[(sizeof(ble_evt_t) + (GATT_MTU_SIZE_DEFAULT) + 3) / sizeof(uint32_t)];
142 
143 void NoApplicHandleSysEvent(uint32_t Event)
144 {}
145 void ApplicHandleSysEvent(uint32_t Event) __attribute__((weak,alias("NoApplicHandleSysEvent")));
146 
147 void NoApplicHandleBleEvent(const ble_evt_t *Event)
148 {}
149 void ApplicHandleBleEvent(const ble_evt_t *Event) __attribute__((weak,alias("NoApplicHandleBleEvent")));
150 
151 void NoTocAppGetToc(struct toc_blob_t *Ptr)
152 {
153  memset(Ptr, 0, sizeof(struct toc_blob_t));
154 }
155 void TocAppGetToc(struct toc_blob_t *Ptr) __attribute__((weak,alias("NoTocAppGetToc")));
156 
157 const struct toc_segment_descriptor_t TocSegmentTable[1] __attribute__((weak));
158 
159 int NoTocVarCb(int Id, int Index)
160 {
161  return 0;
162 }
163 int TocVarPreGet(int Id, int Index) __attribute__((weak,alias("NoTocVarCb")));
164 int TocVarPostGet(int Id, int Index) __attribute__((weak,alias("NoTocVarCb")));
165 int TocVarPreSet(int Id, int Index) __attribute__((weak,alias("NoTocVarCb")));
166 int TocVarPostSet(int Id, int Index) __attribute__((weak,alias("NoTocVarCb")));
167 
168 void SOFTDEVICE_EVT_IRQHandler(void)
169 {
170  work_schedule(&BleWork);
171 }
172 
173 static void BleWorkCb(struct work_t *Work)
174 {
175  uint32_t err_code;
176 
177  for (;;)
178  {
179  uint32_t evt_id;
180  err_code = sd_evt_get(&evt_id);
181  if (err_code == NRF_ERROR_NOT_FOUND) {
182  break;
183  } else if (err_code != NRF_SUCCESS) {
184  APP_ERROR_CHECK(err_code);
185  } else {
186  PRINTD(">>> SYS: 0x%.8X\n", (unsigned) evt_id);
187  if (EveBleServiceEnabled) {
188  eve_dm_sys_event_handler(evt_id);
189  }
190  ApplicHandleSysEvent(evt_id);
191  }
192  }
193 
194  for (;;)
195  {
196  uint16_t evt_len = sizeof(ble_event_buffer);
197  err_code = sd_ble_evt_get((void *) ble_event_buffer, &evt_len);
198  if (err_code == NRF_ERROR_NOT_FOUND || err_code == BLE_ERROR_NOT_ENABLED) {
199  break;
200  } else if (err_code != NRF_SUCCESS) {
201  APP_ERROR_CHECK(err_code);
202  } else {
203  const ble_evt_t *evt = (void *) ble_event_buffer;
204  PRINTD(">>> BLE: 0x%.2X (%d bytes)\n",
205  (unsigned) evt->header.evt_id,
206  (unsigned) evt->header.evt_len);
207  if (EveBleServiceEnabled) {
208  eve_connection_on_ble_evt(evt);
209  eve_svc_on_ble_evt(evt);
210  eve_disc_on_ble_evt(evt);
211  }
212  ApplicHandleBleEvent(evt);
213  }
214  }
215 }
Header file for BLE subsystem interface.
#define PRINTD(FORMAT, args...)
Definition: uip.c:100
void work_schedule(struct work_t *work)
void clk_init(void)
__attribute__((always_inline)) static inline void swint_enable_indirect_adapter(swint_state_t *state)
Definition: work.h:245
void TocAppGetToc(struct toc_blob_t *Ptr) __attribute__((weak
Gir "table of content" (TOC).
Header file for the EVE work scheduling.
Header file for the EVE clock management framework.
TOC application API.
Definition: work.h:140
#define WORK_INIT_TYPED(work, callback)
Definition: work.h:76