refactor: refactor embedded C policy and enhance warning checks

- Updated the default output path in  to .
- Introduced a new  file to define excluded prefixes, compatibility files, and forbidden calls for embedded C sources.
- Modified  to improve compiler flags and source file organization.
- Added scripts for checking C warnings and embedded C compliance, ensuring self-owned sources are validated against the policy.
- Implemented regression tests to capture and report self-owned C compiler warnings during builds.
- Created a new test suite for runtime tests of SDK utilities, ensuring deterministic behavior.
- Enhanced existing test scripts to include checks for C warnings and compliance with the embedded C policy.
This commit is contained in:
maksyuki committed 2026-07-11 12:43:26 +08:00
1 parent 42f902e995
commit 0d4999a794
206 files changed
+6219 -5352

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Never
ColumnLimit: 100
BreakBeforeBraces: Attach
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
PointerAlignment: Right
SortIncludes: Never
+14
View File
@@ -0,0 +1,14 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.{c,h,S}]
indent_style = space
indent_size = 4
[Makefile]
indent_style = tab
+14
View File
@@ -31,12 +31,26 @@ jobs:
- name: Install pinned quality tools
run: python3 -m pip install --requirement requirements/ci.txt
- name: Install clang-format
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends --yes clang-format-14
- name: Validate dependency lock
run: python3 scripts/dependency_lock.py --lock config/dependencies.lock.json
- name: Lint Python
run: ruff check .
- name: Check embedded C formatting policy
run: make sw-format-check
- name: Check embedded C safety policy
run: make sw-policy-check
- name: Run embedded C host tests
run: make sw-host-test
- name: Test scripts
run: python3 -m pytest -q
+26 -6
View File
@@ -48,17 +48,19 @@ RTL_TOP ?= retrosoc_tb
ISA ?= RV32IM
HAVE_CSR ?= NO
FIRMWARE_NAME ?= retrosoc_fw
PROG_TYPE ?= FULL
APP ?= shell
LINK_TYPE ?= ld2_sram
BUILD_ROOT ?= $(ROOT_PATH)/build
CACHE_ROOT ?= $(ROOT_PATH)/.cache/retrosoc
MAX_JOBS ?= 16
HOST_CC ?= cc
CLANG_FORMAT ?= clang-format-14
JOBS ?= $(shell count=$$(nproc 2>/dev/null || printf '1'); \
if [ "$$count" -gt "$(MAX_JOBS)" ]; then printf '%s' '$(MAX_JOBS)'; \
else printf '%s' "$$count"; fi)
CONFIG_KEY_VARS := SOC CORE IP PDK HAVE_PLL HAVE_SRAM_IF HAVE_SRAM_MACRO HAVE_SVA \
ISA HAVE_CSR PROG_TYPE LINK_TYPE RTL_TOP FIRMWARE_NAME
ISA HAVE_CSR APP LINK_TYPE RTL_TOP FIRMWARE_NAME
VARIANT_ID := $(strip $(shell python3 $(ROOT_PATH)/scripts/config_key.py \
--lock $(LOCK_FILE) --profile $(PROFILE_NAME) \
$(foreach var,$(CONFIG_KEY_VARS),--value $(var)=$($(var)))))
@@ -88,7 +90,7 @@ VALID_STA := NONE OPENSTA
VALID_PDK := ICS55 IHP130 SKY130 GF180
VALID_BOOL := YES NO
VALID_ISA := RV32E RV32I RV32IM
VALID_PROG_TYPE := BASE FULL
VALID_APP := bringup shell
VALID_LINK_TYPE := xip ld2_sram ld2_psram ld2_sdram
define validate_value
@@ -109,7 +111,7 @@ $(call validate_value,HAVE_SVA,$(VALID_BOOL))
$(call validate_value,WAVE,$(VALID_BOOL))
$(call validate_value,ISA,$(VALID_ISA))
$(call validate_value,HAVE_CSR,$(VALID_BOOL))
$(call validate_value,PROG_TYPE,$(VALID_PROG_TYPE))
$(call validate_value,APP,$(VALID_APP))
$(call validate_value,LINK_TYPE,$(VALID_LINK_TYPE))
ifeq ($(SYNTH),YOSYS)
@@ -161,7 +163,7 @@ endif
.PHONY: help config doctor setup setup-mpw setup-core setup-clusterip setup-ip setup-pdk setup-app \
clean-all purge-cache manifest check-warnings metrics check-metrics package \
regress-pr regress-nightly sim-asm
regress-pr regress-nightly sim-asm sw-format sw-format-check sw-policy-check sw-host-test
.NOTPARALLEL: setup
help:
@@ -178,6 +180,10 @@ help:
' config | manifest print/write the effective configuration' \
' check-warnings | metrics analyze flow logs and reports' \
' check-metrics apply the committed metrics policy' \
' sw-format apply clang-format to self-owned embedded C code' \
' sw-format-check check embedded C whitespace and line-ending policy' \
' sw-policy-check check embedded C API and naming policy' \
' sw-host-test run host tests for deterministic SDK utilities' \
' regress-pr | regress-nightly run supported regression suites' \
' package create checksummed source deliverables' \
' clean | clean-all clean current flow or all build output' \
@@ -194,7 +200,7 @@ config:
SIMU '$(SIMU)' SYNTH '$(SYNTH)' STA '$(STA)' PDK '$(PDK)' \
HAVE_PLL '$(HAVE_PLL)' HAVE_SRAM_IF '$(HAVE_SRAM_IF)' \
HAVE_SRAM_MACRO '$(HAVE_SRAM_MACRO)' HAVE_SVA '$(HAVE_SVA)' \
ISA '$(ISA)' HAVE_CSR '$(HAVE_CSR)' PROG_TYPE '$(PROG_TYPE)' \
ISA '$(ISA)' HAVE_CSR '$(HAVE_CSR)' APP '$(APP)' \
LINK_TYPE '$(LINK_TYPE)'
doctor:
@@ -251,6 +257,20 @@ check-metrics: metrics
--policy $(ROOT_PATH)/quality/metrics/policy.json \
--baseline $(ROOT_PATH)/quality/metrics/baseline.json
sw-format:
python3 $(ROOT_PATH)/scripts/check_embedded_c.py --root $(ROOT_PATH) \
--apply-format --clang-format $(CLANG_FORMAT)
sw-format-check:
python3 $(ROOT_PATH)/scripts/check_embedded_c.py --root $(ROOT_PATH) --format-check \
--clang-format-check --clang-format $(CLANG_FORMAT)
sw-policy-check:
python3 $(ROOT_PATH)/scripts/check_embedded_c.py --root $(ROOT_PATH) --policy-check
sw-host-test:
python3 $(ROOT_PATH)/scripts/run_c_tests.py --root $(ROOT_PATH) --cc $(HOST_CC)
package: $(MPW_VARIANT_STAMP) $(FILELIST_STAMP) manifest
python3 $(ROOT_PATH)/scripts/package.py --root $(ROOT_PATH) --lock $(LOCK_FILE) \
--variant-root $(VARIANT_ROOT) --output-dir $(ROOT_PATH)/dist/$(VARIANT_ID)
+87
View File
@@ -0,0 +1,87 @@
# retroSoC Applications
`app/` contains the firmware applications and the components assembled by those
applications. It builds on the freestanding SDK in [`../crt`](../crt) and keeps
application policy separate from common runtime and HAL code.
## Layout
| Path | Purpose |
| --- | --- |
| `apps/` | Selectable application profiles. Each profile owns `main.c` and an `app.mk` source manifest. |
| `board/` | Board-specific device drivers and public board headers. |
| `media/` | WAV, video, and visual-demo components with public media headers. |
| `middleware/` | Application middleware configuration and integration, including FatFs. |
| `network/` | Optional network or user-IP integration. |
| `ports/` | Ports and configuration for external libraries, such as LVGL. |
| `benchmark/` | Project integration for benchmark workloads, including CoreMark. |
| `asm/` | Standalone assembly firmware used by low-level simulation self-tests. |
Versioned third-party source trees are managed by the setup flow. Do not
reformat or treat them as ordinary application code: use their integration
directory and setup tooling when updating FatFs, CoreMark, or LVGL.
## Application Profiles
The build selects an application with `APP=<name>`. The supported profiles are:
| Profile | Description |
| --- | --- |
| `bringup` | Minimal firmware used for startup and basic SoC regression. |
| `shell` | Interactive application that adds shell services, board drivers, media, FatFs, CoreMark, and UserIP integration. |
The application manifest is loaded from `app/apps/<name>/app.mk`. It appends
`APP_SRCS` and, when necessary, `APP_INC_DIRS` to the SDK sources selected by
the central build.
Build and simulate the supported profiles from the repository root:
```sh
# Bringup firmware and Verilator simulation
make CONFIG=configs/ci/hazard3-rv32im-ihp130.mk SIMU=VERILATOR firmware sim
# Shell firmware and Verilator simulation
make CONFIG=configs/ci/hazard3-rv32im-ihp130-shell.mk SIMU=VERILATOR firmware sim
```
For a firmware-only build, omit `SIMU=VERILATOR sim`.
## Adding an Application
1. Create `app/apps/<name>/main.c` and `app/apps/<name>/app.mk`.
2. List the application-owned sources in `APP_SRCS` and export only required
include directories through `APP_INC_DIRS`.
3. Add `<name>` to the allowed `APP` values in the top-level `Makefile`; this
keeps profile selection explicit and rejects misspellings.
4. Add a committed configuration profile under `configs/` that selects
`APP := <name>` and the required core, ISA, CSR, and linker options.
5. Add host tests for deterministic parsing or utility code, and add a
regression command when the application must execute in simulation.
Applications should consume public SDK headers through `<retrosoc/...>`.
Application-specific public headers belong below their own component include
directory, such as `board/include/retrosoc/board/` or
`media/include/retrosoc/media/`.
## Quality Checks
Run the shared checks from the repository root before submitting changes:
```sh
make sw-format-check
make sw-policy-check
make sw-host-test
python3 -m pytest -q
```
The embedded-C checks apply to self-owned code and deliberately exclude managed
third-party source trees. Use the repository regression suites for end-to-end
firmware, RTL, netlist, synthesis, and timing coverage:
```sh
make regress-pr
make regress-nightly
```
See the [repository README](../README.md) for prerequisites, supported
configurations, and build artifact locations.
+1
View File
@@ -0,0 +1 @@
APP_SRCS += $(ROOT_PATH)/app/apps/bringup/main.c
+11
View File
@@ -0,0 +1,11 @@
#include <retrosoc/core/archinfo.h>
#include <retrosoc/core/soc.h>
#include <retrosoc/hal/uart.h>
#include <retrosoc/service/booter.h>
int main(void) {
uart0_init(CPU_FREQ, UART_BPS);
rs_app_info();
ip_archinfo_test(0, 0);
return 0;
}
+17
View File
@@ -0,0 +1,17 @@
APP_SRCS += $(ROOT_PATH)/app/apps/shell/main.c
APP_SRCS += $(ROOT_PATH)/crt/src/service/shell.c
APP_SRCS += $(ROOT_PATH)/crt/src/hal/i2s.c
APP_SRCS += $(ROOT_PATH)/app/board/src/at24cxx.c
APP_SRCS += $(ROOT_PATH)/app/board/src/pcf8563b.c
APP_SRCS += $(ROOT_PATH)/app/board/src/es8388.c
APP_SRCS += $(ROOT_PATH)/app/board/src/w25q128jvxim.c
APP_SRCS += $(ROOT_PATH)/app/media/src/wav_audio.c
APP_SRCS += $(ROOT_PATH)/app/media/src/video_player.c
APP_SRCS += $(ROOT_PATH)/app/media/src/donut.c
APP_INC_DIRS += $(ROOT_PATH)/app/board/include
APP_INC_DIRS += $(ROOT_PATH)/app/media/include
include $(ROOT_PATH)/app/middleware/fatfs/fatfs.mk
include $(ROOT_PATH)/app/benchmark/coremark/coremark.mk
include $(ROOT_PATH)/app/network/userip/userip.mk
+88
View File
@@ -0,0 +1,88 @@
#include <retrosoc/board/pcf8563b.h>
#include <retrosoc/board/w25q128jvxim.h>
#include <retrosoc/core/archinfo.h>
#include <retrosoc/core/irq.h>
#include <retrosoc/core/soc.h>
#include <retrosoc/hal/crc.h>
#include <retrosoc/hal/gpio.h>
#include <retrosoc/hal/hpuart.h>
#include <retrosoc/hal/i2c.h>
#include <retrosoc/hal/i2s.h>
#include <retrosoc/hal/lcd.h>
#include <retrosoc/hal/onewire.h>
#include <retrosoc/hal/ps2.h>
#include <retrosoc/hal/pwm.h>
#include <retrosoc/hal/qspi.h>
#include <retrosoc/hal/rng.h>
#include <retrosoc/hal/rtc.h>
#include <retrosoc/hal/timer.h>
#include <retrosoc/hal/uart.h>
#include <retrosoc/hal/watchdog.h>
#include <retrosoc/media/donut.h>
#include <retrosoc/service/booter.h>
#include <retrosoc/service/shell.h>
static void rs_app_info_command(int argc, char **argv) {
(void)argc;
(void)argv;
rs_app_info();
}
int main(void) {
uart0_init(CPU_FREQ, UART_BPS);
rs_booter();
if (rs_i2c0_init((uint8_t)(CPU_FREQ / 2 - 1)) != RS_OK) {
return 1;
}
qspi_dev_init();
lcd_init();
// lv_init();
// tim1_init();
// lv_tick_set_cb(my_get_millis);
// lv_port_disp_init();
// lv_obj_t *label = lv_label_create(lv_scr_act());
// lv_label_set_text(label,"Hello maksyuki!!!");
// lv_obj_center(label);
// while(1) {
// lv_timer_handler();
// delay_ms(5);
// printf("hello\n");
// }
rs_shell_init();
(void)rs_shell_register("app", "app info", true, rs_app_info_command);
(void)rs_shell_register("arch", "archinfo test", true, ip_archinfo_test);
(void)rs_shell_register("1wire", "1wire test", true, ip_1wire_test);
(void)rs_shell_register("tim", "timer test", true, ip_tim_test);
(void)rs_shell_register("gpio", "gpio test", true, ip_gpio_test);
(void)rs_shell_register("pwm", "pwm test", true, ip_pwm_test);
(void)rs_shell_register("rtc", "rtc test", true, ip_rtc_test);
(void)rs_shell_register("wdg", "wdg test", true, ip_wdg_test);
(void)rs_shell_register("rng", "rng test", true, ip_rng_test);
(void)rs_shell_register("crc", "crc test", true, ip_crc_test);
(void)rs_shell_register("ps2", "ps2 test", false, ip_ps2_test);
(void)rs_shell_register("lcd", "lcd test", true, ip_lcd_test);
(void)rs_shell_register("i2s", "i2s test", false, ip_i2s_test);
(void)rs_shell_register("nor", "nor flash test", false, ip_norflash_test);
(void)rs_shell_register("uart1", "uart1 test", false, ip_hpuart_test);
(void)rs_shell_register("pcf", "pcf8563b test", true, pcf8563b_test);
#ifdef CSR_ENABLE
(void)rs_shell_register("irq", "tmr/sw irq test", true, irq_test);
#endif
(void)rs_shell_register("donut", "donut test", false, donut_test);
rs_shell_batch_run();
rs_shell_launch();
// video_show(0x60000000);
// ip_norflash_test();
// ip_lcd_test(0, NULL);
// ip_spisd_read((uint32_t)0x51004000, (uint32_t)44);
// ip_spisd_test();
// ip_dma_test(0, NULL);
// rs_bench(true, 0);
return 0;
}
-9
View File
@@ -1,9 +0,0 @@
#ifndef AT24C64_H__
#define AT24C64_H__
#define I2C_TEST_NUM 24
#define AT24C64_DEV_ADDR 0x50
void at24cxx_test();
#endif
-7
View File
@@ -1,7 +0,0 @@
#ifndef DONUT_H__
#define DONUT_H__
void donut_test();
#endif
-8
View File
@@ -1,8 +0,0 @@
#ifndef ES8388_H__
#define ES8388_H__
#define ES8388_DEV_ADDR 0x10
void es8388_init();
#endif
-48
View File
@@ -1,48 +0,0 @@
#ifndef PCF8563B_H__
#define PCF8563B_H__
#define PCF8563B_DEV_ADDR 0x51
#define PCF8563B_CTL_STATUS1 ((uint8_t)0x00)
#define PCF8563B_CTL_STATUS2 ((uint8_t)0x01)
#define PCF8563B_SECOND_REG ((uint8_t)0x02)
#define PCF8563B_MINUTE_REG ((uint8_t)0x03)
#define PCF8563B_HOUR_REG ((uint8_t)0x04)
#define PCF8563B_DAY_REG ((uint8_t)0x05)
#define PCF8563B_WEEKDAY_REG ((uint8_t)0x06)
#define PCF8563B_MONTH_REG ((uint8_t)0x07)
#define PCF8563B_YEAR_REG ((uint8_t)0x08)
#define SECOND_MINUTE_REG_WIDTH ((uint8_t)0x7F)
#define HOUR_DAY_REG_WIDTH ((uint8_t)0x3F)
#define WEEKDAY_REG_WIDTH ((uint8_t)0x07)
#define MONTH_REG_WIDTH ((uint8_t)0x1F)
#define YEAR_REG_WIDTH ((uint8_t)0xFF)
#define BCD_Century ((uint8_t)0x80)
typedef struct {
struct {
uint8_t second;
uint8_t minute;
uint8_t hour;
} time;
struct {
uint8_t weekday;
uint8_t day;
uint8_t month;
uint8_t year;
} date;
} PCF8563B_info_t;
// helper functions
uint8_t pcf8563b_bcd2bin(uint8_t val,uint8_t reg_width);
uint8_t pcf8563b_bin2bcd(uint8_t val);
void pcf8563b_wr_reg(PCF8563B_info_t *info);
PCF8563B_info_t pcf8563b_rd_reg();
void pcf8563b_test(int argc, char **argv);
#endif
-14
View File
@@ -1,14 +0,0 @@
#ifndef VIDEO_PLAYER_H__
#define VIDEO_PLAYER_H__
typedef struct {
uint32_t width;
uint32_t height;
uint32_t frame_count;
uint32_t reserved;
} VideoHeader_t;
void video_show(uint32_t addr);
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef W25Q128JVXIM_H__
#define W25Q128JVXIM_H__
void ip_norflash_test(int argc, char **argv);
#endif
-58
View File
@@ -1,58 +0,0 @@
#ifndef WAV_AUDIO_H__
#define WAV_AUDIO_H__
typedef struct {
char ChunkID[4];
uint32_t ChunkSize;
} ChunkHeader_t;
typedef struct {
char ChunkID[4]; // big endian
uint32_t ChunkSize;
char Format[4]; // big endian
} RIFFChunk_t;
typedef struct {
char Subchunk1ID[4]; // big endian
uint32_t Subchunk1Size;
uint16_t AudioFormat;
uint16_t NumChannels;
uint32_t SampleRate;
uint32_t ByteRate;
uint16_t BlockAlign;
uint16_t BitsPerSample;
} FMTChunk_t;
typedef struct {
char ChunkID[4];
uint32_t ChunkSize;
char ChunkData[60]; // HACK: use flexible array + malloc
} LISTChunkItem_t;
typedef struct {
char Subchunk2ID[4]; // big endian
uint32_t Subchunk2Size;
} DATAChunk_t;
typedef struct {
RIFFChunk_t riff;
FMTChunk_t fmt;
DATAChunk_t data;
LISTChunkItem_t list[20];
int info_num;
} WAVHeader_t;
// typedef struct {
// WAVHeader_t header;
// uint32_t addr;
// } WAVFile_t;
typedef struct {
uint32_t addr;
uint32_t size;
} WAVFile_t;
WAVFile_t wav_audio_parse(uint32_t start_addr);
#endif
-24
View File
@@ -1,24 +0,0 @@
#include <firmware.h>
#include <rs_printf.h>
#include <rs_i2c.h>
#include <at24cxx.h>
void at24cxx_test() {
printf("AT24C64 wr/rd test\n");
// prepare ref data
uint8_t ref_data[I2C_TEST_NUM], rd_data[I2C_TEST_NUM];
for(int i = 0; i < I2C_TEST_NUM; ++i) ref_data[i] = i;
// write AT24C64
i2c0_wr_nbyte(AT24C64_DEV_ADDR, (uint16_t)0, I2C_DEV_ADDR_16BIT, I2C_TEST_NUM, ref_data);
// read AT24C64
i2c0_rd_nbyte(AT24C64_DEV_ADDR, (uint16_t)0, I2C_DEV_ADDR_16BIT, I2C_TEST_NUM, rd_data);
// check data
for(int i = 0; i < I2C_TEST_NUM; ++i) {
printf("recv: %d expt: %d\n", rd_data[i], i);
if (rd_data[i] != i) printf("test fail\n");
}
i2c0_wr_nbyte(AT24C64_DEV_ADDR, (uint16_t)0, I2C_DEV_ADDR_16BIT, I2C_TEST_NUM, ref_data);
printf("AT24C64 wr/rd test done\n");
}
-235
View File
@@ -1,235 +0,0 @@
// Copyright 2025 ECOS Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -- Adaptable modifications are redistributed under compatible License --
//
// Copyright (c) 2023-2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
// retroSoC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
#include <firmware.h>
#include <rs_string.h>
#include <rs_printf.h>
#include <rs_qspi.h>
#include <rs_lcd.h>
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define GRAY_LEVELS 12
// screen framebuffer (128x128)
#define scale_x 8
#define scale_y 8
#define DONUT_SIZE 16
#define DONUT_WIDTH DONUT_SIZE * scale_x
#define DONUT_HEIGHT DONUT_SIZE * scale_y
const uint32_t gray_colors[GRAY_LEVELS] = {
0x00000000, // black (' ')
0x10821082, // dark gray ('.')
0x21042104, // Dark gray(',')
0x31863186, // darker gray ('-')
0x42084208, // medium dark gray ('~')
0x528A528A, // medium gray(':')
0x630C630C, // medium bright gray (';')
0x738E738E, // lighter gray ('=')
0x84108410, // bright gray('!')
0x94929492, // very bright gray ('*')
0xA514A514, // extremely bright gray ('#')
0xB596B596 // brightest gray ('$')
};
uint32_t donut_framebuffer_32[DONUT_WIDTH * DONUT_HEIGHT];
// void screen_clear(void) {
// memset(donut_framebuffer_32, 0x00, sizeof(donut_framebuffer_32));
// }
// inline marco
#define R_OPT(mul,shift,x,y) \
do { \
int _temp = x; \
x -= mul*y>>shift; \
y += mul*_temp>>shift; \
_temp = (3145728-x*x-y*y)>>11; \
x = x*_temp>>10; \
y = y*_temp>>10; \
} while(0)
// trigonometric function table (1024 = 1.0) - reserve 91 values
// static const int16_t sin_table[91] = {
// 0, 18, 36, 54, 71, 89, 107, 125, 143, 160, 178, 195, 213, 230, 248, 265, 282, 299, 316, 333, 350, 367, 384, 400, 416, 433, 449, 465, 481, 496, 512, 527, 542, 557, 572, 587, 601, 615, 629, 643, 657, 670, 683, 696, 709, 721, 733, 745, 757, 768, 779, 790, 801, 811, 821, 831, 841, 850, 859, 868, 876, 884, 892, 900, 907, 914, 921, 927, 933, 939, 945, 950, 955, 960, 964, 968, 972, 975, 978, 981, 984, 986, 988, 990, 991, 992, 993, 994, 994, 995, 995
// };
// static const int16_t cos_table[91] = {
// 1024, 1023, 1023, 1022, 1021, 1019, 1017, 1014, 1011, 1007, 1003, 998, 993, 987, 981, 974, 967, 959, 951, 942, 933, 923, 913, 902, 891, 879, 867, 854, 841, 827, 813, 798, 783, 767, 751, 734, 717, 699, 681, 662, 643, 623, 603, 582, 561, 539, 517, 494, 471, 447, 423, 398, 373, 347, 321, 294, 267, 239, 211, 182, 153, 123, 93, 62, 31, 0, -31, -62, -93, -123, -153, -182, -211, -239, -267, -294, -321, -347, -373, -398, -423, -447, -471, -494, -517, -539, -561, -582, -603, -623, -643
// };
static uint32_t pixel_buffer[DONUT_SIZE * DONUT_SIZE];
static signed char z_buffer[DONUT_SIZE * DONUT_SIZE];
static inline void fast_pixel_write(uint32_t color, int x, int y) {
if (likely(x >= 0 && x < DONUT_SIZE && y >= 0 && y < DONUT_SIZE)) {
int index = y * DONUT_SIZE + x;
pixel_buffer[index] = color;
}
}
static inline void fast_scaled_pixel_write(uint32_t color, int x, int y) {
if (likely(x >= 0 && x < DONUT_SIZE && y >= 0 && y < DONUT_SIZE)) {
int scaled_x = x * scale_x;
int scaled_y = y * scale_y;
int base_index = scaled_y * DONUT_WIDTH + scaled_x;
int row_index = base_index;
donut_framebuffer_32[row_index/2] = color;
donut_framebuffer_32[row_index/2 + 1] = color;
donut_framebuffer_32[row_index/2 + 2] = color;
donut_framebuffer_32[row_index/2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index/2] = color;
donut_framebuffer_32[row_index/2 + 1] = color;
donut_framebuffer_32[row_index/2 + 2] = color;
donut_framebuffer_32[row_index/2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index/2] = color;
donut_framebuffer_32[row_index/2 + 1] = color;
donut_framebuffer_32[row_index/2 + 2] = color;
donut_framebuffer_32[row_index/2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index/2] = color;
donut_framebuffer_32[row_index/2 + 1] = color;
donut_framebuffer_32[row_index/2 + 2] = color;
donut_framebuffer_32[row_index/2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index/2] = color;
donut_framebuffer_32[row_index/2 + 1] = color;
donut_framebuffer_32[row_index/2 + 2] = color;
donut_framebuffer_32[row_index/2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index/2] = color;
donut_framebuffer_32[row_index/2 + 1] = color;
donut_framebuffer_32[row_index/2 + 2] = color;
donut_framebuffer_32[row_index/2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index/2] = color;
donut_framebuffer_32[row_index/2 + 1] = color;
donut_framebuffer_32[row_index/2 + 2] = color;
donut_framebuffer_32[row_index/2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index/2] = color;
donut_framebuffer_32[row_index/2 + 1] = color;
donut_framebuffer_32[row_index/2 + 2] = color;
donut_framebuffer_32[row_index/2 + 3] = color;
}
}
void donut() {
register int sA = 1024, cA = 0, sB = 1024, cB = 0;
const int R1 = 1, R2 = 1024, K2 = 4096*1024;
const int screen_center_x = DONUT_SIZE/2, screen_center_y = DONUT_SIZE/2;
const int scale_x_val = 12, scale_y_val = 12;
while(1) {
// clean buffer
uint32_t *pixel_ptr = (uint32_t*)pixel_buffer;
uint32_t *z_ptr = (uint32_t*)z_buffer;
uint32_t *fb_ptr = (uint32_t*)donut_framebuffer_32;
// clean zero
for (int i = 0; i < (DONUT_SIZE*DONUT_SIZE)/2; i++) {
pixel_ptr[i] = 0;
}
// init z-buffer
for (int i = 0; i < (DONUT_SIZE*DONUT_SIZE)/4; i++) {
z_ptr[i] = 0x7F7F7F7F; // 127 in each byte
}
// clean zero
for (int i = 0; i < (DONUT_WIDTH*DONUT_HEIGHT)/2; i++) {
fb_ptr[i] = 0;
}
int sj = 0, cj = 1024;
for (int j = 0; j < 90; j++) {
int si = 0, ci = 1024;
for (int i = 0; i < DONUT_SIZE*DONUT_SIZE; i++) {
int x0 = R1*cj + R2;
int x1 = ci*x0 >> 10;
int x2 = cA*sj >> 10;
int x3 = si*x0 >> 10;
int x4 = R1*x2 - (sA*x3 >> 10);
int x5 = sA*sj >> 10;
int x6 = K2 + R1*1024*x5 + cA*x3;
int x7 = cj*si >> 10;
int x = screen_center_x + (scale_x_val*(cB*x1 - sB*x4)) / x6;
int y = screen_center_y + (scale_y_val*(cB*x4 + sB*x1)) / x6;
int N = (((-cA*x7 - cB*((-sA*x7>>10) + x2) - ci*(cj*sB >> 10)) >> 10) - x5) >> 7;
if (likely(y > 0 && y < DONUT_SIZE && x > 0 && x < DONUT_SIZE)) {
int o = x + DONUT_SIZE * y;
signed char zz = (x6-K2)>>15;
if (likely(zz < z_buffer[o])) {
z_buffer[o] = zz;
uint32_t color = gray_colors[N > 0 ? N : 0];
pixel_buffer[o] = color;
}
}
R_OPT(5, 8, ci, si);
}
R_OPT(9, 7, cj, sj);
}
R_OPT(5, 7, cA, sA);
R_OPT(5, 8, cB, sB);
for (int y = 0; y < DONUT_SIZE; y++) {
for (int x = 0; x < DONUT_SIZE; x++) {
int index = x + DONUT_SIZE * y;
uint32_t color = pixel_buffer[index];
if (likely(color != 0)) {
fast_scaled_pixel_write(color, x, y);
}
}
}
lcd_fill_image(0, 0, DONUT_WIDTH, DONUT_HEIGHT, donut_framebuffer_32);
}
}
void donut_test(int argc, char **argv) {
(void) argc;
(void) argv;
printf("donut test\n");
donut();
}
-96
View File
@@ -1,96 +0,0 @@
#include <firmware.h>
#include <rs_printf.h>
#include <rs_tim.h>
#include <rs_i2c.h>
#include <pcf8563b.h>
uint8_t pcf8563b_bin2bcd(uint8_t val) {
uint8_t bcdhigh = 0;
while (val >= 10) {
++bcdhigh;
val -= 10;
}
return ((uint8_t)(bcdhigh << 4) | val);
}
uint8_t pcf8563b_bcd2bin(uint8_t val,uint8_t reg_width)
{
uint8_t res = 0;
res = (val & (reg_width & 0xF0)) >> 4;
res = res * 10 + (val & (reg_width & 0x0F));
return res;
}
void pcf8563b_wr_reg(PCF8563B_info_t *info) {
uint8_t wr_data[7] = {0};
*wr_data = pcf8563b_bin2bcd(info->time.second);
*(wr_data + 1) = pcf8563b_bin2bcd(info->time.minute);
*(wr_data + 2) = pcf8563b_bin2bcd(info->time.hour);
*(wr_data + 3) = pcf8563b_bin2bcd(info->date.day);
*(wr_data + 4) = pcf8563b_bin2bcd(info->date.weekday);
*(wr_data + 5) = pcf8563b_bin2bcd(info->date.month);
*(wr_data + 6) = pcf8563b_bin2bcd(info->date.year);
i2c0_wr_nbyte(PCF8563B_DEV_ADDR, PCF8563B_SECOND_REG, I2C_DEV_ADDR_8BIT, 7, wr_data);
}
PCF8563B_info_t pcf8563b_rd_reg() {
uint8_t rd_data[7] = {0};
PCF8563B_info_t info = {0};
i2c0_rd_nbyte(PCF8563B_DEV_ADDR, PCF8563B_SECOND_REG, I2C_DEV_ADDR_8BIT, 7, rd_data);
info.time.second = pcf8563b_bcd2bin(rd_data[0], SECOND_MINUTE_REG_WIDTH);
info.time.minute = pcf8563b_bcd2bin(rd_data[1], SECOND_MINUTE_REG_WIDTH);
info.time.hour = pcf8563b_bcd2bin(rd_data[2], HOUR_DAY_REG_WIDTH);
info.date.day = pcf8563b_bcd2bin(rd_data[3], HOUR_DAY_REG_WIDTH);
info.date.weekday = pcf8563b_bcd2bin(rd_data[4], WEEKDAY_REG_WIDTH);
info.date.month = pcf8563b_bcd2bin(rd_data[5], MONTH_REG_WIDTH);
info.date.year = pcf8563b_bcd2bin(rd_data[6], YEAR_REG_WIDTH);
return info;
}
void pcf8563b_test(int argc, char **argv) {
(void) argc;
(void) argv;
printf("PCF8563B test\n");
PCF8563B_info_t init1_info = {
.time.second = 51,
.time.minute = 30,
.time.hour = 18,
.date.weekday = 3,
.date.day = 16,
.date.month = 9,
.date.year = 25
};
pcf8563b_wr_reg(&init1_info);
PCF8563B_info_t rd_info = {0};
for(int i = 0; i < 6; ++i) {
rd_info = pcf8563b_rd_reg();
printf("[PCF8563B] %d-%d-%d %d %d:%d:%d\n", rd_info.date.year, rd_info.date.month,
rd_info.date.day, rd_info.date.weekday,
rd_info.time.hour, rd_info.time.minute,
rd_info.time.second);
delay_ms(1000);
}
PCF8563B_info_t init2_info = {
.time.second = 23,
.time.minute = 22,
.time.hour = 12,
.date.weekday = 1,
.date.day = 19,
.date.month = 8,
.date.year = 24
};
pcf8563b_wr_reg(&init2_info);
for(int i = 0; i < 6; ++i) {
rd_info = pcf8563b_rd_reg();
printf("[PCF8563B] %d-%d-%d %d %d:%d:%d\n", rd_info.date.year, rd_info.date.month,
rd_info.date.day, rd_info.date.weekday,
rd_info.time.hour, rd_info.time.minute,
rd_info.time.second);
delay_ms(1000);
}
printf("PCF8563B test done\n");
}
-38
View File
@@ -1,38 +0,0 @@
#include <firmware.h>
#include <rs_printf.h>
#include <rs_spisd.h>
#include <rs_lcd.h>
#include <rs_dma.h>
#include <rs_qspi.h>
#include <video_player.h>
static VideoHeader_t video_header_parse(uint32_t addr) {
VideoHeader_t videoHeader;
spisd_mem_read((uint8_t *)&videoHeader, 1, sizeof(VideoHeader_t), addr);
printf("================================\n");
printf(" video bin file info \n");
printf("width: %d\n", videoHeader.width);
printf("height: %d\n", videoHeader.height);
printf("frame count: %d\n", videoHeader.frame_count);
printf("================================\n");
return videoHeader;
}
void video_show(uint32_t addr) {
VideoHeader_t videoHeader = video_header_parse(addr);
uint32_t* ptr = (uint32_t*)(addr + 16);
uint32_t delta = videoHeader.width * videoHeader.height / 2;
printf("addr: %x\n", addr);
for(uint32_t i = 0; i < videoHeader.frame_count; ++i) {
// lcd_addr_set(0, 0, 239, 134); // 240 - 1, 135 - 1
// lcd_dc_set;
// qspi0_dma_xfer(ptr, delta);
lcd_fill_image(0, 0, videoHeader.width, videoHeader.height, ptr);
ptr += delta;
}
}
-364
View File
@@ -1,364 +0,0 @@
#include <stdbool.h>
#include <rs_printf.h>
#include <rs_string.h>
#include <rs_qspi.h>
// #include <rs_spisd.h>
// #include <rs_dma.h>
static void norflash_spi_wr_en() {
uint32_t data[] = {0};
qspi0_wr((uint32_t)1, (uint32_t)1, (uint32_t)0x06000000,
(uint32_t)0, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)0, (uint32_t)1, (uint32_t)2,
data);
}
static void norflash_qpi_wr_en() {
uint32_t data[] = {0};
qspi0_wr((uint32_t)3, (uint32_t)1, (uint32_t)0x06000000,
(uint32_t)0, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)0, (uint32_t)1, (uint32_t)2,
data);
}
static void norflash_spi_wr_data(uint32_t* data, uint32_t len) {
printf("len: %d\n", len);
qspi0_wr((uint32_t)1, (uint32_t)1, (uint32_t)0x02000000,
(uint32_t)1, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)1, len, (uint32_t)4,
data);
}
static void norflash_qspi_wr_data(uint32_t* data, uint32_t len) {
printf("len: %d\n", len);
qspi0_wr((uint32_t)1, (uint32_t)1, (uint32_t)0x32000000,
(uint32_t)1, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)3, len, (uint32_t)4,
data);
}
static void norflash_qpi_wr_data(uint32_t* data, uint32_t len) {
printf("len: %d\n", len);
qspi0_wr((uint32_t)3, (uint32_t)1, (uint32_t)0x02000000,
(uint32_t)3, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)3, len, (uint32_t)4,
data);
}
static void norflash_spi_rd_data(uint32_t len) {
uint32_t data[64] = {0};
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x03000000,
(uint32_t)1, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)1, len, (uint32_t)4,
data);
printf("rd: ");
for(uint32_t i = 0; i < len; ++i) printf(" %x", data[i]);
printf("\n");
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x0B000000,
(uint32_t)1, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)8,
(uint32_t)1, len, (uint32_t)4,
data);
printf("rd: ");
for(uint32_t i = 0; i < len; ++i) printf(" %x", data[i]);
printf("\n");
}
static void norflash_dspi_rd_data(uint32_t len) {
printf("len: %d", len);
uint32_t data[64] = {0};
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x3B000000,
(uint32_t)1, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)8,
(uint32_t)2, len, (uint32_t)4,
data);
printf("rd: ");
for(uint32_t i = 0; i < len; ++i) printf(" %x", data[i]);
printf("\n");
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0xBB000000,
(uint32_t)2, (uint32_t)4, (uint32_t)0x000000F0,
(uint32_t)0,
(uint32_t)2, len, (uint32_t)4,
data);
printf("rd: ");
for(uint32_t i = 0; i < len; ++i) printf(" %x", data[i]);
printf("\n");
}
static void norflash_qspi_rd_data(uint32_t len) {
printf("len: %d", len);
uint32_t data[64] = {0};
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x6B000000,
(uint32_t)1, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)8,
(uint32_t)3, len, (uint32_t)4,
data);
printf("rd: ");
for(uint32_t i = 0; i < len; ++i) printf(" %x", data[i]);
printf("\n");
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0xEB000000,
(uint32_t)3, (uint32_t)4, (uint32_t)0x000000F0,
(uint32_t)4,
(uint32_t)3, len, (uint32_t)4,
data);
printf("rd: ");
for(uint32_t i = 0; i < len; ++i) printf(" %x", data[i]);
printf("\n");
}
static void norflash_qpi_rd_data(uint32_t len) {
printf("len: %d", len);
uint32_t data[64] = {0};
qspi0_rd((uint32_t)3, (uint32_t)1, (uint32_t)0x0B000000,
(uint32_t)3, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)2,
(uint32_t)3, len, (uint32_t)4,
data);
printf("rd: ");
for(uint32_t i = 0; i < len; ++i) printf(" %x", data[i]);
printf("\n");
qspi0_rd((uint32_t)3, (uint32_t)1, (uint32_t)0xEB000000,
(uint32_t)3, (uint32_t)4, (uint32_t)0x000000F0,
(uint32_t)4,
(uint32_t)3, len, (uint32_t)4,
data);
printf("rd: ");
for(uint32_t i = 0; i < len; ++i) printf(" %x", data[i]);
printf("\n");
}
static void norflash_spi_id() {
// manu/dev id
uint32_t data[2];
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x90000000,
(uint32_t)1, (uint32_t)3, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)1, (uint32_t)1, (uint32_t)2,
data);
printf("manu/dev id: %x\n", data[0]);
// uni id
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x4B000000,
(uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)32,
(uint32_t)1, (uint32_t)2, (uint32_t)4,
data);
printf("uni id: %x %x\n", data[0], data[1]);
// jedec id
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x9F000000,
(uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)1, (uint32_t)1, (uint32_t)3,
data);
printf("mem/cap id: %x\n", data[0]);
}
static void norflash_dspi_id() {
// manu/dev id
uint32_t data[2];
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x92000000,
(uint32_t)2, (uint32_t)4, (uint32_t)0x000000F0,
(uint32_t)0,
(uint32_t)2, (uint32_t)1, (uint32_t)2,
data);
printf("manu/dev id: %x\n", data[0]);
}
static void norflash_qspi_id() {
uint32_t data[2];
// manu/dev id
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x94000000,
(uint32_t)3, (uint32_t)4, (uint32_t)0x000000F0,
(uint32_t)4,
(uint32_t)3, (uint32_t)1, (uint32_t)2,
data);
printf("manu/dev id: %x\n", data[0]);
}
static void norflash_qpi_id() {
uint32_t data[2];
// jedec id
qspi0_rd((uint32_t)3, (uint32_t)1, (uint32_t)0x9F000000,
(uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)3, (uint32_t)1, (uint32_t)3,
data);
printf("mem/cap id: %x\n", data[0]);
}
static void norflash_spi_status() {
uint32_t data[2];
uint32_t cmd[] = {(uint32_t)0x05000000, (uint32_t)0x35000000, (uint32_t)0x15000000,};
for(int i = 0; i < 3; ++i) {
qspi0_rd((uint32_t)1, (uint32_t)1, cmd[i],
(uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)1, (uint32_t)1, (uint32_t)1,
data);
printf("status reg %d: %x\n", i, data[0]);
}
}
static void norflash_qpi_status() {
uint32_t data[2];
uint32_t cmd[] = {(uint32_t)0x05000000, (uint32_t)0x35000000, (uint32_t)0x15000000,};
for(int i = 0; i < 3; ++i) {
qspi0_rd((uint32_t)3, (uint32_t)1, cmd[i],
(uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)3, (uint32_t)1, (uint32_t)1,
data);
printf("status reg %d: %x\n", i, data[0]);
}
// qpis0_qpi_rd_data(val_list, dumlen=0, datalen=1); // 4-4-4(05/35/15h)
}
static void norflash_enter_quad_mode() {
uint32_t data[] = {0};
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x35000000,
(uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)1, (uint32_t)1, (uint32_t)1,
data);
// set QE=1 in status reg 2 for QSPI/QPI
data[0] = (data[0] | 0x02) << 24;
printf("data[0]: %x\n", data[0]);
norflash_spi_wr_en();
qspi0_wr((uint32_t)1, (uint32_t)1, (uint32_t)0x31000000,
(uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)1, (uint32_t)1, (uint32_t)1,
data);
norflash_spi_status();
}
static void norflash_enter_qpi_mode() {
uint32_t data[] = {0};
norflash_spi_wr_en();
qspi0_wr((uint32_t)1, (uint32_t)1, (uint32_t)0x38000000,
(uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)0, (uint32_t)1, (uint32_t)1,
data);
}
// need to assure in qpi mode before
static void norflash_quit_qpi_mode() {
uint32_t data[] = {0};
norflash_qpi_wr_en();
qspi0_wr((uint32_t)3, (uint32_t)1, (uint32_t)0xFF000000,
(uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)0,
(uint32_t)0, (uint32_t)1, (uint32_t)1,
data);
}
static void norflash_spi_test() {
printf("\nnorflash spi test\n");
uint32_t wr_data[] = {0x23456788, 0x00FFEE30, 0x418461AB, 0xC252DE21, 0x00550022, 0x00002266};
norflash_spi_id();
norflash_spi_status();
norflash_spi_wr_en();
norflash_spi_wr_data(wr_data, sizeof(wr_data)/sizeof(wr_data[0]));
norflash_spi_rd_data(sizeof(wr_data)/sizeof(wr_data[0]));
}
static void norflash_dspi_test() {
printf("\nnorflash dspi test\n");
uint32_t wr_data[] = {0x23456788, 0x00FFEE30, 0x418461AB, 0xC252DE21, 0x00550022, 0x00002266};
norflash_dspi_id();
norflash_spi_wr_en();
norflash_spi_wr_data(wr_data, sizeof(wr_data)/sizeof(wr_data[0]));
// rd
norflash_dspi_rd_data(sizeof(wr_data)/sizeof(wr_data[0]));
}
static void norflash_qspi_test() {
printf("\nnorflash qspi test\n");
uint32_t wr_data[] = {0x23456788, 0x00FFEE30, 0x418461AB, 0xC252DE21, 0x00550022, 0x00002266};
norflash_enter_quad_mode();
norflash_qspi_id();
norflash_spi_wr_en();
norflash_qspi_wr_data(wr_data, sizeof(wr_data)/sizeof(wr_data[0]));
// rd:
norflash_qspi_rd_data(sizeof(wr_data)/sizeof(wr_data[0]));
}
static void norflash_qpi_test() {
printf("\nnorflash qpi test\n");
uint32_t wr_data[] = {0x23456788, 0x00FFEE30, 0x418461AB, 0xC252DE21, 0x00550022, 0x00002266};
norflash_enter_quad_mode();
norflash_enter_qpi_mode();
norflash_qpi_id();
norflash_qpi_status();
norflash_qpi_wr_en();
norflash_qpi_wr_data(wr_data, sizeof(wr_data)/sizeof(wr_data[0]));
// rd
norflash_qpi_rd_data(sizeof(wr_data)/sizeof(wr_data[0]));
norflash_quit_qpi_mode();
}
void ip_norflash_test(int argc, char **argv) {
(void) argc;
(void) argv;
printf("[NATV IP] qspi nor flash test\n");
QSPI0_InitStruct_t qspi0 = {
(uint32_t)0,
(uint32_t)0b0001,
(uint32_t)0,
(uint32_t)250,
(uint32_t)140,
(uint32_t)24,
(uint32_t)10,
(uint32_t)0,
};
qspi0_init(qspi0);
norflash_spi_test();
norflash_dspi_test();
norflash_qspi_test();
norflash_qpi_test();
}
-104
View File
@@ -1,104 +0,0 @@
#include <stdbool.h>
#include <libdef.h>
#include <rs_printf.h>
#include <rs_string.h>
#include <rs_spisd.h>
#include <rs_dma.h>
#include <wav_audio.h>
static void printfln(char *buff, uint32_t len) {
for(uint32_t i = 0; i < len; ++i) printf("%c", buff[i]);
printf("\n");
}
static void parseLISTChunk(WAVHeader_t *header, uint32_t addr) {
const char *info_tag[] = {"IART", "ICOP", "ICRD", "IGNR", "INAM", "IPRD", "IPRT", "ISFT", "ISRC", "ICMT", "ISBJ", "ITCH"};
char info_tag_len = sizeof(info_tag) / sizeof(info_tag[0]);
ChunkHeader_t chunkHeader;
uint32_t info_num = 0;
// "LIST"
spisd_mem_read((uint8_t *)&chunkHeader, 1, sizeof(ChunkHeader_t), addr);
// printf("ChunkID: %.4s\n", chunkHeader.ChunkID);
uint32_t list_end = addr + chunkHeader.ChunkSize;
addr += sizeof(ChunkHeader_t);
spisd_mem_read((uint8_t *)&chunkHeader, 1, sizeof(ChunkHeader_t) - 4, addr);
if (memcmp(chunkHeader.ChunkID, "INFO", 4) == 0) {
addr += 4;
while (addr < list_end) {
spisd_mem_read((uint8_t *)&chunkHeader, 1, sizeof(ChunkHeader_t), addr);
bool is_find = false;
for(int i = 0; i < info_tag_len; ++i) {
if (memcmp(chunkHeader.ChunkID, info_tag[i], 4) == 0) {
// printf("tag %.4s\n", chunkHeader.ChunkID);
// printf("ChunkID: %.4s\n", chunkHeader.ChunkID);
// printf("addr: %x\n", addr);
is_find = true;
spisd_mem_read((uint8_t *)&header->list[info_num++], 1, chunkHeader.ChunkSize + 8, addr);
addr += chunkHeader.ChunkSize + 8;
}
}
if(!is_find) addr += 1; // for align the exten data
}
}
header->info_num = info_num;
}
WAVFile_t wav_audio_parse(uint32_t start_addr) {
WAVHeader_t header;
ChunkHeader_t chunkHeader;
WAVFile_t res = {0, 0};
spisd_mem_read((uint8_t *)&header.riff, 1, sizeof(RIFFChunk_t), start_addr);
start_addr += sizeof(RIFFChunk_t);
if (memcmp(header.riff.ChunkID, "RIFF", 4) != 0 || memcmp(header.riff.Format, "WAVE", 4) != 0) {
return res;
}
while(1) {
spisd_mem_read((uint8_t *)&chunkHeader, 1, sizeof(ChunkHeader_t), start_addr);
// printf("start addr: %x\n", start_addr);
if (memcmp(chunkHeader.ChunkID, "fmt ", 4) == 0) {
spisd_mem_read((uint8_t *)&header.fmt, 1, sizeof(FMTChunk_t), start_addr);
start_addr += sizeof(FMTChunk_t);
} else if(memcmp(chunkHeader.ChunkID, "LIST", 4) == 0) {
parseLISTChunk(&header, start_addr);
start_addr += chunkHeader.ChunkSize + sizeof(ChunkHeader_t);
printf("start addr: %x\n", start_addr);
} else if(memcmp(chunkHeader.ChunkID, "data", 4) == 0) {
spisd_mem_read((uint8_t *)&header.data, 1, sizeof(DATAChunk_t), start_addr);
start_addr += sizeof(DATAChunk_t);
break;
}
}
// RIFF
printf("File size: %d bytes(~%d MiB)\n", header.riff.ChunkSize + 8, (header.riff.ChunkSize + 8) / 1024 / 1024);
printf("Format: %.4s\n", header.riff.Format);
// FMT
printf("AudioFormat: %d(PCM)\n", header.fmt.AudioFormat); // TODO: need to assign by looking up table
printf("NumChannels: %d channels\n", header.fmt.NumChannels);
printf("SampleRate: %d kHz\n", header.fmt.SampleRate);
printf("ByteRate: %d bps\n", header.fmt.ByteRate);
printf("BlockAlign: %d\n", header.fmt.BlockAlign);
printf("BitsPerSample: %d bits\n", header.fmt.BitsPerSample);
// LIST(optional)
for(int i = 0; i < header.info_num; ++i) {
printf("%.4s: ", header.list[i].ChunkID);
printfln(header.list[i].ChunkData, header.list[i].ChunkSize);
}
// data
printf("Data size: %d bytes(~%d MiB)\n", header.data.Subchunk2Size, (header.data.Subchunk2Size) / 1024 / 1024);
res.addr = start_addr;
res.size = header.data.Subchunk2Size / 4;
return res;
}
@@ -18,7 +18,7 @@ Original Author: Shay Gal-on
#include "coremark.h"
#include "core_portme.h"
#include <stdint.h>
#include <rs_tim.h>
#include <retrosoc/hal/timer.h>
#if VALIDATION_RUN
volatile ee_s32 seed1_volatile = 0x3415;
@@ -43,11 +43,10 @@ volatile ee_s32 seed5_volatile = 0;
cpu clock cycles performance counter etc. Sample implementation for standard
time.h and windows.h definitions included.
*/
CORETIMETYPE
barebones_clock()
{
static CORETIMETYPE barebones_clock(void) {
return tim1_get_value();
// #error // "You must implement a method to measure time in barebones_clock()! This function should return current time.\n"
// #error // "You must implement a method to measure time in barebones_clock()! This function
// should return current time.\n"
}
/* Define : TIMER_RES_DIVIDER
Divider to trade off timer resolution and total time that can be
@@ -75,9 +74,7 @@ static CORETIMETYPE start_time_val, stop_time_val;
example code) or zeroing some system parameters - e.g. setting the cpu clocks
cycles to 0.
*/
void
start_time(void)
{
void start_time(void) {
GETMYTIME(&start_time_val);
}
/* Function : stop_time
@@ -88,9 +85,7 @@ start_time(void)
example code) or other system parameters - e.g. reading the current value of
cpu cycles counter.
*/
void
stop_time(void)
{
void stop_time(void) {
GETMYTIME(&stop_time_val);
}
/* Function : get_time
@@ -103,10 +98,8 @@ stop_time(void)
controlled by <TIMER_RES_DIVIDER>
*/
CORE_TICKS
get_time(void)
{
CORE_TICKS elapsed
= (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
get_time(void) {
CORE_TICKS elapsed = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
return elapsed;
}
/* Function : time_in_secs
@@ -116,9 +109,7 @@ get_time(void)
floating point. Default implementation implemented by the EE_TICKS_PER_SEC
macro above.
*/
secs_ret
time_in_secs(CORE_TICKS ticks)
{
secs_ret time_in_secs(CORE_TICKS ticks) {
secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
return retval;
}
@@ -129,23 +120,19 @@ ee_u32 default_num_contexts = 1;
Target specific initialization code
Test for some common mistakes.
*/
void
portable_init(core_portable *p, int *argc, char *argv[])
{
// #error "Call board initialization routines in portable init (if needed), in particular initialize UART!\n"
void portable_init(core_portable *p, int *argc, char *argv[]) {
// #error "Call board initialization routines in portable init (if needed), in particular
// initialize UART!\n"
(void)argc; // prevent unused warning
(void)argv; // prevent unused warning
tim1_init();
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *))
{
ee_printf(
"ERROR! Please define ee_ptr_int to a type that holds a "
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) {
ee_printf("ERROR! Please define ee_ptr_int to a type that holds a "
"pointer!\n");
}
if (sizeof(ee_u32) != 4)
{
if (sizeof(ee_u32) != 4) {
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
}
p->portable_id = 1;
@@ -153,8 +140,6 @@ portable_init(core_portable *p, int *argc, char *argv[])
/* Function : portable_fini
Target specific final code
*/
void
portable_fini(core_portable *p)
{
void portable_fini(core_portable *p) {
p->portable_id = 0;
}
@@ -76,8 +76,7 @@ int core_main(void);
#endif
#endif
#ifndef COMPILER_FLAGS
#define COMPILER_FLAGS \
"-o3" /* "Please put compiler flags here (e.g. -o3)" */
#define COMPILER_FLAGS "-o3" /* "Please put compiler flags here (e.g. -o3)" */
#endif
#ifndef MEM_LOCATION
#define MEM_LOCATION "STACK"
@@ -192,8 +191,7 @@ typedef ee_u32 CORE_TICKS;
*/
extern ee_u32 default_num_contexts;
typedef struct CORE_PORTABLE_S
{
typedef struct CORE_PORTABLE_S {
ee_u8 portable_id;
} core_portable;
@@ -201,8 +199,7 @@ typedef struct CORE_PORTABLE_S
void portable_init(core_portable *p, int *argc, char *argv[]);
void portable_fini(core_portable *p);
#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) \
&& !defined(VALIDATION_RUN)
#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN)
#if (TOTAL_DATA_SIZE == 1200)
#define PROFILE_RUN 1
#elif (TOTAL_DATA_SIZE == 2000)
+9
View File
@@ -0,0 +1,9 @@
APP_SRCS += $(ROOT_PATH)/app/coremark/coremark-main/core_main.c
APP_SRCS += $(ROOT_PATH)/app/coremark/coremark-main/core_list_join.c
APP_SRCS += $(ROOT_PATH)/app/coremark/coremark-main/core_matrix.c
APP_SRCS += $(ROOT_PATH)/app/coremark/coremark-main/core_state.c
APP_SRCS += $(ROOT_PATH)/app/coremark/coremark-main/core_util.c
APP_SRCS += $(ROOT_PATH)/app/benchmark/coremark/core_portme.c
APP_INC_DIRS += $(ROOT_PATH)/app/coremark/coremark-main
APP_INC_DIRS += $(ROOT_PATH)/app/benchmark/coremark
@@ -0,0 +1,9 @@
#ifndef RETROSOC_BOARD_AT24CXX_H
#define RETROSOC_BOARD_AT24CXX_H
#define I2C_TEST_NUM 24
#define AT24C64_DEV_ADDR 0x50
void at24cxx_test(void);
#endif
@@ -0,0 +1,8 @@
#ifndef RETROSOC_BOARD_ES8388_H
#define RETROSOC_BOARD_ES8388_H
#define ES8388_DEV_ADDR 0x10
void es8388_init(void);
#endif
@@ -0,0 +1,50 @@
#ifndef RETROSOC_BOARD_PCF8563B_H
#define RETROSOC_BOARD_PCF8563B_H
#include <stdint.h>
#define PCF8563B_DEV_ADDR 0x51
#define PCF8563B_CTL_STATUS1 ((uint8_t)0x00)
#define PCF8563B_CTL_STATUS2 ((uint8_t)0x01)
#define PCF8563B_SECOND_REG ((uint8_t)0x02)
#define PCF8563B_MINUTE_REG ((uint8_t)0x03)
#define PCF8563B_HOUR_REG ((uint8_t)0x04)
#define PCF8563B_DAY_REG ((uint8_t)0x05)
#define PCF8563B_WEEKDAY_REG ((uint8_t)0x06)
#define PCF8563B_MONTH_REG ((uint8_t)0x07)
#define PCF8563B_YEAR_REG ((uint8_t)0x08)
#define SECOND_MINUTE_REG_WIDTH ((uint8_t)0x7F)
#define HOUR_DAY_REG_WIDTH ((uint8_t)0x3F)
#define WEEKDAY_REG_WIDTH ((uint8_t)0x07)
#define MONTH_REG_WIDTH ((uint8_t)0x1F)
#define YEAR_REG_WIDTH ((uint8_t)0xFF)
#define BCD_Century ((uint8_t)0x80)
typedef struct {
struct {
uint8_t second;
uint8_t minute;
uint8_t hour;
} time;
struct {
uint8_t weekday;
uint8_t day;
uint8_t month;
uint8_t year;
} date;
} PCF8563B_info_t;
// helper functions
uint8_t pcf8563b_bcd2bin(uint8_t val, uint8_t reg_width);
uint8_t pcf8563b_bin2bcd(uint8_t val);
void pcf8563b_wr_reg(PCF8563B_info_t *info);
PCF8563B_info_t pcf8563b_rd_reg(void);
void pcf8563b_test(int argc, char **argv);
#endif
@@ -0,0 +1,6 @@
#ifndef RETROSOC_BOARD_W25Q128JVXIM_H
#define RETROSOC_BOARD_W25Q128JVXIM_H
void ip_norflash_test(int argc, char **argv);
#endif
+36
View File
@@ -0,0 +1,36 @@
#include <retrosoc/core/soc.h>
#include <retrosoc/lib/printf.h>
#include <retrosoc/hal/i2c.h>
#include <retrosoc/board/at24cxx.h>
void at24cxx_test(void) {
printf("AT24C64 wr/rd test\n");
// prepare ref data
uint8_t ref_data[I2C_TEST_NUM], rd_data[I2C_TEST_NUM];
for (uint8_t i = 0U; i < I2C_TEST_NUM; ++i) {
ref_data[i] = i;
}
// write AT24C64
if (rs_i2c0_write(AT24C64_DEV_ADDR, 0U, RS_I2C_DEVICE_ADDRESS_16BIT, I2C_TEST_NUM, ref_data,
RS_TIMEOUT_DEFAULT) != RS_OK) {
printf("AT24C64 write timed out\n");
return;
}
// read AT24C64
if (rs_i2c0_read(AT24C64_DEV_ADDR, 0U, RS_I2C_DEVICE_ADDRESS_16BIT, I2C_TEST_NUM, rd_data,
RS_TIMEOUT_DEFAULT) != RS_OK) {
printf("AT24C64 read timed out\n");
return;
}
// check data
for (uint8_t i = 0U; i < I2C_TEST_NUM; ++i) {
printf("recv: %d expt: %d\n", rd_data[i], i);
if (rd_data[i] != i)
printf("test fail\n");
}
(void)rs_i2c0_write(AT24C64_DEV_ADDR, 0U, RS_I2C_DEVICE_ADDRESS_16BIT, I2C_TEST_NUM, ref_data,
RS_TIMEOUT_DEFAULT);
printf("AT24C64 wr/rd test done\n");
}
@@ -1,12 +1,12 @@
#include <firmware.h>
#include <rs_printf.h>
#include <rs_i2c.h>
#include <es8388.h>
#include <retrosoc/core/soc.h>
#include <retrosoc/lib/printf.h>
#include <retrosoc/hal/i2c.h>
#include <retrosoc/board/es8388.h>
#define ES8388_PHONE_VOLUME 3
#define ES8388_SPEAK_VOLUME 3
uint8_t es8388_init_cfg[] = {
static const uint8_t es8388_init_cfg[] = {
(uint8_t)0, (uint8_t)0x80,
(uint8_t)0, (uint8_t)0x00,
(uint8_t)1, (uint8_t)0x58,
@@ -38,16 +38,25 @@ uint8_t es8388_init_cfg[] = {
(uint8_t)49, (uint8_t)ES8388_SPEAK_VOLUME,
};
void es8388_init() {
int init_cfg_len = sizeof(es8388_init_cfg)/sizeof(uint8_t);
printf("[ES8388] init cfg len: %d\n", init_cfg_len);
for(int i = 0; i < init_cfg_len; i += 2) {
i2c0_wr_nbyte(ES8388_DEV_ADDR, (uint16_t)es8388_init_cfg[i], I2C_DEV_ADDR_8BIT, 1, es8388_init_cfg + i + 1);
void es8388_init(void) {
const uint32_t init_cfg_len = sizeof(es8388_init_cfg) / sizeof(es8388_init_cfg[0]);
printf("[ES8388] init cfg len: %u\n", init_cfg_len);
for (uint32_t i = 0U; i < init_cfg_len; i += 2U) {
if (rs_i2c0_write(ES8388_DEV_ADDR, (uint16_t)es8388_init_cfg[i], RS_I2C_DEVICE_ADDRESS_8BIT,
1U, es8388_init_cfg + i + 1, RS_TIMEOUT_DEFAULT) != RS_OK) {
printf("[ES8388] write failed at register %d\n", es8388_init_cfg[i]);
return;
}
}
uint8_t rxdata[60] = {0};
i2c0_rd_nbyte(ES8388_DEV_ADDR, (uint16_t)0, I2C_DEV_ADDR_8BIT, 53, rxdata);
for(int i = 0; i < 53; ++i) {
if (rs_i2c0_read(ES8388_DEV_ADDR, 0U, RS_I2C_DEVICE_ADDRESS_8BIT, 53U, rxdata,
RS_TIMEOUT_DEFAULT) != RS_OK) {
printf("[ES8388] read failed\n");
return;
}
for (uint32_t i = 0U; i < 53U; ++i) {
printf("[ES8388] reg: %d val:%x\n", i, rxdata[i]);
}
}
+101
View File
@@ -0,0 +1,101 @@
#include <retrosoc/core/soc.h>
#include <retrosoc/lib/printf.h>
#include <retrosoc/hal/timer.h>
#include <retrosoc/hal/i2c.h>
#include <retrosoc/board/pcf8563b.h>
uint8_t pcf8563b_bin2bcd(uint8_t val) {
uint8_t bcdhigh = 0;
while (val >= 10) {
++bcdhigh;
val -= 10;
}
return ((uint8_t)(bcdhigh << 4) | val);
}
uint8_t pcf8563b_bcd2bin(uint8_t val, uint8_t reg_width) {
uint8_t res = 0;
res = (val & (reg_width & 0xF0)) >> 4;
res = res * 10 + (val & (reg_width & 0x0F));
return res;
}
void pcf8563b_wr_reg(PCF8563B_info_t *info) {
uint8_t wr_data[7] = {0};
if (info == NULL) {
return;
}
*wr_data = pcf8563b_bin2bcd(info->time.second);
*(wr_data + 1) = pcf8563b_bin2bcd(info->time.minute);
*(wr_data + 2) = pcf8563b_bin2bcd(info->time.hour);
*(wr_data + 3) = pcf8563b_bin2bcd(info->date.day);
*(wr_data + 4) = pcf8563b_bin2bcd(info->date.weekday);
*(wr_data + 5) = pcf8563b_bin2bcd(info->date.month);
*(wr_data + 6) = pcf8563b_bin2bcd(info->date.year);
if (rs_i2c0_write(PCF8563B_DEV_ADDR, PCF8563B_SECOND_REG, RS_I2C_DEVICE_ADDRESS_8BIT, 7U,
wr_data, RS_TIMEOUT_DEFAULT) != RS_OK) {
printf("[PCF8563B] write failed\n");
}
}
PCF8563B_info_t pcf8563b_rd_reg(void) {
uint8_t rd_data[7] = {0};
PCF8563B_info_t info = {0};
if (rs_i2c0_read(PCF8563B_DEV_ADDR, PCF8563B_SECOND_REG, RS_I2C_DEVICE_ADDRESS_8BIT, 7U,
rd_data, RS_TIMEOUT_DEFAULT) != RS_OK) {
printf("[PCF8563B] read failed\n");
return info;
}
info.time.second = pcf8563b_bcd2bin(rd_data[0], SECOND_MINUTE_REG_WIDTH);
info.time.minute = pcf8563b_bcd2bin(rd_data[1], SECOND_MINUTE_REG_WIDTH);
info.time.hour = pcf8563b_bcd2bin(rd_data[2], HOUR_DAY_REG_WIDTH);
info.date.day = pcf8563b_bcd2bin(rd_data[3], HOUR_DAY_REG_WIDTH);
info.date.weekday = pcf8563b_bcd2bin(rd_data[4], WEEKDAY_REG_WIDTH);
info.date.month = pcf8563b_bcd2bin(rd_data[5], MONTH_REG_WIDTH);
info.date.year = pcf8563b_bcd2bin(rd_data[6], YEAR_REG_WIDTH);
return info;
}
void pcf8563b_test(int argc, char **argv) {
(void)argc;
(void)argv;
printf("PCF8563B test\n");
PCF8563B_info_t init1_info = {.time.second = 51,
.time.minute = 30,
.time.hour = 18,
.date.weekday = 3,
.date.day = 16,
.date.month = 9,
.date.year = 25};
pcf8563b_wr_reg(&init1_info);
PCF8563B_info_t rd_info = {0};
for (int i = 0; i < 6; ++i) {
rd_info = pcf8563b_rd_reg();
printf("[PCF8563B] %d-%d-%d %d %d:%d:%d\n", rd_info.date.year, rd_info.date.month,
rd_info.date.day, rd_info.date.weekday, rd_info.time.hour, rd_info.time.minute,
rd_info.time.second);
delay_ms(1000);
}
PCF8563B_info_t init2_info = {.time.second = 23,
.time.minute = 22,
.time.hour = 12,
.date.weekday = 1,
.date.day = 19,
.date.month = 8,
.date.year = 24};
pcf8563b_wr_reg(&init2_info);
for (int i = 0; i < 6; ++i) {
rd_info = pcf8563b_rd_reg();
printf("[PCF8563B] %d-%d-%d %d %d:%d:%d\n", rd_info.date.year, rd_info.date.month,
rd_info.date.day, rd_info.date.weekday, rd_info.time.hour, rd_info.time.minute,
rd_info.time.second);
delay_ms(1000);
}
printf("PCF8563B test done\n");
}
+299
View File
@@ -0,0 +1,299 @@
#include <stdbool.h>
#include <retrosoc/lib/printf.h>
#include <retrosoc/lib/string.h>
#include <retrosoc/board/w25q128jvxim.h>
#include <retrosoc/hal/qspi.h>
// #include <retrosoc/hal/spisd.h>
// #include <retrosoc/hal/dma.h>
static void norflash_spi_wr_en(void) {
uint32_t data[] = {0};
qspi0_wr((uint32_t)1, (uint32_t)1, (uint32_t)0x06000000, (uint32_t)0, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)0, (uint32_t)1, (uint32_t)2, data);
}
static void norflash_qpi_wr_en(void) {
uint32_t data[] = {0};
qspi0_wr((uint32_t)3, (uint32_t)1, (uint32_t)0x06000000, (uint32_t)0, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)0, (uint32_t)1, (uint32_t)2, data);
}
static void norflash_spi_wr_data(uint32_t *data, uint32_t len) {
printf("len: %d\n", len);
qspi0_wr((uint32_t)1, (uint32_t)1, (uint32_t)0x02000000, (uint32_t)1, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)1, len, (uint32_t)4, data);
}
static void norflash_qspi_wr_data(uint32_t *data, uint32_t len) {
printf("len: %d\n", len);
qspi0_wr((uint32_t)1, (uint32_t)1, (uint32_t)0x32000000, (uint32_t)1, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)3, len, (uint32_t)4, data);
}
static void norflash_qpi_wr_data(uint32_t *data, uint32_t len) {
printf("len: %d\n", len);
qspi0_wr((uint32_t)3, (uint32_t)1, (uint32_t)0x02000000, (uint32_t)3, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)3, len, (uint32_t)4, data);
}
static void norflash_spi_rd_data(uint32_t len) {
uint32_t data[64] = {0};
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x03000000, (uint32_t)1, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)1, len, (uint32_t)4, data);
printf("rd: ");
for (uint32_t i = 0; i < len; ++i)
printf(" %x", data[i]);
printf("\n");
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x0B000000, (uint32_t)1, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)8, (uint32_t)1, len, (uint32_t)4, data);
printf("rd: ");
for (uint32_t i = 0; i < len; ++i)
printf(" %x", data[i]);
printf("\n");
}
static void norflash_dspi_rd_data(uint32_t len) {
printf("len: %d", len);
uint32_t data[64] = {0};
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x3B000000, (uint32_t)1, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)8, (uint32_t)2, len, (uint32_t)4, data);
printf("rd: ");
for (uint32_t i = 0; i < len; ++i)
printf(" %x", data[i]);
printf("\n");
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0xBB000000, (uint32_t)2, (uint32_t)4,
(uint32_t)0x000000F0, (uint32_t)0, (uint32_t)2, len, (uint32_t)4, data);
printf("rd: ");
for (uint32_t i = 0; i < len; ++i)
printf(" %x", data[i]);
printf("\n");
}
static void norflash_qspi_rd_data(uint32_t len) {
printf("len: %d", len);
uint32_t data[64] = {0};
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x6B000000, (uint32_t)1, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)8, (uint32_t)3, len, (uint32_t)4, data);
printf("rd: ");
for (uint32_t i = 0; i < len; ++i)
printf(" %x", data[i]);
printf("\n");
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0xEB000000, (uint32_t)3, (uint32_t)4,
(uint32_t)0x000000F0, (uint32_t)4, (uint32_t)3, len, (uint32_t)4, data);
printf("rd: ");
for (uint32_t i = 0; i < len; ++i)
printf(" %x", data[i]);
printf("\n");
}
static void norflash_qpi_rd_data(uint32_t len) {
printf("len: %d", len);
uint32_t data[64] = {0};
qspi0_rd((uint32_t)3, (uint32_t)1, (uint32_t)0x0B000000, (uint32_t)3, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)2, (uint32_t)3, len, (uint32_t)4, data);
printf("rd: ");
for (uint32_t i = 0; i < len; ++i)
printf(" %x", data[i]);
printf("\n");
qspi0_rd((uint32_t)3, (uint32_t)1, (uint32_t)0xEB000000, (uint32_t)3, (uint32_t)4,
(uint32_t)0x000000F0, (uint32_t)4, (uint32_t)3, len, (uint32_t)4, data);
printf("rd: ");
for (uint32_t i = 0; i < len; ++i)
printf(" %x", data[i]);
printf("\n");
}
static void norflash_spi_id(void) {
// manu/dev id
uint32_t data[2];
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x90000000, (uint32_t)1, (uint32_t)3,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)1, (uint32_t)1, (uint32_t)2, data);
printf("manu/dev id: %x\n", data[0]);
// uni id
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x4B000000, (uint32_t)0, (uint32_t)0,
(uint32_t)0x00000000, (uint32_t)32, (uint32_t)1, (uint32_t)2, (uint32_t)4, data);
printf("uni id: %x %x\n", data[0], data[1]);
// jedec id
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x9F000000, (uint32_t)0, (uint32_t)0,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)1, (uint32_t)1, (uint32_t)3, data);
printf("mem/cap id: %x\n", data[0]);
}
static void norflash_dspi_id(void) {
// manu/dev id
uint32_t data[2];
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x92000000, (uint32_t)2, (uint32_t)4,
(uint32_t)0x000000F0, (uint32_t)0, (uint32_t)2, (uint32_t)1, (uint32_t)2, data);
printf("manu/dev id: %x\n", data[0]);
}
static void norflash_qspi_id(void) {
uint32_t data[2];
// manu/dev id
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x94000000, (uint32_t)3, (uint32_t)4,
(uint32_t)0x000000F0, (uint32_t)4, (uint32_t)3, (uint32_t)1, (uint32_t)2, data);
printf("manu/dev id: %x\n", data[0]);
}
static void norflash_qpi_id(void) {
uint32_t data[2];
// jedec id
qspi0_rd((uint32_t)3, (uint32_t)1, (uint32_t)0x9F000000, (uint32_t)0, (uint32_t)0,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)3, (uint32_t)1, (uint32_t)3, data);
printf("mem/cap id: %x\n", data[0]);
}
static void norflash_spi_status(void) {
uint32_t data[2];
uint32_t cmd[] = {
(uint32_t)0x05000000,
(uint32_t)0x35000000,
(uint32_t)0x15000000,
};
for (int i = 0; i < 3; ++i) {
qspi0_rd((uint32_t)1, (uint32_t)1, cmd[i], (uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)0, (uint32_t)1, (uint32_t)1, (uint32_t)1, data);
printf("status reg %d: %x\n", i, data[0]);
}
}
static void norflash_qpi_status(void) {
uint32_t data[2];
uint32_t cmd[] = {
(uint32_t)0x05000000,
(uint32_t)0x35000000,
(uint32_t)0x15000000,
};
for (int i = 0; i < 3; ++i) {
qspi0_rd((uint32_t)3, (uint32_t)1, cmd[i], (uint32_t)0, (uint32_t)0, (uint32_t)0x00000000,
(uint32_t)0, (uint32_t)3, (uint32_t)1, (uint32_t)1, data);
printf("status reg %d: %x\n", i, data[0]);
}
// qpis0_qpi_rd_data(val_list, dumlen=0, datalen=1); // 4-4-4(05/35/15h)
}
static void norflash_enter_quad_mode(void) {
uint32_t data[] = {0};
qspi0_rd((uint32_t)1, (uint32_t)1, (uint32_t)0x35000000, (uint32_t)0, (uint32_t)0,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)1, (uint32_t)1, (uint32_t)1, data);
// set QE=1 in status reg 2 for QSPI/QPI
data[0] = (data[0] | 0x02) << 24;
printf("data[0]: %x\n", data[0]);
norflash_spi_wr_en();
qspi0_wr((uint32_t)1, (uint32_t)1, (uint32_t)0x31000000, (uint32_t)0, (uint32_t)0,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)1, (uint32_t)1, (uint32_t)1, data);
norflash_spi_status();
}
static void norflash_enter_qpi_mode(void) {
uint32_t data[] = {0};
norflash_spi_wr_en();
qspi0_wr((uint32_t)1, (uint32_t)1, (uint32_t)0x38000000, (uint32_t)0, (uint32_t)0,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)0, (uint32_t)1, (uint32_t)1, data);
}
// need to assure in qpi mode before
static void norflash_quit_qpi_mode(void) {
uint32_t data[] = {0};
norflash_qpi_wr_en();
qspi0_wr((uint32_t)3, (uint32_t)1, (uint32_t)0xFF000000, (uint32_t)0, (uint32_t)0,
(uint32_t)0x00000000, (uint32_t)0, (uint32_t)0, (uint32_t)1, (uint32_t)1, data);
}
static void norflash_spi_test(void) {
printf("\nnorflash spi test\n");
uint32_t wr_data[] = {0x23456788, 0x00FFEE30, 0x418461AB, 0xC252DE21, 0x00550022, 0x00002266};
norflash_spi_id();
norflash_spi_status();
norflash_spi_wr_en();
norflash_spi_wr_data(wr_data, sizeof(wr_data) / sizeof(wr_data[0]));
norflash_spi_rd_data(sizeof(wr_data) / sizeof(wr_data[0]));
}
static void norflash_dspi_test(void) {
printf("\nnorflash dspi test\n");
uint32_t wr_data[] = {0x23456788, 0x00FFEE30, 0x418461AB, 0xC252DE21, 0x00550022, 0x00002266};
norflash_dspi_id();
norflash_spi_wr_en();
norflash_spi_wr_data(wr_data, sizeof(wr_data) / sizeof(wr_data[0]));
// rd
norflash_dspi_rd_data(sizeof(wr_data) / sizeof(wr_data[0]));
}
static void norflash_qspi_test(void) {
printf("\nnorflash qspi test\n");
uint32_t wr_data[] = {0x23456788, 0x00FFEE30, 0x418461AB, 0xC252DE21, 0x00550022, 0x00002266};
norflash_enter_quad_mode();
norflash_qspi_id();
norflash_spi_wr_en();
norflash_qspi_wr_data(wr_data, sizeof(wr_data) / sizeof(wr_data[0]));
// rd:
norflash_qspi_rd_data(sizeof(wr_data) / sizeof(wr_data[0]));
}
static void norflash_qpi_test(void) {
printf("\nnorflash qpi test\n");
uint32_t wr_data[] = {0x23456788, 0x00FFEE30, 0x418461AB, 0xC252DE21, 0x00550022, 0x00002266};
norflash_enter_quad_mode();
norflash_enter_qpi_mode();
norflash_qpi_id();
norflash_qpi_status();
norflash_qpi_wr_en();
norflash_qpi_wr_data(wr_data, sizeof(wr_data) / sizeof(wr_data[0]));
// rd
norflash_qpi_rd_data(sizeof(wr_data) / sizeof(wr_data[0]));
norflash_quit_qpi_mode();
}
void ip_norflash_test(int argc, char **argv) {
(void)argc;
(void)argv;
printf("[NATV IP] qspi nor flash test\n");
QSPI0_InitStruct_t qspi0 = {
(uint32_t)0, (uint32_t)0b0001, (uint32_t)0, (uint32_t)250,
(uint32_t)140, (uint32_t)24, (uint32_t)10, (uint32_t)0,
};
qspi0_init(qspi0);
norflash_spi_test();
norflash_dspi_test();
norflash_qspi_test();
norflash_qpi_test();
}
-9
View File
@@ -1,9 +0,0 @@
APP_PATH += $(ROOT_PATH)/app/coremark/coremark-main/core_main.c
APP_PATH += $(ROOT_PATH)/app/coremark/coremark-main/core_list_join.c
APP_PATH += $(ROOT_PATH)/app/coremark/coremark-main/core_matrix.c
APP_PATH += $(ROOT_PATH)/app/coremark/coremark-main/core_state.c
APP_PATH += $(ROOT_PATH)/app/coremark/coremark-main/core_util.c
APP_PATH += $(ROOT_PATH)/app/coremark/core_portme.c
INC_PATH += -I$(ROOT_PATH)/app/coremark/coremark-main
INC_PATH += -I$(ROOT_PATH)/app/coremark
-173
View File
@@ -1,173 +0,0 @@
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2025 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "ff.h" /* Basic definitions of FatFs */
#include "diskio.h" /* Declarations FatFs MAI */
#include <rs_spisd.h>
#define DEV_TF 0 /* Map MMC/SD card to physical drive 1 */
#define SD_BLOCKSIZE 512
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS status = STA_NOINIT;
switch (pdrv) {
case DEV_TF:
status &= ~STA_NOINIT;
break;
default:
status = STA_NOINIT;
}
return status;
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS status = STA_NOINIT;
switch (pdrv) {
case DEV_TF:
status &= ~STA_NOINIT;
break;
default:
status = STA_NOINIT;
}
return status;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
DRESULT status = RES_PARERR;
if (!count) return RES_PARERR; /* Check parameter */
switch (pdrv) {
case DEV_TF:
// if ((DWORD)buff&3) {
// DRESULT res = RES_OK;
// DWORD scratch[SD_BLOCKSIZE / 4];
// while (count--) {
// res = disk_read(DEV_TF, (void *)scratch, sector++, 1);
// if (res != RES_OK) {
// break;
// }
// memcpy(buff, scratch, SD_BLOCKSIZE);
// buff += SD_BLOCKSIZE;
// }
// return res;
// }
spisd_sector_read(buff, sector, count);
status = RES_OK;
break;
default:
status = RES_PARERR;
}
return status;
return status;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if FF_FS_READONLY == 0
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT status = RES_PARERR;
if (!count) return RES_PARERR; /* Check parameter */
switch (pdrv) {
case DEV_TF:
spisd_sector_write(buff, sector, count);
status = RES_OK;
break;
default:
status = RES_PARERR;
}
return status;
return status;
}
#endif
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT status = RES_PARERR;
switch (pdrv) {
case DEV_TF:
switch(cmd) {
case GET_SECTOR_SIZE:
*(WORD * )buff = SD_BLOCKSIZE;
break;
case GET_SECTOR_COUNT:
*(DWORD * )buff = 524288 * 4; // 1024MiB(mem access)
break;
case GET_BLOCK_SIZE:
*(WORD * )buff = 1;
break;
case CTRL_SYNC:
spisd_sector_sync();
break;
}
status = RES_OK;
break;
default:
status = RES_PARERR;
}
return status;
return status;
}
DWORD get_fattime(void) {
// HACK:
return ((DWORD)(2025 - 1980) << 25) /* Year 2025 */
| ((DWORD)1 << 21) /* Month 1 */
| ((DWORD)1 << 16) /* Mday 1 */
| ((DWORD)0 << 11) /* Hour 0 */
| ((DWORD)0 << 5) /* Min 0 */
| ((DWORD)0 >> 1); /* Sec 0 */
}
-6
View File
@@ -1,6 +0,0 @@
APP_PATH += $(ROOT_PATH)/app/fatfs/ff16/source/diskio.c
APP_PATH += $(ROOT_PATH)/app/fatfs/ff16/source/ff.c
APP_PATH += $(ROOT_PATH)/app/fatfs/ff16/source/ffsystem.c
APP_PATH += $(ROOT_PATH)/app/fatfs/ff16/source/ffunicode.c
INC_PATH += -I$(ROOT_PATH)/app/fatfs/ff16/source
-10
View File
@@ -1,10 +0,0 @@
APP_PATH += $(shell find $(ROOT_PATH)/app/lvgl/lvgl-main/src -type f -name '*.c')
APP_PATH += $(ROOT_PATH)/app/lvgl/lv_port_disp.c
APP_PATH += $(ROOT_PATH)/crt/libgcc/clzsi2.c
APP_PATH += $(ROOT_PATH)/crt/libgcc/ffssi2.c
APP_PATH += $(ROOT_PATH)/crt/libgcc/udivdi3.c
APP_PATH += $(ROOT_PATH)/crt/libgcc/divdi3.c
APP_PATH += $(ROOT_PATH)/crt/libgcc/umoddi3.c
INC_PATH += -I$(ROOT_PATH)/app/lvgl/lvgl-main/
INC_PATH += -I$(ROOT_PATH)/app/lvgl/
+8
View File
@@ -0,0 +1,8 @@
#ifndef RETROSOC_MEDIA_DONUT_H
#define RETROSOC_MEDIA_DONUT_H
#include <stdint.h>
void donut_test(int argc, char **argv);
#endif
@@ -0,0 +1,20 @@
#ifndef RETROSOC_MEDIA_VIDEO_PLAYER_H
#define RETROSOC_MEDIA_VIDEO_PLAYER_H
#include <stddef.h>
#include <stdint.h>
#include <retrosoc/core/status.h>
typedef struct {
uint32_t width;
uint32_t height;
uint32_t frame_count;
uint32_t payload_offset;
uint32_t frame_size;
} rs_video_info_t;
rs_status_t rs_video_parse(const void *data, size_t data_size, rs_video_info_t *info);
rs_status_t rs_video_show_spisd(uintptr_t start_address, uint32_t available_size);
#endif
@@ -0,0 +1,33 @@
#ifndef RETROSOC_MEDIA_WAV_AUDIO_H
#define RETROSOC_MEDIA_WAV_AUDIO_H
#include <stddef.h>
#include <stdint.h>
#include <retrosoc/core/status.h>
typedef rs_status_t (*rs_wav_read_fn)(void *context, uint32_t offset, void *buffer,
size_t byte_count);
typedef struct {
rs_wav_read_fn read;
void *context;
uint32_t size;
} rs_wav_reader_t;
typedef struct {
uint16_t audio_format;
uint16_t channel_count;
uint32_t sample_rate;
uint32_t byte_rate;
uint16_t block_align;
uint16_t bits_per_sample;
uint32_t data_offset;
uint32_t data_size;
} rs_wav_info_t;
rs_status_t rs_wav_parse(const rs_wav_reader_t *reader, rs_wav_info_t *info);
rs_status_t rs_wav_parse_spisd(uintptr_t start_address, uint32_t available_size,
rs_wav_info_t *info);
#endif
+229
View File
@@ -0,0 +1,229 @@
// Copyright 2025 ECOS Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -- Adaptable modifications are redistributed under compatible License --
//
// Copyright (c) 2023-2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
// retroSoC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
#include <retrosoc/core/soc.h>
#include <retrosoc/lib/string.h>
#include <retrosoc/lib/printf.h>
#include <retrosoc/hal/qspi.h>
#include <retrosoc/hal/lcd.h>
#include <retrosoc/media/donut.h>
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define GRAY_LEVELS 12
// screen framebuffer (128x128)
#define scale_x 8
#define scale_y 8
#define DONUT_SIZE 16
#define DONUT_WIDTH DONUT_SIZE *scale_x
#define DONUT_HEIGHT DONUT_SIZE *scale_y
#define RS_DONUT_FRAME_COUNT 300U
static const uint32_t gray_colors[GRAY_LEVELS] = {
0x00000000, // black (' ')
0x10821082, // dark gray ('.')
0x21042104, // Dark gray(',')
0x31863186, // darker gray ('-')
0x42084208, // medium dark gray ('~')
0x528A528A, // medium gray(':')
0x630C630C, // medium bright gray (';')
0x738E738E, // lighter gray ('=')
0x84108410, // bright gray('!')
0x94929492, // very bright gray ('*')
0xA514A514, // extremely bright gray ('#')
0xB596B596 // brightest gray ('$')
};
static uint32_t donut_framebuffer_32[DONUT_WIDTH * DONUT_HEIGHT];
// void screen_clear(void) {
// memset(donut_framebuffer_32, 0x00, sizeof(donut_framebuffer_32));
// }
// inline marco
#define R_OPT(mul, shift, x, y) \
do { \
int _temp = x; \
x -= mul * y >> shift; \
y += mul * _temp >> shift; \
_temp = (3145728 - x * x - y * y) >> 11; \
x = x * _temp >> 10; \
y = y * _temp >> 10; \
} while (0)
// trigonometric function table (1024 = 1.0) - reserve 91 values
// static const int16_t sin_table[91] = {
// 0, 18, 36, 54, 71, 89, 107, 125, 143, 160, 178, 195, 213, 230, 248, 265, 282, 299, 316, 333,
// 350, 367, 384, 400, 416, 433, 449, 465, 481, 496, 512, 527, 542, 557, 572, 587, 601, 615,
// 629, 643, 657, 670, 683, 696, 709, 721, 733, 745, 757, 768, 779, 790, 801, 811, 821, 831,
// 841, 850, 859, 868, 876, 884, 892, 900, 907, 914, 921, 927, 933, 939, 945, 950, 955, 960,
// 964, 968, 972, 975, 978, 981, 984, 986, 988, 990, 991, 992, 993, 994, 994, 995, 995
// };
// static const int16_t cos_table[91] = {
// 1024, 1023, 1023, 1022, 1021, 1019, 1017, 1014, 1011, 1007, 1003, 998, 993, 987, 981, 974,
// 967, 959, 951, 942, 933, 923, 913, 902, 891, 879, 867, 854, 841, 827, 813, 798, 783, 767,
// 751, 734, 717, 699, 681, 662, 643, 623, 603, 582, 561, 539, 517, 494, 471, 447, 423, 398,
// 373, 347, 321, 294, 267, 239, 211, 182, 153, 123, 93, 62, 31, 0, -31, -62, -93, -123, -153,
// -182, -211, -239, -267, -294, -321, -347, -373, -398, -423, -447, -471, -494, -517, -539,
// -561, -582, -603, -623, -643
// };
static uint32_t pixel_buffer[DONUT_SIZE * DONUT_SIZE];
static signed char z_buffer[DONUT_SIZE * DONUT_SIZE];
static inline void fast_scaled_pixel_write(uint32_t color, int x, int y) {
if (likely(x >= 0 && x < DONUT_SIZE && y >= 0 && y < DONUT_SIZE)) {
int scaled_x = x * scale_x;
int scaled_y = y * scale_y;
int base_index = scaled_y * DONUT_WIDTH + scaled_x;
int row_index = base_index;
donut_framebuffer_32[row_index / 2] = color;
donut_framebuffer_32[row_index / 2 + 1] = color;
donut_framebuffer_32[row_index / 2 + 2] = color;
donut_framebuffer_32[row_index / 2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index / 2] = color;
donut_framebuffer_32[row_index / 2 + 1] = color;
donut_framebuffer_32[row_index / 2 + 2] = color;
donut_framebuffer_32[row_index / 2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index / 2] = color;
donut_framebuffer_32[row_index / 2 + 1] = color;
donut_framebuffer_32[row_index / 2 + 2] = color;
donut_framebuffer_32[row_index / 2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index / 2] = color;
donut_framebuffer_32[row_index / 2 + 1] = color;
donut_framebuffer_32[row_index / 2 + 2] = color;
donut_framebuffer_32[row_index / 2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index / 2] = color;
donut_framebuffer_32[row_index / 2 + 1] = color;
donut_framebuffer_32[row_index / 2 + 2] = color;
donut_framebuffer_32[row_index / 2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index / 2] = color;
donut_framebuffer_32[row_index / 2 + 1] = color;
donut_framebuffer_32[row_index / 2 + 2] = color;
donut_framebuffer_32[row_index / 2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index / 2] = color;
donut_framebuffer_32[row_index / 2 + 1] = color;
donut_framebuffer_32[row_index / 2 + 2] = color;
donut_framebuffer_32[row_index / 2 + 3] = color;
row_index += DONUT_WIDTH;
donut_framebuffer_32[row_index / 2] = color;
donut_framebuffer_32[row_index / 2 + 1] = color;
donut_framebuffer_32[row_index / 2 + 2] = color;
donut_framebuffer_32[row_index / 2 + 3] = color;
}
}
static void rs_donut_render(uint32_t frame_count) {
int sA = 1024;
int cA = 0;
int sB = 1024;
int cB = 0;
const int R1 = 1, R2 = 1024, K2 = 4096 * 1024;
const int screen_center_x = DONUT_SIZE / 2, screen_center_y = DONUT_SIZE / 2;
const int scale_x_val = 12, scale_y_val = 12;
for (uint32_t frame = 0U; frame < frame_count; ++frame) {
(void)memset(pixel_buffer, 0, sizeof(pixel_buffer));
(void)memset(z_buffer, 0x7F, sizeof(z_buffer));
(void)memset(donut_framebuffer_32, 0, sizeof(donut_framebuffer_32));
int sj = 0, cj = 1024;
for (int j = 0; j < 90; j++) {
int si = 0, ci = 1024;
for (int i = 0; i < DONUT_SIZE * DONUT_SIZE; i++) {
int x0 = R1 * cj + R2;
int x1 = ci * x0 >> 10;
int x2 = cA * sj >> 10;
int x3 = si * x0 >> 10;
int x4 = R1 * x2 - (sA * x3 >> 10);
int x5 = sA * sj >> 10;
int x6 = K2 + R1 * 1024 * x5 + cA * x3;
int x7 = cj * si >> 10;
int x = screen_center_x + (scale_x_val * (cB * x1 - sB * x4)) / x6;
int y = screen_center_y + (scale_y_val * (cB * x4 + sB * x1)) / x6;
int N = (((-cA * x7 - cB * ((-sA * x7 >> 10) + x2) - ci * (cj * sB >> 10)) >> 10) -
x5) >>
7;
if (likely(y > 0 && y < DONUT_SIZE && x > 0 && x < DONUT_SIZE)) {
int o = x + DONUT_SIZE * y;
signed char zz = (x6 - K2) >> 15;
if (likely(zz < z_buffer[o])) {
z_buffer[o] = zz;
const uint32_t shade =
(N <= 0) ? 0U : ((N >= GRAY_LEVELS) ? GRAY_LEVELS - 1U : (uint32_t)N);
uint32_t color = gray_colors[shade];
pixel_buffer[o] = color;
}
}
R_OPT(5, 8, ci, si);
}
R_OPT(9, 7, cj, sj);
}
R_OPT(5, 7, cA, sA);
R_OPT(5, 8, cB, sB);
for (int y = 0; y < DONUT_SIZE; y++) {
for (int x = 0; x < DONUT_SIZE; x++) {
int index = x + DONUT_SIZE * y;
uint32_t color = pixel_buffer[index];
if (likely(color != 0)) {
fast_scaled_pixel_write(color, x, y);
}
}
}
lcd_fill_image(0, 0, DONUT_WIDTH, DONUT_HEIGHT, donut_framebuffer_32);
}
}
void donut_test(int argc, char **argv) {
(void)argc;
(void)argv;
printf("donut test\n");
rs_donut_render(RS_DONUT_FRAME_COUNT);
}
+85
View File
@@ -0,0 +1,85 @@
#include <retrosoc/core/soc.h>
#include <retrosoc/hal/lcd.h>
#include <retrosoc/hal/spisd.h>
#include <retrosoc/media/video_player.h>
#define RS_VIDEO_HEADER_SIZE 16U
static uint32_t rs_video_read_le32(const uint8_t *data) {
return (uint32_t)data[0] | ((uint32_t)data[1] << 8U) | ((uint32_t)data[2] << 16U) |
((uint32_t)data[3] << 24U);
}
static rs_status_t rs_video_decode_header(const uint8_t *bytes, uint32_t available_size,
rs_video_info_t *info) {
uint32_t pixels;
uint32_t frame_size;
uint32_t payload_size;
if ((bytes == NULL) || (info == NULL) || (available_size < RS_VIDEO_HEADER_SIZE)) {
return RS_EINVAL;
}
*info = (rs_video_info_t){0};
info->width = rs_video_read_le32(&bytes[0]);
info->height = rs_video_read_le32(&bytes[4]);
info->frame_count = rs_video_read_le32(&bytes[8]);
if ((info->width == 0U) || (info->height == 0U) || (info->frame_count == 0U) ||
(info->width > (UINT32_MAX / info->height))) {
return RS_EFORMAT;
}
pixels = info->width * info->height;
if (((pixels & 1U) != 0U) || (pixels > (UINT32_MAX / 2U))) {
return RS_EFORMAT;
}
frame_size = pixels * 2U;
if ((frame_size == 0U) ||
(info->frame_count > ((UINT32_MAX - RS_VIDEO_HEADER_SIZE) / frame_size))) {
return RS_EFORMAT;
}
payload_size = info->frame_count * frame_size;
if (payload_size > (available_size - RS_VIDEO_HEADER_SIZE)) {
return RS_EFORMAT;
}
info->payload_offset = RS_VIDEO_HEADER_SIZE;
info->frame_size = frame_size;
return RS_OK;
}
rs_status_t rs_video_parse(const void *data, size_t data_size, rs_video_info_t *info) {
if ((data_size > UINT32_MAX) || (data == NULL)) {
return RS_EINVAL;
}
return rs_video_decode_header((const uint8_t *)data, (uint32_t)data_size, info);
}
rs_status_t rs_video_show_spisd(uintptr_t start_address, uint32_t available_size) {
uint8_t header[RS_VIDEO_HEADER_SIZE];
rs_video_info_t info;
rs_status_t status;
status = rs_spisd_read_bytes(header, sizeof(header), start_address);
if (status != RS_OK) {
return status;
}
status = rs_video_decode_header(header, available_size, &info);
if (status != RS_OK) {
return status;
}
if ((info.width > LCD_W) || (info.height > LCD_H) || ((start_address & 3U) != 0U) ||
((uintptr_t)info.payload_offset > (UINTPTR_MAX - start_address))) {
return RS_EINVAL;
}
for (uint32_t frame = 0U; frame < info.frame_count; ++frame) {
const uint32_t frame_offset = frame * info.frame_size;
const uintptr_t payload_address = start_address + info.payload_offset;
if ((uintptr_t)frame_offset > (UINTPTR_MAX - payload_address)) {
return RS_EINVAL;
}
const uintptr_t frame_address = payload_address + frame_offset;
lcd_fill_image(0U, 0U, (uint16_t)info.width, (uint16_t)info.height,
(uint32_t *)frame_address);
}
return RS_OK;
}
+133
View File
@@ -0,0 +1,133 @@
#include <stdbool.h>
#include <retrosoc/core/soc.h>
#include <retrosoc/hal/spisd.h>
#include <retrosoc/media/wav_audio.h>
static uint16_t rs_wav_read_le16(const uint8_t *data) {
return (uint16_t)((uint16_t)data[0] | ((uint16_t)data[1] << 8U));
}
static uint32_t rs_wav_read_le32(const uint8_t *data) {
return (uint32_t)data[0] | ((uint32_t)data[1] << 8U) | ((uint32_t)data[2] << 16U) |
((uint32_t)data[3] << 24U);
}
static bool rs_wav_tag_matches(const uint8_t *tag, const char *expected) {
return (tag[0] == (uint8_t)expected[0]) && (tag[1] == (uint8_t)expected[1]) &&
(tag[2] == (uint8_t)expected[2]) && (tag[3] == (uint8_t)expected[3]);
}
static rs_status_t rs_wav_read(const rs_wav_reader_t *reader, uint32_t offset, void *buffer,
size_t byte_count) {
if ((reader == NULL) || (reader->read == NULL) || (buffer == NULL) || (offset > reader->size) ||
(byte_count > ((size_t)reader->size - offset))) {
return RS_EFORMAT;
}
return reader->read(reader->context, offset, buffer, byte_count);
}
rs_status_t rs_wav_parse(const rs_wav_reader_t *reader, rs_wav_info_t *info) {
uint8_t riff[12];
uint8_t chunk[8];
uint8_t format[16];
uint32_t offset = 12U;
uint32_t limit;
bool format_found = false;
if ((reader == NULL) || (info == NULL) || (reader->size < sizeof(riff))) {
return RS_EINVAL;
}
*info = (rs_wav_info_t){0};
if (rs_wav_read(reader, 0U, riff, sizeof(riff)) != RS_OK) {
return RS_EIO;
}
if (!rs_wav_tag_matches(riff, "RIFF") || !rs_wav_tag_matches(&riff[8], "WAVE")) {
return RS_EFORMAT;
}
if (rs_wav_read_le32(&riff[4]) > (reader->size - 8U)) {
return RS_EFORMAT;
}
limit = rs_wav_read_le32(&riff[4]) + 8U;
while (offset < limit) {
uint32_t payload_offset;
uint32_t payload_size;
uint32_t padded_size;
if ((limit - offset) < sizeof(chunk)) {
return RS_EFORMAT;
}
if (rs_wav_read(reader, offset, chunk, sizeof(chunk)) != RS_OK) {
return RS_EIO;
}
payload_size = rs_wav_read_le32(&chunk[4]);
payload_offset = offset + (uint32_t)sizeof(chunk);
if ((payload_offset > limit) || (payload_size > (limit - payload_offset))) {
return RS_EFORMAT;
}
padded_size = payload_size + (payload_size & 1U);
if ((padded_size < payload_size) || (padded_size > (limit - payload_offset))) {
return RS_EFORMAT;
}
if (rs_wav_tag_matches(chunk, "fmt ")) {
uint32_t expected_block_align;
if ((payload_size < sizeof(format)) ||
(rs_wav_read(reader, payload_offset, format, sizeof(format)) != RS_OK)) {
return RS_EFORMAT;
}
info->audio_format = rs_wav_read_le16(&format[0]);
info->channel_count = rs_wav_read_le16(&format[2]);
info->sample_rate = rs_wav_read_le32(&format[4]);
info->byte_rate = rs_wav_read_le32(&format[8]);
info->block_align = rs_wav_read_le16(&format[12]);
info->bits_per_sample = rs_wav_read_le16(&format[14]);
if ((info->audio_format != 1U) || (info->channel_count == 0U) ||
((info->bits_per_sample != 8U) && (info->bits_per_sample != 16U) &&
(info->bits_per_sample != 24U) && (info->bits_per_sample != 32U))) {
return RS_ENOTSUP;
}
expected_block_align = (uint32_t)info->channel_count * info->bits_per_sample / 8U;
if ((expected_block_align == 0U) || (expected_block_align > UINT16_MAX) ||
(info->block_align != expected_block_align) ||
(info->sample_rate > (UINT32_MAX / info->block_align)) ||
(info->byte_rate != (info->sample_rate * info->block_align))) {
return RS_EFORMAT;
}
format_found = true;
} else if (rs_wav_tag_matches(chunk, "data")) {
if (!format_found || ((payload_size % info->block_align) != 0U)) {
return RS_EFORMAT;
}
info->data_offset = payload_offset;
info->data_size = payload_size;
return RS_OK;
}
offset = payload_offset + padded_size;
}
return RS_EFORMAT;
}
typedef struct {
uintptr_t start_address;
} rs_wav_spisd_context_t;
static rs_status_t rs_wav_spisd_read(void *context, uint32_t offset, void *buffer,
size_t byte_count) {
const rs_wav_spisd_context_t *spisd = (const rs_wav_spisd_context_t *)context;
if ((spisd == NULL) || (offset > (UINTPTR_MAX - spisd->start_address))) {
return RS_EINVAL;
}
return rs_spisd_read_bytes(buffer, byte_count, spisd->start_address + offset);
}
rs_status_t rs_wav_parse_spisd(uintptr_t start_address, uint32_t available_size,
rs_wav_info_t *info) {
rs_wav_spisd_context_t context = {start_address};
const rs_wav_reader_t reader = {rs_wav_spisd_read, &context, available_size};
return rs_wav_parse(&reader, info);
}
+81
View File
@@ -0,0 +1,81 @@
/* FatFs block-device adapter for the retroSoC SPISD memory window. */
#include <stdbool.h>
#include "ff.h"
#include "diskio.h"
#include <retrosoc/core/soc.h>
#include <retrosoc/hal/spisd.h>
#define RS_FATFS_DRIVE_TF 0U
static bool rs_fatfs_initialized;
static DRESULT rs_fatfs_result(rs_status_t status) {
return (status == RS_OK) ? RES_OK : RES_ERROR;
}
DSTATUS disk_status(BYTE pdrv) {
if (pdrv != RS_FATFS_DRIVE_TF) {
return STA_NOINIT;
}
return rs_fatfs_initialized ? 0U : STA_NOINIT;
}
DSTATUS disk_initialize(BYTE pdrv) {
if (pdrv != RS_FATFS_DRIVE_TF) {
return STA_NOINIT;
}
rs_fatfs_initialized = true;
return 0U;
}
DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) {
if ((pdrv != RS_FATFS_DRIVE_TF) || (buff == NULL) || (count == 0U) ||
(disk_status(pdrv) != 0U) || (sector > UINT32_MAX)) {
return RES_PARERR;
}
return rs_fatfs_result(rs_spisd_sector_read(buff, (uint32_t)sector, (uint32_t)count));
}
#if FF_FS_READONLY == 0
DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count) {
if ((pdrv != RS_FATFS_DRIVE_TF) || (buff == NULL) || (count == 0U) ||
(disk_status(pdrv) != 0U) || (sector > UINT32_MAX)) {
return RES_PARERR;
}
return rs_fatfs_result(rs_spisd_sector_write(buff, (uint32_t)sector, (uint32_t)count));
}
#endif
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) {
if ((pdrv != RS_FATFS_DRIVE_TF) || (disk_status(pdrv) != 0U)) {
return RES_NOTRDY;
}
switch (cmd) {
case CTRL_SYNC:
return rs_fatfs_result(rs_spisd_sector_sync(RS_TIMEOUT_DEFAULT));
case GET_SECTOR_SIZE:
if (buff == NULL) {
return RES_PARERR;
}
*(WORD *)buff = RS_SPISD_SECTOR_SIZE;
return RES_OK;
case GET_SECTOR_COUNT:
if (buff == NULL) {
return RES_PARERR;
}
*(LBA_t *)buff = (LBA_t)(TF_CARD_OFFST / RS_SPISD_SECTOR_SIZE);
return RES_OK;
case GET_BLOCK_SIZE:
if (buff == NULL) {
return RES_PARERR;
}
*(DWORD *)buff = 1U;
return RES_OK;
default:
return RES_PARERR;
}
}
+6
View File
@@ -0,0 +1,6 @@
APP_SRCS += $(ROOT_PATH)/app/fatfs/ff16/source/diskio.c
APP_SRCS += $(ROOT_PATH)/app/fatfs/ff16/source/ff.c
APP_SRCS += $(ROOT_PATH)/app/fatfs/ff16/source/ffsystem.c
APP_SRCS += $(ROOT_PATH)/app/fatfs/ff16/source/ffunicode.c
APP_INC_DIRS += $(ROOT_PATH)/app/fatfs/ff16/source
@@ -249,7 +249,7 @@
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
#define FF_FS_NORTC 0
#define FF_FS_NORTC 1
#define FF_NORTC_MON 1
#define FF_NORTC_MDAY 1
#define FF_NORTC_YEAR 2025
@@ -1,27 +1,27 @@
#include <firmware.h>
#include <rs_printf.h>
#include <rs_tim.h>
#include <retrosoc/core/soc.h>
#include <retrosoc/lib/printf.h>
#include <retrosoc/hal/timer.h>
#include <userip.h>
void userip_main(int argc, char **argv) {
// user custom area HACK:
(void)argv;
if(argc == 0) {
if (argc == 0) {
printf("[FIXED IP] archinfo test\n");
printf("[ARCHINFO SYS] %x\n", reg_user_ip_reg0);
printf("[ARCHINFO IDL] %x\n", reg_user_ip_reg1);
printf("[ARCHINFO IDH] %x\n", reg_user_ip_reg2);
} else if(argc == 1) {
} else if (argc == 1) {
reg_user_ip_reg1 = 2;
printf("div val: %x\n", reg_user_ip_reg1);
reg_user_ip_reg2 = 0;
for(int i = 0; i < 6; ++i) printf("tim val: %d\n", reg_user_ip_reg2);
} else if(argc == 2) {
for (int i = 0; i < 6; ++i)
printf("tim val: %d\n", reg_user_ip_reg2);
} else if (argc == 2) {
printf("[reg0] %x\n", reg_user_ip_reg0);
reg_user_ip_reg1 = (uint32_t)0xfffe;
printf("do val: %x\n", reg_user_ip_reg5);
for(int i = 0; i < 3; ++i) {
for (int i = 0; i < 3; ++i) {
delay_ms(1);
reg_user_ip_reg5 = ~reg_user_ip_reg5;
printf("[%d]do val: %x\n", i, reg_user_ip_reg5);
@@ -40,7 +40,7 @@ void userip_main(int argc, char **argv) {
printf("pd val: %x\n", reg_user_ip_reg4);
reg_user_ip_reg1 = (uint32_t)0xfffe;
for(int i = 0; i < 6; ++i) {
for (int i = 0; i < 6; ++i) {
printf("[%d]di val: %x\n", i, reg_user_ip_reg6);
}
}
File renamed without changes.
+5
View File
@@ -0,0 +1,5 @@
# User IP is optional and is linked only for MDD configurations.
ifeq ($(IP), MDD)
APP_SRCS += $(ROOT_PATH)/app/network/userip/userip.c
APP_INC_DIRS += $(ROOT_PATH)/app/network/userip
endif
File renamed without changes.
@@ -11,8 +11,8 @@
*********************/
#include "lv_port_disp.h"
#include <stdbool.h>
#include <rs_lcd.h>
#include <rs_printf.h>
#include <retrosoc/hal/lcd.h>
#include <retrosoc/lib/printf.h>
#define MY_DISP_HOR_RES 240
#define MY_DISP_VER_RES 135
File renamed without changes.
File renamed without changes.
File renamed without changes.
+8
View File
@@ -0,0 +1,8 @@
LVGL_SDK_DIR := $(ROOT_PATH)/app/lvgl/lvgl-main
APP_SRCS += $(sort $(shell find $(LVGL_SDK_DIR)/src -type f -name '*.c'))
APP_SRCS += $(ROOT_PATH)/app/ports/lvgl/lv_port_disp.c
APP_SRCS += $(ROOT_PATH)/app/ports/lvgl/lv_port_indev.c
APP_INC_DIRS += $(LVGL_SDK_DIR)
APP_INC_DIRS += $(ROOT_PATH)/app/ports/lvgl
+5 -5
View File
@@ -14,7 +14,7 @@ from scripts.setup_helpers import atomic_write, download_file, ensure_git_repo
APP_DIR = Path(__file__).resolve().parent
FATFS_DIR = APP_DIR / "fatfs"
FATFS_DIR = APP_DIR / "middleware/fatfs"
COREMARK_DIR = APP_DIR / "coremark/coremark-main"
@@ -30,9 +30,9 @@ def patch_fatfs(source: Path) -> None:
fatfs_source = source / "ff.c"
content = fatfs_source.read_text(encoding="utf-8")
original_content = content
include = "#include <rs_string.h>"
include = "#include <retrosoc/lib/string.h>"
if include not in content:
for legacy_include in ("#include <string.h>", "#include <tinystring.h>"):
for legacy_include in ("#include <string.h>", "#include <tinystring.h>", "#include <rs_string.h>"):
if legacy_include in content:
content = content.replace(legacy_include, include)
break
@@ -46,8 +46,8 @@ def patch_coremark() -> None:
header = COREMARK_DIR / "coremark.h"
content = header.read_text(encoding="utf-8")
original_content = content
include = "#include <rs_printf.h>"
legacy_include = "#include <tinyprintf.h>"
include = "#include <retrosoc/lib/printf.h>"
for legacy_include in ("#include <tinyprintf.h>", "#include <rs_printf.h>"):
if legacy_include in content:
content = content.replace(legacy_include, include)
if include not in content:
-6
View File
@@ -1,6 +0,0 @@
# user custom area
ifeq ($(IP), MDD)
APP_PATH += $(ROOT_PATH)/app/userip/userip.c
INC_PATH += -I$(ROOT_PATH)/app/userip
# add more user custom files into 'APP_PATH'
endif
+12
View File
@@ -0,0 +1,12 @@
SOC := MINI
CORE := HAZARD3
IP := NONE
PDK := IHP130
HAVE_PLL := NO
HAVE_SRAM_IF := NO
HAVE_SRAM_MACRO := NO
HAVE_SVA := NO
ISA := RV32IM
HAVE_CSR := YES
APP := shell
LINK_TYPE := ld2_psram
+1 -1
View File
@@ -8,5 +8,5 @@ HAVE_SRAM_MACRO := NO
HAVE_SVA := NO
ISA := RV32IM
HAVE_CSR := NO
PROG_TYPE := BASE
APP := bringup
LINK_TYPE := ld2_psram
+1 -1
View File
@@ -8,5 +8,5 @@ HAVE_SRAM_MACRO := NO
HAVE_SVA := NO
ISA := RV32IM
HAVE_CSR := NO
PROG_TYPE := BASE
APP := bringup
LINK_TYPE := ld2_psram
+1 -1
View File
@@ -8,5 +8,5 @@ HAVE_SRAM_MACRO := NO
HAVE_SVA := NO
ISA := RV32IM
HAVE_CSR := NO
PROG_TYPE := BASE
APP := bringup
LINK_TYPE := ld2_psram
+1 -1
View File
@@ -8,5 +8,5 @@ HAVE_SRAM_MACRO := NO
HAVE_SVA := NO
ISA := RV32IM
HAVE_CSR := NO
PROG_TYPE := BASE
APP := bringup
LINK_TYPE := ld2_psram
+81
View File
@@ -0,0 +1,81 @@
# retroSoC Runtime and SDK
`crt/` contains the freestanding RISC-V runtime and software development kit
used by every retroSoC firmware image. It provides startup code, linker
layouts, public SoC interfaces, hardware abstraction layers, and small runtime
services. It does not provide an application entry point; applications live in
[`../app`](../app).
## Layout
| Path | Purpose |
| --- | --- |
| `arch/riscv/` | RISC-V startup, interrupt assembly, compiler runtime helpers, and architecture-specific support. |
| `include/retrosoc/core/` | Public status, SoC, architecture, interrupt, and bounded-wait interfaces. |
| `include/retrosoc/hal/` | Public memory-mapped peripheral interfaces. |
| `include/retrosoc/lib/` | Freestanding console, formatting, string, and conversion interfaces. |
| `include/retrosoc/service/` | Public boot, shell, and benchmark service interfaces. |
| `src/core/`, `src/hal/`, `src/lib/`, `src/service/` | Implementations grouped by the same ownership boundary as the public headers. |
| `linker/` | Supported linker layouts, selected through `LINK_TYPE`. |
The active public include root is `crt/include`. Include SDK headers through
the `retrosoc` namespace, for example:
```c
#include <retrosoc/core/status.h>
#include <retrosoc/hal/uart.h>
#include <retrosoc/lib/printf.h>
```
`crt/inc/` is legacy or generated compatibility material. It is not an active
public include root for the firmware build; new code must not add dependencies
on it.
## Build Integration
The central software build assembles the runtime sources in
[`../rtl/mini/mk/software.mk`](../rtl/mini/mk/software.mk). It selects the
RISC-V ISA, optional CSR interrupt support, linker layout, and the application
profile. Applications add their own sources after the common runtime is
selected.
Start from a committed configuration profile:
```sh
make CONFIG=configs/ci/hazard3-rv32im-ihp130.mk setup
make CONFIG=configs/ci/hazard3-rv32im-ihp130.mk firmware
```
The resulting firmware and generated headers are isolated under
`build/<profile>-<config-hash>/sw/`. Do not commit build outputs.
## API and Contribution Rules
- Keep public interfaces in the matching `include/retrosoc/<layer>/` directory
and implementations in the corresponding `src/<layer>/` directory.
- Use the `rs_` API namespace and `rs_status_t` for operations that can fail.
- Keep the runtime freestanding: do not add hosted-library, dynamic-allocation,
or operating-system dependencies.
- Prefer bounded APIs such as `rs_strlcpy`, `rs_strlcat`, `rs_snprintf`, and
timeout-based register waits over unbounded operations.
- Add deterministic host tests when new code does not require real registers,
timing, or board hardware.
## Quality Checks
Run the SDK checks from the repository root:
```sh
make sw-format-check
make sw-policy-check
make sw-host-test
```
`sw-format-check` requires the project formatter version (`clang-format-14` in
CI). `sw-policy-check` enforces the self-owned embedded-C naming and unsafe API
policy. `sw-host-test` compiles deterministic runtime, parser, and compiler
helper tests with a host C compiler; it does not replace RTL simulation or
hardware validation.
For the complete firmware, simulation, synthesis, and timing flow, see the
[repository README](../README.md).
+14
View File
@@ -0,0 +1,14 @@
int __clzsi2(unsigned int value);
int __clzsi2(unsigned int value) {
int count = 0;
if (value == 0U) {
return 32;
}
while ((value & 0x80000000U) == 0U) {
++count;
value <<= 1U;
}
return count;
}
File renamed without changes.
+21
View File
@@ -0,0 +1,21 @@
#include <stdbool.h>
#include <stdint.h>
unsigned long long __udivdi3(unsigned long long dividend, unsigned long long divisor);
long long __divdi3(long long dividend, long long divisor);
long long __divdi3(long long dividend, long long divisor) {
const bool dividend_negative = dividend < 0;
const bool divisor_negative = divisor < 0;
const unsigned long long unsigned_dividend =
dividend_negative ? 0U - (unsigned long long)dividend : (unsigned long long)dividend;
const unsigned long long unsigned_divisor =
divisor_negative ? 0U - (unsigned long long)divisor : (unsigned long long)divisor;
const unsigned long long quotient = __udivdi3(unsigned_dividend, unsigned_divisor);
if (unsigned_divisor == 0U) {
return 0;
}
return (dividend_negative != divisor_negative) ? (long long)(0U - quotient)
: (long long)quotient;
}
+14
View File
@@ -0,0 +1,14 @@
int __ffssi2(unsigned int value);
int __ffssi2(unsigned int value) {
int position = 1;
if (value == 0U) {
return 0;
}
while ((value & 1U) == 0U) {
++position;
value >>= 1U;
}
return position;
}
File renamed without changes.
+11
View File
@@ -0,0 +1,11 @@
unsigned int __mulsi3(unsigned int a, unsigned int b) {
unsigned int r = 0;
while (a) {
if (a & 1)
r += b;
a >>= 1;
b <<= 1;
}
return r;
}
+25
View File
@@ -0,0 +1,25 @@
#include <stdint.h>
unsigned long long __udivdi3(unsigned long long dividend, unsigned long long divisor);
unsigned long long __udivdi3(unsigned long long dividend, unsigned long long divisor) {
unsigned long long quotient = 0U;
unsigned long long quotient_bit = 1U;
if (divisor == 0U) {
return 0U;
}
while ((divisor <= dividend) && ((divisor & (1ULL << 63U)) == 0U)) {
divisor <<= 1U;
quotient_bit <<= 1U;
}
while (quotient_bit != 0U) {
if (dividend >= divisor) {
dividend -= divisor;
quotient |= quotient_bit;
}
divisor >>= 1U;
quotient_bit >>= 1U;
}
return quotient;
}
+23
View File
@@ -0,0 +1,23 @@
#include <stdint.h>
unsigned long long __umoddi3(unsigned long long dividend, unsigned long long divisor);
unsigned long long __umoddi3(unsigned long long dividend, unsigned long long divisor) {
unsigned long long quotient_bit = 1U;
if (divisor == 0U) {
return 0U;
}
while ((divisor <= dividend) && ((divisor & (1ULL << 63U)) == 0U)) {
divisor <<= 1U;
quotient_bit <<= 1U;
}
while (quotient_bit != 0U) {
if (dividend >= divisor) {
dividend -= divisor;
}
divisor >>= 1U;
quotient_bit >>= 1U;
}
return dividend;
}
File renamed without changes.
@@ -5,7 +5,7 @@
// binary, for any purpose, commercial or non-commercial, and by any
// means.
#include <firmware.h>
#include <retrosoc/core/soc.h>
#include <libdef.h>
// user custom area
File renamed without changes.
+1 -1
View File
@@ -2,7 +2,7 @@
.global _start
.type _start,@function
#include "system_csr.h"
#include "retrosoc/arch/riscv/system_csr.h"
_start:
#ifdef CSR_ENABLE
@@ -27,7 +27,7 @@
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
#include <system_csr.h>
#include <retrosoc/arch/riscv/system_csr.h>
/**
* \brief Global interrupt disabled
-249
View File
@@ -1,249 +0,0 @@
#ifndef _RETROSOC_DEF_H_
#define _RETROSOC_DEF_H_
#include <stdint.h>
#include <stdbool.h>
#ifdef CORE_PICORV32
#define HW_CORE "PicoRV32"
#elif CORE_HAZARD3
#define HW_CORE "HAZARD3"
#else
#define HW_CORE "none"
#endif
#define CPU_FREQ 72 // unit: MHz
#define UART_BPS 921600 // unit: bps
#define PSRAM_NUM 4
#define PSRAM_SCLK_MIN_FREQ 12 // unit: MHz
#define PSRAM_SCLK_MAX_FREQ 133 // unit: MHz
#define PSRAM_SCLK_FREQ (CPU_FREQ / 2)
#define SPFS_MEM_START 0x00000000
#define SPFS_MEM_OFFST 32 * 1024 * 1024
#define NMI_MEM_START 0x10000000
#define NMI_MEM_OFFST 256 * 1024 * 1024
#define APB_MEM_START 0x20000000
#define APB_MEM_OFFST 256 * 1024 * 1024
#define SRAM_MEM_START 0x30000000
#define SRAM_MEM_OFFST 128 * 1024
#define SDRAM_MEM_START 0x38000000
#define SDRAM_MEM_OFFST 64 * 1024 * 1024
#define PSRAM_MEM_START 0x40000000
#define PSRAM_MEM_OFFST 8 * 1024 * 1024 * PSRAM_NUM
#define OPIPSRAM_MEM_START 0x48000000
#define OPIPSRAM_MEM_OFFST 32 * 1024 * 1024
#define XPI_MEM_START 0x50000000
#define XPI_MEM_OFFST 256 * 1024 * 1024
#define TF_CARD_START (uint32_t)0x60000000
#define TF_CARD_OFFST (uint32_t)0x40000000
// gpio
#define reg_gpio_oe (*(volatile uint32_t*)0x10000000)
#define reg_gpio_cs (*(volatile uint32_t*)0x10000004)
#define reg_gpio_pu (*(volatile uint32_t*)0x10000008)
#define reg_gpio_pd (*(volatile uint32_t*)0x1000000c)
#define reg_gpio_do (*(volatile uint32_t*)0x10000010)
#define reg_gpio_di (*(volatile uint32_t*)0x10000014)
#define reg_gpio_ien (*(volatile uint32_t*)0x10000018)
#define reg_gpio_itype0 (*(volatile uint32_t*)0x1000001c)
#define reg_gpio_itype1 (*(volatile uint32_t*)0x10000020)
#define reg_gpio_istat (*(volatile uint32_t*)0x10000024)
#define reg_gpio_iofcfg (*(volatile uint32_t*)0x10000028)
#define reg_gpio_pinmux (*(volatile uint32_t*)0x1000002c)
// uart0
#define reg_uart0_clkdiv (*(volatile uint32_t*)0x10001000)
#define reg_uart0_data (*(volatile uint32_t*)0x10001004)
// tim0
#define reg_tim0_cfg (*(volatile uint32_t*)0x10002000)
#define reg_tim0_rld (*(volatile uint32_t*)0x10002004)
#define reg_tim0_val (*(volatile uint32_t*)0x10002008)
// tim1
#define reg_tim1_cfg (*(volatile uint32_t*)0x10003000)
#define reg_tim1_rld (*(volatile uint32_t*)0x10003004)
#define reg_tim1_val (*(volatile uint32_t*)0x10003008)
// psram
#define reg_psram_wait (*(volatile uint32_t*)0x10004000)
#define reg_psram_chd (*(volatile uint32_t*)0x10004004)
#define reg_psram_init (*(volatile uint32_t*)0x10004008)
// spisd
#define reg_spisd_mode (*(volatile uint32_t*)0x10005000)
#define reg_spisd_clkdiv (*(volatile uint32_t*)0x10005004)
#define reg_spisd_addr (*(volatile uint32_t*)0x10005008)
#define reg_spisd_txdata (*(volatile uint32_t*)0x1000500C)
#define reg_spisd_rxdata (*(volatile uint32_t*)0x10005010)
#define reg_spisd_status (*(volatile uint32_t*)0x10005014)
#define reg_spisd_sync (*(volatile uint32_t*)0x10005018)
// i2c0
#define reg_i2c0_clkdiv (*(volatile uint32_t*)0x10006000)
#define reg_i2c0_devaddr (*(volatile uint32_t*)0x10006004)
#define reg_i2c0_regaddr (*(volatile uint32_t*)0x10006008)
#define reg_i2c0_txdata (*(volatile uint32_t*)0x1000600C)
#define reg_i2c0_rxdata (*(volatile uint32_t*)0x10006010)
#define reg_i2c0_xfer (*(volatile uint32_t*)0x10006014)
#define reg_i2c0_cfg (*(volatile uint32_t*)0x10006018)
#define reg_i2c0_status (*(volatile uint32_t*)0x1000601C)
// i2s
#define reg_i2s_mode (*(volatile uint32_t*)0x10007000)
#define reg_i2s_format (*(volatile uint32_t*)0x10007004)
#define reg_i2s_upbound (*(volatile uint32_t*)0x10007008)
#define reg_i2s_lowbound (*(volatile uint32_t*)0x1000700C)
#define reg_i2s_recven (*(volatile uint32_t*)0x10007010)
#define reg_i2s_txdata (*(volatile uint32_t*)0x10007014)
#define reg_i2s_rxdata (*(volatile uint32_t*)0x10007018)
#define reg_i2s_status (*(volatile uint32_t*)0x1000701C)
// onewire
#define reg_onewire_clkdiv (*(volatile uint32_t*)0x10008000)
#define reg_onewire_zerocnt (*(volatile uint32_t*)0x10008004)
#define reg_onewire_onecnt (*(volatile uint32_t*)0x10008008)
#define reg_onewire_rstcnt (*(volatile uint32_t*)0x1000800C)
#define reg_onewire_txdata (*(volatile uint32_t*)0x10008010)
#define reg_onewire_ctrl (*(volatile uint32_t*)0x10008014)
#define reg_onewire_status (*(volatile uint32_t*)0x10008018)
// xpi
#define reg_xpi_cfgidx (*(volatile uint32_t*)0x10009000)
#define reg_xpi_accmd (*(volatile uint32_t*)0x10009004)
#define reg_xpi_mmstad (*(volatile uint32_t*)0x10009008)
#define reg_xpi_mmoffst (*(volatile uint32_t*)0x1000900C)
#define reg_xpi_mode (*(volatile uint32_t*)0x10009010)
#define reg_xpi_nss (*(volatile uint32_t*)0x10009014)
#define reg_xpi_clkdiv (*(volatile uint32_t*)0x10009018)
#define reg_xpi_rdwr (*(volatile uint32_t*)0x1000901C)
#define reg_xpi_revdat (*(volatile uint32_t*)0x10009020)
#define reg_xpi_txupb (*(volatile uint32_t*)0x10009024)
#define reg_xpi_txlowb (*(volatile uint32_t*)0x10009028)
#define reg_xpi_rxupb (*(volatile uint32_t*)0x1000902C)
#define reg_xpi_rxlowb (*(volatile uint32_t*)0x10009030)
#define reg_xpi_flush (*(volatile uint32_t*)0x10009034)
#define reg_xpi_cmdtyp (*(volatile uint32_t*)0x10009038)
#define reg_xpi_cmdlen (*(volatile uint32_t*)0x1000903C)
#define reg_xpi_cmddat (*(volatile uint32_t*)0x10009040)
#define reg_xpi_adrtyp (*(volatile uint32_t*)0x10009044)
#define reg_xpi_adrlen (*(volatile uint32_t*)0x10009048)
#define reg_xpi_adrdat (*(volatile uint32_t*)0x1000904C)
#define reg_xpi_alttyp (*(volatile uint32_t*)0x10009050)
#define reg_xpi_altlen (*(volatile uint32_t*)0x10009054)
#define reg_xpi_altdat (*(volatile uint32_t*)0x10009058)
#define reg_xpi_tdulen (*(volatile uint32_t*)0x1000905C)
#define reg_xpi_rdulen (*(volatile uint32_t*)0x10009060)
#define reg_xpi_dattyp (*(volatile uint32_t*)0x10009064)
#define reg_xpi_datlen (*(volatile uint32_t*)0x10009068)
#define reg_xpi_datbit (*(volatile uint32_t*)0x1000906C)
#define reg_xpi_hlvlen (*(volatile uint32_t*)0x10009070)
#define reg_xpi_txdata (*(volatile uint32_t*)0x10009074)
#define reg_xpi_rxdata (*(volatile uint32_t*)0x10009078)
#define reg_xpi_start (*(volatile uint32_t*)0x1000907C)
#define reg_xpi_status (*(volatile uint32_t*)0x10009080)
// dma(32b xfer, hardware trigger by I2S fifo, QSPI fifo)
#define reg_dma_mode (*(volatile uint32_t*)0x1000A000)
#define reg_dma_srcaddr (*(volatile uint32_t*)0x1000A004)
#define reg_dma_srcincr (*(volatile uint32_t*)0x1000A008)
#define reg_dma_dstaddr (*(volatile uint32_t*)0x1000A00C)
#define reg_dma_dstincr (*(volatile uint32_t*)0x1000A010)
#define reg_dma_xferlen (*(volatile uint32_t*)0x1000A014)
#define reg_dma_start (*(volatile uint32_t*)0x1000A018)
#define reg_dma_stop (*(volatile uint32_t*)0x1000A01C)
#define reg_dma_reset (*(volatile uint32_t*)0x1000A020)
#define reg_dma_status (*(volatile uint32_t*)0x1000A024)
#define reg_dma_fsm (*(volatile uint32_t*)0x1000A028)
// sys ctrl
#define reg_sysctrl_coresel (*(volatile uint32_t*)0x1000B000)
#define reg_sysctrl_ipsel (*(volatile uint32_t*)0x1000B004)
#define reg_sysctrl_i2csel (*(volatile uint32_t*)0x1000B008)
#define reg_sysctrl_qspicsel (*(volatile uint32_t*)0x1000B00C)
// clint
#define reg_clint_mtimel (*(volatile uint32_t*)0x1000C000)
#define reg_clint_mtimeh (*(volatile uint32_t*)0x1000C004)
#define reg_clint_mtimecmpl (*(volatile uint32_t*)0x1000C008)
#define reg_clint_mtimecmph (*(volatile uint32_t*)0x1000C00C)
#define reg_clint_msip (*(volatile uint32_t*)0x1000C010)
#define reg_clint_clkdiv (*(volatile uint32_t*)0x1000C014)
// sdram
#define reg_sdram_clkdiv (*(volatile uint32_t*)0x1000D000)
#define reg_sdram_cfg (*(volatile uint32_t*)0x1000D004)
// dvp
#define reg_dvp_recven (*(volatile uint32_t*)0x1000E000)
#define reg_dvp_rxdata (*(volatile uint32_t*)0x1000E004)
#define reg_dvp_status (*(volatile uint32_t*)0x1000E008)
// sdio
#define reg_sdio_cfg (*(volatile uint32_t*)0x1000F000)
// opipsram
#define reg_opipsram_cfg (*(volatile uint32_t*)0x10010000)
// i2c1
#define reg_i2c1_clkdiv (*(volatile uint32_t*)0x10011000)
#define reg_i2c1_devaddr (*(volatile uint32_t*)0x10011004)
#define reg_i2c1_regaddr (*(volatile uint32_t*)0x10011008)
#define reg_i2c1_txdata (*(volatile uint32_t*)0x1001100C)
#define reg_i2c1_rxdata (*(volatile uint32_t*)0x10011010)
#define reg_i2c1_xfer (*(volatile uint32_t*)0x10011014)
#define reg_i2c1_cfg (*(volatile uint32_t*)0x10011018)
#define reg_i2c1_status (*(volatile uint32_t*)0x1001101C)
// ga
#define reg_ga_cfg (*(volatile uint32_t*)0x10012000)
// apu
#define reg_apu_cfg (*(volatile uint32_t*)0x10013000)
// archinfo
#define reg_archinfo_sys (*(volatile uint32_t*)0x20000000)
#define reg_archinfo_idl (*(volatile uint32_t*)0x20000004)
#define reg_archinfo_idh (*(volatile uint32_t*)0x20000008)
// rng
#define reg_rng_ctrl (*(volatile uint32_t*)0x20001000)
#define reg_rng_seed (*(volatile uint32_t*)0x20001004)
#define reg_rng_val (*(volatile uint32_t*)0x20001008)
// uart
#define reg_uart1_lcr (*(volatile uint32_t*)0x20002000)
#define reg_uart1_div (*(volatile uint32_t*)0x20002004)
#define reg_uart1_trx (*(volatile uint32_t*)0x20002008)
#define reg_uart1_fcr (*(volatile uint32_t*)0x2000200c)
#define reg_uart1_lsr (*(volatile uint32_t*)0x20002010)
// pwm
#define reg_pwm_ctrl (*(volatile uint32_t*)0x20003000)
#define reg_pwm_pscr (*(volatile uint32_t*)0x20003004)
#define reg_pwm_cnt (*(volatile uint32_t*)0x20003008)
#define reg_pwm_cmp (*(volatile uint32_t*)0x2000300c)
#define reg_pwm_cr0 (*(volatile uint32_t*)0x20003010)
#define reg_pwm_cr1 (*(volatile uint32_t*)0x20003014)
#define reg_pwm_cr2 (*(volatile uint32_t*)0x20003018)
#define reg_pwm_cr3 (*(volatile uint32_t*)0x2000301c)
#define reg_pwm_stat (*(volatile uint32_t*)0x20003020)
// ps2
#define reg_ps2_ctrl (*(volatile uint32_t*)0x20004000)
#define reg_ps2_data (*(volatile uint32_t*)0x20004004)
#define reg_ps2_stat (*(volatile uint32_t*)0x20004008)
// rtc
#define reg_rtc_ctrl (*(volatile uint32_t*)0x20005000)
#define reg_rtc_pscr (*(volatile uint32_t*)0x20005004)
#define reg_rtc_cnt (*(volatile uint32_t*)0x20005008)
#define reg_rtc_alrm (*(volatile uint32_t*)0x2000500C)
#define reg_rtc_ista (*(volatile uint32_t*)0x20005010)
#define reg_rtc_ssta (*(volatile uint32_t*)0x20005014)
// wdg
#define reg_wdg_ctrl (*(volatile uint32_t*)0x20006000)
#define reg_wdg_pscr (*(volatile uint32_t*)0x20006004)
#define reg_wdg_cnt (*(volatile uint32_t*)0x20006008)
#define reg_wdg_cmp (*(volatile uint32_t*)0x2000600C)
#define reg_wdg_stat (*(volatile uint32_t*)0x20006010)
#define reg_wdg_key (*(volatile uint32_t*)0x20006014)
#define reg_wdg_feed (*(volatile uint32_t*)0x20006018)
// crc
#define reg_crc_ctrl (*(volatile uint32_t*)0x20007000)
#define reg_crc_init (*(volatile uint32_t*)0x20007004)
#define reg_crc_xorv (*(volatile uint32_t*)0x20007008)
#define reg_crc_data (*(volatile uint32_t*)0x2000700C)
#define reg_crc_stat (*(volatile uint32_t*)0x20007010)
// tim3
#define reg_tim3_ctrl (*(volatile uint32_t*)0x20008000)
#define reg_tim3_pscr (*(volatile uint32_t*)0x20008004)
#define reg_tim3_cnt (*(volatile uint32_t*)0x20008008)
#define reg_tim3_cmp (*(volatile uint32_t*)0x2000800C)
#define reg_tim3_stat (*(volatile uint32_t*)0x20008010)
// user ip design(example)
#define reg_user_ip_reg0 (*(volatile uint32_t*)0x2000F000)
#define reg_user_ip_reg1 (*(volatile uint32_t*)0x2000F004)
#define reg_user_ip_reg2 (*(volatile uint32_t*)0x2000F008)
#define reg_user_ip_reg3 (*(volatile uint32_t*)0x2000F00C)
#define reg_user_ip_reg4 (*(volatile uint32_t*)0x2000F010)
#define reg_user_ip_reg5 (*(volatile uint32_t*)0x2000F014)
#define reg_user_ip_reg6 (*(volatile uint32_t*)0x2000F018)
// ... user custom area ...
#endif
-79
View File
@@ -1,79 +0,0 @@
#ifndef LIBDEF_H__
#define LIBDEF_H__
#include <stddef.h>
#include <stdint.h>
#include <firmware.h>
#include <socver.h>
#include <rs_booter.h>
#include <rs_uart.h>
#include <rs_string.h>
#include <rs_printf.h>
#include <rs_gpio.h>
#include <rs_tim.h>
#include <rs_archinfo.h>
#include <rs_rng.h>
#include <rs_hpuart.h>
#include <rs_pwm.h>
#include <rs_ps2.h>
#include <rs_i2c.h>
#include <rs_1wire.h>
#include <rs_dma.h>
#include <rs_lcd.h>
#include <rs_psram.h>
#include <rs_spisd.h>
#include <rs_qspi.h>
#include <rs_i2s.h>
#include <rs_rtc.h>
#include <rs_wdg.h>
#include <rs_crc.h>
#include <rs_advtim.h>
#include <rs_bench.h>
#include <rs_sh.h>
#include <at24cxx.h>
#include <pcf8563b.h>
#include <es8388.h>
#include <w25q128jvxim.h>
#include <wav_audio.h>
#include <video_player.h>
#include <donut.h>
#ifdef CSR_ENABLE
#include <rs_irq.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
// uint32_t system_runtime() {
// uint32_t sys_cycle_val, sys_cycle_valh;
// __asm__ volatile("rdcycle %0" : "=r"(sys_cycle_val));
// __asm__ volatile("rdcycleh %0" : "=r"(sys_cycle_valh));
// if(sys_cycle_valh == 0) return sys_cycle_val * CPU_FREQ / 1000;
// else return (sys_cycle_val) * CPU_FREQ / 1000; // unit: ms
// }
uint32_t *irq_handler(uint32_t *regs, uint32_t irqs);
#define putstr(s) \
({ for (const char *p = s; *p; p++) putch(*p); })
// assert.h
#define assert(cond) \
do \
{ \
if (!(cond)) \
{ \
printf("Assertion fail at %s:%d\n", __FILE__, __LINE__); \
halt(1); \
} \
} while (0)
#ifdef __cplusplus
}
#endif
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef TINY1WIRE_H__
#define TINY1WIRE_H__
void ip_1wire_test(int argc, char **argv);
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef TINYADVTIM_H__
#define TINYADVTIM_H__
void ip_advtim_test();
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef TINYARCHINFO_H__
#define TINYARCHINFO_H__
void ip_archinfo_test(int argc, char **argv);
#endif
-7
View File
@@ -1,7 +0,0 @@
#ifndef TINYBENCH_H__
#define TINYBENCH_H__
#include <stdint.h>
uint32_t tinybench(bool verbose, uint32_t *instns_p);
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef TINYCRC_H__
#define TINYCRC_H__
void ip_crc_test(int argc, char **argv);
#endif
-12
View File
@@ -1,12 +0,0 @@
#ifndef TINYDMA_H__
#define TINYDMA_H__
void dma_config(uint32_t mode, uint32_t src, uint32_t srcincr, uint32_t dst, uint32_t dstincr, uint32_t xferlen);
void dma_start_xfer();
void dma_stop_toggle();
void dma_reset_xfer();
void dma_wait_done();
void ip_dma_test();
#endif
-6
View File
@@ -1,6 +0,0 @@
#ifndef TINYGPIO_H__
#define TINYGPIO_H__
void ip_gpio_test(int argc, char **argv);
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef TINYHPUART_H__
#define TINYHPUART_H__
void ip_hpuart_test(int argc, char **argv);
#endif
-14
View File
@@ -1,14 +0,0 @@
#ifndef TINYI2C_H__
#define TINYI2C_H__
#define I2C0_XFER_WR 0b10
#define I2C0_XFER_RD 0b11
#define I2C_DEV_ADDR_8BIT 0
#define I2C_DEV_ADDR_16BIT 1
void i2c0_init(uint8_t clkdiv);
void i2c0_wr_nbyte(uint8_t dev_addr, uint16_t reg_addr, uint8_t type, uint8_t num, uint8_t *data);
void i2c0_rd_nbyte(uint8_t dev_addr, uint16_t reg_addr, uint8_t type, uint8_t num, uint8_t *data);
#endif
-6
View File
@@ -1,6 +0,0 @@
#ifndef TINYI2S_H__
#define TINYI2S_H__
void ip_i2s_test(int argc, char **argv);
#endif
-6
View File
@@ -1,6 +0,0 @@
#ifndef TINYIRQ_H__
#define TINYIRQ_H__
void irq_test(int argc, char **argv);
#endif
-14
View File
@@ -1,14 +0,0 @@
#ifndef TINYLIB_H__
#define TINYLIB_H__
#define RAND_MAX 32768
int atoi(const char *str);
char *itoa(unsigned int val, char *str, int base);
void *malloc(size_t size);
void free(void *ptr);
int abs(int x);
int rand(void);
void srand(unsigned int seed);
#endif
-11
View File
@@ -1,11 +0,0 @@
#ifndef TINYPRINT_H__
#define TINYPRINT_H__
#include <stdint.h>
void putchar(char c);
char getchar();
void print(const char *p);
#endif
-13
View File
@@ -1,13 +0,0 @@
#ifndef TINYPRINTF_H__
#define TINYPRINTF_H__
#include <stddef.h>
#include <stdarg.h>
int printf(const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef TINYPS2_H__
#define TINYPS2_H__
void ip_ps2_test(int argc, char **argv);
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef TINYPWM_H__
#define TINYPWM_H__
void ip_pwm_test(int argc, char **argv);
#endif
-48
View File
@@ -1,48 +0,0 @@
#ifndef TINYQSPI_H__
#define TINYQSPI_H__
#define USE_QSPI0_DMA
typedef struct {
uint32_t mode;
uint32_t nss;
uint32_t clkdiv;
uint32_t txub;
uint32_t txlb;
uint32_t rxub;
uint32_t rxlb;
uint32_t hlven;
} QSPI0_InitStruct_t;
void qspi0_init(QSPI0_InitStruct_t val);
void qspi0_wr(uint32_t cmdtyp, uint32_t cmdlen, uint32_t cmddat,
uint32_t adrtyp, uint32_t adrlen, uint32_t adrdat,
uint32_t dumlen,
uint32_t dattyp, uint32_t datlen, uint32_t datbit,
uint32_t* dat_list);
void qspi0_rd(uint32_t cmdtyp, uint32_t cmdlen, uint32_t cmddat,
uint32_t adrtyp, uint32_t adrlen, uint32_t adrdat,
uint32_t dumlen,
uint32_t dattyp, uint32_t datlen, uint32_t datbit,
uint32_t* dat_list);
void qspi0_xfer_config(
uint32_t rdwr, uint32_t revdat, uint32_t flush,
uint32_t cmdtyp, uint32_t cmdlen,
uint32_t adrtyp, uint32_t adrlen,
uint32_t dumlen,
uint32_t dattyp, uint32_t datlen, uint32_t datbit
);
void qspi0_wr_cmd8(uint8_t dat);
void qspi0_wr_cmd16(uint16_t dat);
void qspi0_wr_dat8(uint8_t dat);
void qspi0_wr_dat16(uint16_t dat);
void qspi0_wr_data32(uint32_t* dat, uint32_t len);
void qspi0_dma_xfer(uint32_t addr, uint32_t len);
void qspi_dev_init();
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef TINYRNG_H__
#define TINYRNG_H__
void ip_rng_test(int argc, char **argv);
#endif
-5
View File
@@ -1,5 +0,0 @@
#ifndef TINYRTC_H__
#define TINYRTC_H__
void ip_rtc_test(int argc, char **argv);
#endif
-25
View File
@@ -1,25 +0,0 @@
#ifndef TINYSH_H__
#define TINYSH_H__
typedef void (*cmd_handler)(int argc, char **argv);
typedef struct {
char *name;
char *info;
uint8_t batch;
cmd_handler handler;
} tinysh_cmd_t;
#define MAX_CMD_ARGC 16
#define MAX_CMD_NUM 72
#define MAX_CMD_LEN 100
#define MAX_CMD_HIST 100
#define MAX_PATH_LEN 128
#define MAX_BUFFER_LEN 512 * 1024
uint8_t tinysh_register(char *name, char *info, uint8_t batch, void *handler);
void tinysh_init();
void tinysh_batch_run();
void tinysh_launch();
#endif
-10
View File
@@ -1,10 +0,0 @@
#ifndef TINYSPISD_H__
#define TINYSPISD_H__
void spisd_mem_read(uint8_t *buff, uint32_t size, uint32_t count, uint32_t addr);
void spisd_sector_read(uint8_t *buff, uint32_t sector, uint32_t count);
void spisd_sector_write(const uint8_t *buff, uint32_t sector, uint32_t count);
void spisd_sector_sync();
void ip_spisd_test();
void ip_spisd_read(uint32_t addr, uint32_t len);
#endif
-20
View File
@@ -1,20 +0,0 @@
#ifndef TINYSTRING_H__
#define TINYSTRING_H__
#include <stddef.h>
#include <stdint.h>
void *memset(void *s, int c, size_t n);
void *memcpy(void *dst, const void *src, size_t n);
void *memmove(void *dst, const void *src, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
size_t strlen(const char *s);
char *strcat(char *dst, const char *src);
char *strcpy(char *dst, const char *src);
char *strncpy(char *dst, const char *src, size_t n);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
char *strchr(const char *s, int c);
void trim_whitespace(char *str);
void remove_suffix(char *dst, char *src, char sign);
#endif
Loaded 100 of 206 files, more files were not shown because too many files have changed in this diff. Show more