[realtek-ambz2] Implement base C API

This commit is contained in:
Kuba Szczodrzyński
2023-05-23 19:54:00 +02:00
parent 43c9d0db10
commit b073290989
16 changed files with 246 additions and 52 deletions

View File

@@ -29,10 +29,6 @@ lt_cpu_model_t lt_cpu_get_model() {
return CPU_MODEL_ENUM(FAMILY, chipId);
}
uint32_t lt_cpu_get_unique_id() {
return lt_cpu_get_mac_id();
}
uint32_t lt_cpu_get_mac_id() {
uint8_t mac[6];
cfg_load_mac(mac); // force loading MAC from TLV (ignore user-set WiFi MAC)

View File

@@ -15,7 +15,7 @@ const char *lt_get_version();
const char *lt_get_board_code();
/**
* @brief Get device friendly name in format "LT-<family code>-<MAC ID>".
* @brief Get device friendly name in format "LT-<chip model>-<MAC ID>".
* Can be used as hostname.
*/
const char *lt_get_device_name();

View File

@@ -35,6 +35,10 @@ const char *lt_cpu_get_model_code() {
return STRINGIFY_MACRO(MCULC);
}
__attribute__((weak)) uint32_t lt_cpu_get_unique_id() {
return lt_cpu_get_mac_id();
}
__attribute__((weak)) uint8_t lt_cpu_get_core_count() {
return 1;
}
@@ -85,6 +89,12 @@ const char *lt_get_device_name() {
return device_name;
}
__attribute__((weak)) void lt_reboot() {
// The Watchdog Way
lt_wdt_enable(1L);
while (1) {}
}
__attribute__((weak)) bool lt_reboot_wdt() {
if (!lt_wdt_enable(1L))
return false;
@@ -95,24 +105,30 @@ __attribute__((weak)) bool lt_reboot_download_mode() {
return false;
}
__attribute__((weak)) lt_reboot_reason_t lt_get_reboot_reason() {
return REBOOT_REASON_UNKNOWN;
}
const char *lt_get_reboot_reason_name(lt_reboot_reason_t reason) {
if (!reason)
reason = lt_get_reboot_reason();
switch (reason) {
case RESET_REASON_POWER:
case REBOOT_REASON_POWER:
return "Power-On";
case RESET_REASON_BROWNOUT:
case REBOOT_REASON_BROWNOUT:
return "Brownout";
case RESET_REASON_HARDWARE:
case REBOOT_REASON_HARDWARE:
return "HW Reboot";
case RESET_REASON_SOFTWARE:
case REBOOT_REASON_SOFTWARE:
return "SW Reboot";
case RESET_REASON_WATCHDOG:
case REBOOT_REASON_WATCHDOG:
return "WDT Reset";
case RESET_REASON_CRASH:
case REBOOT_REASON_CRASH:
return "Crash";
case RESET_REASON_SLEEP:
case REBOOT_REASON_SLEEP:
return "Sleep Wakeup";
case REBOOT_REASON_DEBUGGER:
return "Debugger";
default:
return "Unknown";
}

View File

@@ -20,7 +20,7 @@ int lt_main(void) {
// initialize C library
__libc_init_array();
// inform about the reset reason
LT_I("Reset reason: %u", lt_get_reboot_reason());
LT_I("Reset reason: %s", lt_get_reboot_reason_name(0));
// initialize FAL
fal_init();
// provide root partition

View File

@@ -40,8 +40,10 @@ typedef enum {
RTL8711BU = CPU_MODEL(F_RTL8710B, 0xFC), // CHIPID_8711BG / QFN68
MX1290 = RTL8710BN,
MX1290V2 = RTL8710BX,
// Realtek AmebaZ2
RTL8720CF = CPU_MODEL(F_RTL8720C, 0x00), // TODO
// Realtek AmebaZ2 (chip_id << 2 | flash_mode)
RTL8720CM = CPU_MODEL(F_RTL8720C, 0xEC), // 0xFB << 2 | 0
RTL8720CF = CPU_MODEL(F_RTL8720C, 0xED), // 0xFB << 2 | 1
RTL8720CX = RTL8720CM,
// Beken 72XX
BK7231T = CPU_MODEL(F_BK7231U, 0x1A), // *SCTRL_CHIP_ID = 0x7231a
BK7231N = CPU_MODEL(F_BK7231N, 0x1C), // *SCTRL_CHIP_ID = 0x7231c
@@ -63,7 +65,8 @@ typedef enum {
REBOOT_REASON_WATCHDOG = 6,
REBOOT_REASON_CRASH = 7,
REBOOT_REASON_SLEEP = 8,
REBOOT_REASON_MAX = 9,
REBOOT_REASON_DEBUGGER = 9,
REBOOT_REASON_MAX = 10,
} lt_reboot_reason_t;
/**

View File

@@ -4,5 +4,13 @@
#ifdef ARDUINO
#define boolean boolean_rtl
#endif
#include <stdbool.h>
#ifndef bool
#define bool bool
#endif
#include_next "basic_types.h"
#undef boolean

View File

@@ -16,9 +16,11 @@
#include <string.h>
#include "basic_types.h" // fixup: replaces typedef boolean for Arduino compatibility
#ifdef LT_RTL8710B
#include "memproc.h" // fixup: redirects to stdlib
#if __has_include(<memproc.h>)
#include <memproc.h> // fixup: redirects to stdlib
#endif
#if __has_include(<strproc.h>)
#include "strproc.h" // fixup: redirects to stdlib
#endif
#include "diag.h"

View File

@@ -0,0 +1,42 @@
/* Copyright (c) Kuba Szczodrzyński 2023-05-23. */
#include <libretiny.h>
#include <sdk_private.h>
/*______ _ _
| ____| | | |
| |__ | | __ _ ___| |__
| __| | |/ _` / __| '_ \
| | | | (_| \__ \ | | |
|_| |_|\__,_|___/_| |*/
lt_flash_id_t lt_flash_get_id() {
lt_flash_id_t id;
uint8_t idBytes[3];
flash_read_id(&lt_flash_obj, idBytes, 3);
id.manufacturer_id = idBytes[0];
id.chip_id = idBytes[1];
id.chip_size_id = idBytes[2];
return id;
}
/*_ __ _ _ _
\ \ / / | | | | | |
\ \ /\ / /_ _| |_ ___| |__ __| | ___ __ _
\ \/ \/ / _` | __/ __| '_ \ / _` |/ _ \ / _` |
\ /\ / (_| | || (__| | | | (_| | (_) | (_| |
\/ \/ \__,_|\__\___|_| |_|\__,_|\___/ \__, |
__/ |
|___*/
bool lt_wdt_enable(uint32_t timeout) {
watchdog_init(timeout);
watchdog_start();
return true;
}
void lt_wdt_disable() {
watchdog_stop();
}
void lt_wdt_feed() {
watchdog_refresh();
}

View File

@@ -7,26 +7,26 @@
#define FLASH_ERASE_MIN_SIZE (4 * 1024)
static flash_t flash_obj;
flash_t lt_flash_obj;
static int init() {
flash_get_status(&flash_obj);
flash_get_status(&lt_flash_obj);
return 0;
}
static int read(long offset, uint8_t *buf, size_t size) {
return size * flash_stream_read(&flash_obj, offset, size, buf);
return size * flash_stream_read(&lt_flash_obj, offset, size, buf);
}
static int write(long offset, const uint8_t *buf, size_t size) {
return size * flash_stream_write(&flash_obj, offset, size, (uint8_t *)buf);
return size * flash_stream_write(&lt_flash_obj, offset, size, (uint8_t *)buf);
}
static int erase(long offset, size_t size) {
offset &= ~(FLASH_ERASE_MIN_SIZE - 1);
size = ((size - 1) / FLASH_ERASE_MIN_SIZE) + 1;
for (uint16_t i = 0; i < size; i++) {
flash_erase_sector(&flash_obj, offset + i * FLASH_ERASE_MIN_SIZE);
flash_erase_sector(&lt_flash_obj, offset + i * FLASH_ERASE_MIN_SIZE);
}
return size * FLASH_ERASE_MIN_SIZE;
}

View File

@@ -21,6 +21,7 @@ extern "C" {
#endif
#if LT_RTL8720C
#include <hal.h>
#include <hal_sys_ctrl.h>
#include <rtl8710c.h>
#endif
@@ -30,6 +31,10 @@ extern "C" {
#include <analogin_api.h>
#include <analogout_api.h>
#include <efuse_api.h>
#if LT_RTL8720C
#include <efuse_logical_api.h>
#endif
#include <flash_api.h>
#include <gpio_irq_api.h>
#include <gpio_irq_ex_api.h>
@@ -43,6 +48,10 @@ extern "C" {
#include <wait_api.h>
#include <wdt_api.h>
#if __has_include(<sdk_extern.h>)
#include <sdk_extern.h>
#endif
// remove previously defined workarounds
#undef PinMode
@@ -67,14 +76,7 @@ extern "C" {
#define _write __rtl_write
#define _sbrk __rtl_sbrk
#define delay_us wait_us
extern void wait_us(int us);
extern int LOGUART_SetBaud(uint32_t BaudRate); // from fixups/log_uart.c
extern void DumpForOneBytes(void *addr, int cnt); // cnt max 0x70!
extern void SystemCoreClockUpdate(void);
extern int _sscanf_patch(const char *buf, const char *fmt, ...);
extern flash_t lt_flash_obj;
#ifdef __cplusplus
} // extern "C"

View File

@@ -27,10 +27,6 @@ lt_cpu_model_t lt_cpu_get_model() {
return CPU_MODEL_ENUM(FAMILY, chipId);
}
uint32_t lt_cpu_get_unique_id() {
return lt_cpu_get_mac_id();
}
uint32_t lt_cpu_get_mac_id() {
uint32_t chipId = 0;
uint8_t *id = (uint8_t *)&chipId;
@@ -61,12 +57,6 @@ uint32_t lt_cpu_get_freq() {
| | | |/ _ \ \ / / |/ __/ _ \
| |__| | __/\ V /| | (_| __/
|_____/ \___| \_/ |_|\___\__*/
void lt_reboot() {
// The Watchdog Way
lt_wdt_enable(1L);
while (1) {}
}
bool lt_reboot_download_mode() {
// mww 0x40000138 0x8
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_NORESET_FF, 0x08);
@@ -76,11 +66,6 @@ bool lt_reboot_download_mode() {
return true;
}
lt_reboot_reason_t lt_get_reboot_reason() {
// TODO
return REBOOT_REASON_UNKNOWN;
}
void lt_gpio_recover() {
// PA14 and PA15 are apparently unusable with SWD enabled
sys_jtag_off();

View File

@@ -0,0 +1,14 @@
/* Copyright (c) Kuba Szczodrzyński 2023-05-23. */
#pragma once
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
int LOGUART_SetBaud(uint32_t BaudRate); // from fixups/log_uart.c
extern void DumpForOneBytes(void *addr, int cnt); // cnt max 0x70!
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -151,7 +151,7 @@ unsigned int atoui(const char *num) {
return strproc_stubs.atoui(num);
}
size_t strnlen(const char *s, size_t count) {
__attribute__((weak)) size_t strnlen(const char *s, size_t count) {
return strproc_stubs.strnlen(s, count);
}
@@ -163,6 +163,6 @@ int strnicmp(const char *s1, const char *s2, size_t len) {
return strproc_stubs.strnicmp(s1, s2, len);
}
char *strsep(char **s, const char *ct) {
__attribute__((weak)) char *strsep(char **s, const char *ct) {
return strproc_stubs.strsep(s, ct);
}

View File

@@ -13,7 +13,107 @@ void lt_init_family() {
lt_uart_port = LT_UART_DEFAULT_PORT;
}
lt_reboot_reason_t lt_get_reboot_reason() {
// TODO
return REBOOT_REASON_UNKNOWN;
/* _____ _____ _ _
/ ____| __ \| | | |
| | | |__) | | | |
| | | ___/| | | |
| |____| | | |__| |
\_____|_| \____*/
lt_cpu_model_t lt_cpu_get_model() {
uint32_t *addr = (uint32_t *)0x40000038;
uint8_t flash_mode = (addr[0] >> 5) & 0b11;
uint32_t chip_id = 0;
hal_get_chip_id(&chip_id);
chip_id <<= 2;
return CPU_MODEL_ENUM(FAMILY, (chip_id & 0xFF) | flash_mode);
}
uint32_t lt_cpu_get_mac_id() {
uint8_t mac[3];
efuse_logical_read(0x11A + 3, 3, mac);
return (mac[0] << 0) | (mac[1] << 8) | (mac[2] << 16);
}
const char *lt_cpu_get_core_type() {
return "ARM Cortex-M4";
}
uint32_t lt_cpu_get_freq() {
return hal_syson_query_sys_clk();
}
/*_____ _
| __ \ (_)
| | | | _____ ___ ___ ___
| | | |/ _ \ \ / / |/ __/ _ \
| |__| | __/\ V /| | (_| __/
|_____/ \___| \_/ |_|\___\__*/
void lt_reboot() {
sys_cpu_reset();
while (1) {}
}
bool lt_reboot_download_mode() {
sys_uart_download_mode();
while (1) {}
return true;
}
lt_reboot_reason_t lt_get_reboot_reason() {
hal_reset_reason_t reason = -1;
rtl8710c_reset_reason_get(&reason);
switch (reason) {
case HAL_RESET_REASON_POWER_ON:
return REBOOT_REASON_POWER;
case HAL_RESET_REASON_SOFTWARE:
return REBOOT_REASON_SOFTWARE;
case HAL_RESET_REASON_WATCHDOG:
return REBOOT_REASON_WATCHDOG;
case HAL_RESET_REASON_JTAG:
return REBOOT_REASON_DEBUGGER;
default:
return REBOOT_REASON_UNKNOWN;
}
}
void lt_gpio_recover() {
sys_jtag_off();
}
/*__ __
| \/ |
| \ / | ___ _ __ ___ ___ _ __ _ _
| |\/| |/ _ \ '_ ` _ \ / _ \| '__| | | |
| | | | __/ | | | | | (_) | | | |_| |
|_| |_|\___|_| |_| |_|\___/|_| \__, |
__/ |
|__*/
uint32_t lt_ram_get_size() {
return 256 * 1024;
}
/* ____ _______
/ __ \__ __|/\
| | | | | | / \
| | | | | | / /\ \
| |__| | | |/ ____ \
\____/ |_/_/ \*/
lt_ota_type_t lt_ota_get_type() {
return OTA_TYPE_DUAL;
}
bool lt_ota_is_valid(uint8_t index) {
return false;
}
uint8_t lt_ota_dual_get_current() {
return 0;
}
uint8_t lt_ota_dual_get_stored() {
return 0;
}
bool lt_ota_switch(bool revert) {
return false;
}

View File

@@ -0,0 +1,26 @@
/* Copyright (c) Kuba Szczodrzyński 2023-05-23. */
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// SDK
void software_reset();
void sys_uart_download_mode();
void sys_download_mode(uint8_t mode);
// blobs
bool Hal_GetPhyEfuseMACAddr(uint32_t xFFFFE5BB, uint8_t *buf);
bool rtw_efuse_map_read(uint32_t xFFFFE5BB, uint32_t offset, uint32_t length, uint8_t *buf);
uint32_t efuse_OneByteRead(uint32_t x33300000, uint32_t addr, uint8_t *buf, uint32_t ldo);
uint32_t EFUSERead8(uint32_t x33300000, uint32_t addr, uint8_t *buf, uint32_t ldo);
uint32_t hal_get_chip_id(uint32_t *id);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -17,4 +17,4 @@ UM0201 | [Ameba Common BT Application User Manual EN](https://raw.githubusercont
&nbsp; | Found elsewhere
AN0400 | [Ameba-D Application Note_v3_watermark](https://files.seeedstudio.com/products/102110419/Basic%20documents/AN0400%20Ameba-D%20Application%20Note_v3_watermark.pdf)
AN0500 | [Realtek Ameba-ZII application note](https://www.e-paper-display.com/99IOT/00015797-AN0500-Realtek-Ameba-ZII-application-note.en_233850.pdf)
&nbsp; | [Realtek Ameba-ZII datasheet v0.8](https://www.e-paper-display.com/Ameba-Z_II_DataSheet_v0r8_RTL8720Cx_20190424%29.pdf)
&nbsp; | [Realtek Ameba-ZII datasheet v0.8](https://web.archive.org/web/20230523175304if_/https://cetest02.cn-bj.ufileos.com/100001_2110255103/RTL872xZ2%20IC%20Datasheet.pdf)