libnile
Loading...
Searching...
No Matches
mcu.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023, 2024, 2025 Adrian "asie" Siekierka
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 *
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 *
20 * 3. This notice may not be removed or altered from any source distribution.
21 */
22
23#ifndef NILE_MCU_H_
24#define NILE_MCU_H_
25
26#include <wonderful.h>
27#include "hardware.h"
28
29#define NILE_MCU_BOOT_ACK 0x79
30#define NILE_MCU_BOOT_NACK 0x1F
31#define NILE_MCU_BOOT_START 0x5A
32#define NILE_MCU_BOOT_GET 0x00
33#define NILE_MCU_BOOT_GET_VERSION 0x01
34#define NILE_MCU_BOOT_GET_ID 0x02
35#define NILE_MCU_BOOT_READ_MEMORY 0x11
36#define NILE_MCU_BOOT_JUMP 0x21
37#define NILE_MCU_BOOT_WRITE_MEMORY 0x31
38#define NILE_MCU_BOOT_ERASE_MEMORY 0x44
39#define NILE_MCU_BOOT_SPECIAL 0x50
40#define NILE_MCU_BOOT_EXT_SPECIAL 0x51
41#define NILE_MCU_BOOT_WRITE_LOCK 0x63
42#define NILE_MCU_BOOT_WRITE_UNLOCK 0x73
43#define NILE_MCU_BOOT_READ_LOCK 0x82
44#define NILE_MCU_BOOT_READ_UNLOCK 0x92
45#define NILE_MCU_BOOT_GET_CRC 0xA1
46
47#define NILE_MCU_BOOT_ERASE_ALL_SECTORS 0xFFFF
48
49#define NILE_MCU_BOOT_FLAG_SIZE 0x01
50#define NILE_MCU_BOOT_FLAG_CHECKSUM 0x02
51
52#define NILE_MCU_FLASH_START 0x08000000
53#define NILE_MCU_FLASH_PAGE_SIZE 2048
54
55#define NILE_MCU_NATIVE_CMD(cmd, arg) (((cmd) & 0x7F) | ((arg) << 7))
56
57#ifndef __ASSEMBLER__
58#include <stdbool.h>
59#include <stddef.h>
60#include <stdint.h>
61
69bool nile_mcu_reset(bool to_bootloader);
70
72bool nile_mcu_boot_send_cmd(uint8_t cmd);
73bool nile_mcu_boot_send_data(const void __far *buffer, uint16_t len, uint8_t flags);
74uint16_t nile_mcu_boot_recv_data(void __far* buffer, uint16_t buflen, uint8_t flags);
75
81
86uint16_t nile_mcu_boot_get_id(void);
87
95bool nile_mcu_boot_read_memory(uint32_t address, void __far* buffer, uint16_t buflen);
96
102bool nile_mcu_boot_jump(uint32_t address);
103
111bool nile_mcu_boot_write_memory(uint32_t address, const void __far* buffer, uint16_t buflen);
112
120bool nile_mcu_boot_erase_memory(uint16_t sector_address, uint16_t sector_count);
121
128
132#define NILE_MCU_NATIVE_ERROR_SPI -1
133
137#define NILE_MCU_NATIVE_ERROR_MCU -2
138
148static inline int16_t nile_mcu_native_send_cmd(uint16_t cmd, const void __far* buffer, int buflen) {
149 int16_t __nile_mcu_native_send_cmd_async(uint16_t cmd, int buflen, const void __far* buffer);
150 return __nile_mcu_native_send_cmd_async(cmd, buflen, buffer);
151}
152// int16_t nile_mcu_native_send_cmd(uint16_t cmd, const void __wf_cram* buffer, int buflen);
153
163int16_t nile_mcu_native_recv_cmd(void __far* buffer, uint16_t buflen);
164
171int16_t nile_mcu_native_recv_cmd_start(uint16_t resplen);
172
180int16_t nile_mcu_native_recv_cmd_finish(void __far* buffer, uint16_t buflen);
181
182static inline int16_t nile_mcu_native_recv_cmd_response_uint8(void) {
183 int16_t result; uint8_t bytes;
184 if ((result = nile_mcu_native_recv_cmd_finish(&bytes, 1)) < 0) return result;
185 return bytes;
186}
187
188static inline int16_t nile_mcu_native_recv_cmd_response_int16(void) {
189 int16_t result, bytes;
190 if ((result = nile_mcu_native_recv_cmd_finish(&bytes, 2)) < 0) return result;
191 return bytes;
192}
193
201
205static inline int16_t nile_mcu_native_mcu_switch_mode(uint8_t mode) {
206 return nile_mcu_native_send_cmd(NILE_MCU_NATIVE_CMD(0x01, mode), NULL, 0);
207}
208
214static inline int16_t nile_mcu_native_mcu_spi_set_speed_sync(uint8_t speed) {
215 int16_t result;
216 uint8_t op_result;
217 if ((result = nile_mcu_native_send_cmd(NILE_MCU_NATIVE_CMD(0x02, speed), NULL, 0)) < 0) return result;
218 if ((result = nile_mcu_native_recv_cmd(&op_result, 1)) < 0) return result;
219 return op_result;
220}
221
222static inline int16_t nile_mcu_native_mcu_get_uuid_sync(void __far* buffer, uint16_t buflen) {
223 int16_t result;
224 if ((result = nile_mcu_native_send_cmd(NILE_MCU_NATIVE_CMD(0x03, 0), NULL, 0)) < 0) return result;
225 return nile_mcu_native_recv_cmd(buffer, buflen);
226}
227
228static inline int16_t nile_mcu_native_cdc_read_sync(void __far* buffer, uint16_t buflen) {
229 int16_t result;
230 if ((result = nile_mcu_native_send_cmd(NILE_MCU_NATIVE_CMD(0x40, buflen), NULL, 0)) < 0) return result;
231 return nile_mcu_native_recv_cmd(buffer, buflen);
232}
233
234static inline int16_t nile_mcu_native_cdc_write_sync(const void __wf_cram* buffer, uint16_t buflen) {
235 int16_t result, bytes;
236 if ((result = nile_mcu_native_send_cmd(NILE_MCU_NATIVE_CMD(0x41, buflen), buffer, buflen)) < 0) return result;
237 if ((result = nile_mcu_native_recv_cmd(&bytes, 2)) < 0) return result;
238 return bytes;
239}
240
241static inline int16_t nile_mcu_native_cdc_write_async_start(const void __wf_cram* buffer, uint16_t buflen) {
242 int16_t result;
243 if ((result = nile_mcu_native_send_cmd(NILE_MCU_NATIVE_CMD(0x41, buflen), buffer, buflen)) < 0) return result;
245}
246#define nile_mcu_native_cdc_write_async_finish nile_mcu_native_recv_cmd_response_int16
247
248static inline int16_t nile_mcu_native_cdc_available_sync(void) {
249 int16_t result, bytes;
250 if ((result = nile_mcu_native_send_cmd(NILE_MCU_NATIVE_CMD(0x43, 0), NULL, 0)) < 0) return result;
251 if ((result = nile_mcu_native_recv_cmd(&bytes, 2)) < 0) return result;
252 return bytes;
253}
254
255static inline int16_t nile_mcu_native_cdc_available_async_start(const void __wf_cram* buffer, uint16_t buflen) {
256 int16_t result;
257 if ((result = nile_mcu_native_send_cmd(NILE_MCU_NATIVE_CMD(0x43, 0), buffer, buflen)) < 0) return result;
259}
260#define nile_mcu_native_cdc_available_async_finish nile_mcu_native_recv_cmd_response_int16
261
262static inline int16_t nile_mcu_native_cdc_clear_sync(void) {
263 int16_t result;
264 if ((result = nile_mcu_native_send_cmd(NILE_MCU_NATIVE_CMD(0x44, 0xFF), NULL, 0)) < 0) return result;
265 return nile_mcu_native_recv_cmd(NULL, 0);
266}
267
268#endif /* __ASSEMBLER__ */
269
270#endif /* NILE_MCU_H_ */
uint8_t nile_mcu_boot_get_version(void)
Get the version of the SPI protocol used. More information is available in the Application Note AN428...
static int16_t nile_mcu_native_mcu_spi_set_speed_sync(uint8_t speed)
Tell the MCU to operate at a specific SPI speed.
Definition mcu.h:214
int16_t nile_mcu_native_recv_cmd(void __far *buffer, uint16_t buflen)
Receive the response of a "native protocol" MCU command synchronously.
static int16_t nile_mcu_native_mcu_get_uuid_sync(void __far *buffer, uint16_t buflen)
Definition mcu.h:222
uint16_t nile_mcu_boot_get_id(void)
Get the chip ID. More information is available in the Application Note AN4286.
bool nile_mcu_boot_send_data(const void __far *buffer, uint16_t len, uint8_t flags)
static int16_t nile_mcu_native_cdc_write_sync(const void __wf_cram *buffer, uint16_t buflen)
Definition mcu.h:234
static int16_t nile_mcu_native_recv_cmd_response_uint8(void)
Definition mcu.h:182
#define NILE_MCU_NATIVE_CMD(cmd, arg)
Definition mcu.h:55
static int16_t nile_mcu_native_cdc_read_sync(void __far *buffer, uint16_t buflen)
Definition mcu.h:228
bool nile_mcu_boot_read_memory(uint32_t address, void __far *buffer, uint16_t buflen)
Request bytes from the MCU's address space.
bool nile_mcu_reset(bool to_bootloader)
Reset the MCU.
static int16_t nile_mcu_native_recv_cmd_response_int16(void)
Definition mcu.h:188
int16_t nile_mcu_native_recv_cmd_start(uint16_t resplen)
Start receiving the response of a "native protocol" MCU command asynchronously.
static int16_t nile_mcu_native_mcu_switch_mode(uint8_t mode)
Switch the mode in which the MCU is operating.
Definition mcu.h:205
bool nile_mcu_boot_jump(uint32_t address)
Request that the MCU branch to a specific address in memory.
static int16_t nile_mcu_native_cdc_available_async_start(const void __wf_cram *buffer, uint16_t buflen)
Definition mcu.h:255
nile_mcu_native_mode_t
Definition mcu.h:194
@ NILE_MCU_NATIVE_MODE_STANDBY
MCU standby mode - will not respond to further SPI messages until reset.
Definition mcu.h:199
@ NILE_MCU_NATIVE_MODE_RTC
RTC emulation mode.
Definition mcu.h:197
@ NILE_MCU_NATIVE_MODE_CDC
CDC output-only mode.
Definition mcu.h:198
@ NILE_MCU_NATIVE_MODE_EEPROM
EEPROM emulation mode.
Definition mcu.h:196
@ NILE_MCU_NATIVE_MODE_CMD
Native command mode.
Definition mcu.h:195
static int16_t nile_mcu_native_cdc_write_async_start(const void __wf_cram *buffer, uint16_t buflen)
Definition mcu.h:241
static int16_t nile_mcu_native_cdc_available_sync(void)
Definition mcu.h:248
bool nile_mcu_boot_send_cmd(uint8_t cmd)
static bool nile_mcu_boot_erase_all_memory(void)
Erase all of the MCU's flash memory.
Definition mcu.h:125
bool nile_mcu_boot_write_memory(uint32_t address, const void __far *buffer, uint16_t buflen)
Write bytes to the MCU's address space (RAM or flash memory).
static int16_t nile_mcu_native_send_cmd(uint16_t cmd, const void __far *buffer, int buflen)
Send a "native protocol" MCU command asynchronously.
Definition mcu.h:148
uint16_t nile_mcu_boot_recv_data(void __far *buffer, uint16_t buflen, uint8_t flags)
bool nile_mcu_boot_erase_memory(uint16_t sector_address, uint16_t sector_count)
Erase pages of the MCU's flash memory.
#define NILE_MCU_BOOT_ERASE_ALL_SECTORS
Definition mcu.h:47
static int16_t nile_mcu_native_cdc_clear_sync(void)
Definition mcu.h:262
bool nile_mcu_boot_wait_ack(void)
int16_t nile_mcu_native_recv_cmd_finish(void __far *buffer, uint16_t buflen)
Finish receiving the response of a "native protocol" MCU command.