mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
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:
206 files changed
+6338
-5471
No files matched your search
@@ -0,0 +1,10 @@
|
|||||||
|
BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 4
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
|
ColumnLimit: 100
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
PointerAlignment: Right
|
||||||
|
SortIncludes: Never
|
||||||
@@ -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
|
||||||
@@ -31,12 +31,26 @@ jobs:
|
|||||||
- name: Install pinned quality tools
|
- name: Install pinned quality tools
|
||||||
run: python3 -m pip install --requirement requirements/ci.txt
|
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
|
- name: Validate dependency lock
|
||||||
run: python3 scripts/dependency_lock.py --lock config/dependencies.lock.json
|
run: python3 scripts/dependency_lock.py --lock config/dependencies.lock.json
|
||||||
|
|
||||||
- name: Lint Python
|
- name: Lint Python
|
||||||
run: ruff check .
|
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
|
- name: Test scripts
|
||||||
run: python3 -m pytest -q
|
run: python3 -m pytest -q
|
||||||
|
|
||||||
|
|||||||
@@ -48,17 +48,19 @@ RTL_TOP ?= retrosoc_tb
|
|||||||
ISA ?= RV32IM
|
ISA ?= RV32IM
|
||||||
HAVE_CSR ?= NO
|
HAVE_CSR ?= NO
|
||||||
FIRMWARE_NAME ?= retrosoc_fw
|
FIRMWARE_NAME ?= retrosoc_fw
|
||||||
PROG_TYPE ?= FULL
|
APP ?= shell
|
||||||
LINK_TYPE ?= ld2_sram
|
LINK_TYPE ?= ld2_sram
|
||||||
|
|
||||||
BUILD_ROOT ?= $(ROOT_PATH)/build
|
BUILD_ROOT ?= $(ROOT_PATH)/build
|
||||||
CACHE_ROOT ?= $(ROOT_PATH)/.cache/retrosoc
|
CACHE_ROOT ?= $(ROOT_PATH)/.cache/retrosoc
|
||||||
MAX_JOBS ?= 16
|
MAX_JOBS ?= 16
|
||||||
|
HOST_CC ?= cc
|
||||||
|
CLANG_FORMAT ?= clang-format-14
|
||||||
JOBS ?= $(shell count=$$(nproc 2>/dev/null || printf '1'); \
|
JOBS ?= $(shell count=$$(nproc 2>/dev/null || printf '1'); \
|
||||||
if [ "$$count" -gt "$(MAX_JOBS)" ]; then printf '%s' '$(MAX_JOBS)'; \
|
if [ "$$count" -gt "$(MAX_JOBS)" ]; then printf '%s' '$(MAX_JOBS)'; \
|
||||||
else printf '%s' "$$count"; fi)
|
else printf '%s' "$$count"; fi)
|
||||||
CONFIG_KEY_VARS := SOC CORE IP PDK HAVE_PLL HAVE_SRAM_IF HAVE_SRAM_MACRO HAVE_SVA \
|
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 \
|
VARIANT_ID := $(strip $(shell python3 $(ROOT_PATH)/scripts/config_key.py \
|
||||||
--lock $(LOCK_FILE) --profile $(PROFILE_NAME) \
|
--lock $(LOCK_FILE) --profile $(PROFILE_NAME) \
|
||||||
$(foreach var,$(CONFIG_KEY_VARS),--value $(var)=$($(var)))))
|
$(foreach var,$(CONFIG_KEY_VARS),--value $(var)=$($(var)))))
|
||||||
@@ -88,7 +90,7 @@ VALID_STA := NONE OPENSTA
|
|||||||
VALID_PDK := ICS55 IHP130 SKY130 GF180
|
VALID_PDK := ICS55 IHP130 SKY130 GF180
|
||||||
VALID_BOOL := YES NO
|
VALID_BOOL := YES NO
|
||||||
VALID_ISA := RV32E RV32I RV32IM
|
VALID_ISA := RV32E RV32I RV32IM
|
||||||
VALID_PROG_TYPE := BASE FULL
|
VALID_APP := bringup shell
|
||||||
VALID_LINK_TYPE := xip ld2_sram ld2_psram ld2_sdram
|
VALID_LINK_TYPE := xip ld2_sram ld2_psram ld2_sdram
|
||||||
|
|
||||||
define validate_value
|
define validate_value
|
||||||
@@ -109,7 +111,7 @@ $(call validate_value,HAVE_SVA,$(VALID_BOOL))
|
|||||||
$(call validate_value,WAVE,$(VALID_BOOL))
|
$(call validate_value,WAVE,$(VALID_BOOL))
|
||||||
$(call validate_value,ISA,$(VALID_ISA))
|
$(call validate_value,ISA,$(VALID_ISA))
|
||||||
$(call validate_value,HAVE_CSR,$(VALID_BOOL))
|
$(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))
|
$(call validate_value,LINK_TYPE,$(VALID_LINK_TYPE))
|
||||||
|
|
||||||
ifeq ($(SYNTH),YOSYS)
|
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 \
|
.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 \
|
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
|
.NOTPARALLEL: setup
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@@ -178,6 +180,10 @@ help:
|
|||||||
' config | manifest print/write the effective configuration' \
|
' config | manifest print/write the effective configuration' \
|
||||||
' check-warnings | metrics analyze flow logs and reports' \
|
' check-warnings | metrics analyze flow logs and reports' \
|
||||||
' check-metrics apply the committed metrics policy' \
|
' 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' \
|
' regress-pr | regress-nightly run supported regression suites' \
|
||||||
' package create checksummed source deliverables' \
|
' package create checksummed source deliverables' \
|
||||||
' clean | clean-all clean current flow or all build output' \
|
' clean | clean-all clean current flow or all build output' \
|
||||||
@@ -194,7 +200,7 @@ config:
|
|||||||
SIMU '$(SIMU)' SYNTH '$(SYNTH)' STA '$(STA)' PDK '$(PDK)' \
|
SIMU '$(SIMU)' SYNTH '$(SYNTH)' STA '$(STA)' PDK '$(PDK)' \
|
||||||
HAVE_PLL '$(HAVE_PLL)' HAVE_SRAM_IF '$(HAVE_SRAM_IF)' \
|
HAVE_PLL '$(HAVE_PLL)' HAVE_SRAM_IF '$(HAVE_SRAM_IF)' \
|
||||||
HAVE_SRAM_MACRO '$(HAVE_SRAM_MACRO)' HAVE_SVA '$(HAVE_SVA)' \
|
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)'
|
LINK_TYPE '$(LINK_TYPE)'
|
||||||
|
|
||||||
doctor:
|
doctor:
|
||||||
@@ -251,6 +257,20 @@ check-metrics: metrics
|
|||||||
--policy $(ROOT_PATH)/quality/metrics/policy.json \
|
--policy $(ROOT_PATH)/quality/metrics/policy.json \
|
||||||
--baseline $(ROOT_PATH)/quality/metrics/baseline.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
|
package: $(MPW_VARIANT_STAMP) $(FILELIST_STAMP) manifest
|
||||||
python3 $(ROOT_PATH)/scripts/package.py --root $(ROOT_PATH) --lock $(LOCK_FILE) \
|
python3 $(ROOT_PATH)/scripts/package.py --root $(ROOT_PATH) --lock $(LOCK_FILE) \
|
||||||
--variant-root $(VARIANT_ROOT) --output-dir $(ROOT_PATH)/dist/$(VARIANT_ID)
|
--variant-root $(VARIANT_ROOT) --output-dir $(ROOT_PATH)/dist/$(VARIANT_ID)
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
APP_SRCS += $(ROOT_PATH)/app/apps/bringup/main.c
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#ifndef AT24C64_H__
|
|
||||||
#define AT24C64_H__
|
|
||||||
|
|
||||||
#define I2C_TEST_NUM 24
|
|
||||||
#define AT24C64_DEV_ADDR 0x50
|
|
||||||
|
|
||||||
void at24cxx_test();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#ifndef DONUT_H__
|
|
||||||
#define DONUT_H__
|
|
||||||
|
|
||||||
void donut_test();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#ifndef ES8388_H__
|
|
||||||
#define ES8388_H__
|
|
||||||
|
|
||||||
#define ES8388_DEV_ADDR 0x10
|
|
||||||
|
|
||||||
void es8388_init();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef W25Q128JVXIM_H__
|
|
||||||
#define W25Q128JVXIM_H__
|
|
||||||
|
|
||||||
void ip_norflash_test(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
@@ -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
|
|
||||||
@@ -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");
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
@@ -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");
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
@@ -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 "coremark.h"
|
||||||
#include "core_portme.h"
|
#include "core_portme.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <rs_tim.h>
|
#include <retrosoc/hal/timer.h>
|
||||||
|
|
||||||
#if VALIDATION_RUN
|
#if VALIDATION_RUN
|
||||||
volatile ee_s32 seed1_volatile = 0x3415;
|
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
|
cpu clock cycles performance counter etc. Sample implementation for standard
|
||||||
time.h and windows.h definitions included.
|
time.h and windows.h definitions included.
|
||||||
*/
|
*/
|
||||||
CORETIMETYPE
|
static CORETIMETYPE barebones_clock(void) {
|
||||||
barebones_clock()
|
|
||||||
{
|
|
||||||
return tim1_get_value();
|
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
|
/* Define : TIMER_RES_DIVIDER
|
||||||
Divider to trade off timer resolution and total time that can be
|
Divider to trade off timer resolution and total time that can be
|
||||||
@@ -57,12 +56,12 @@ barebones_clock()
|
|||||||
does not occur. If there are issues with the return value overflowing,
|
does not occur. If there are issues with the return value overflowing,
|
||||||
increase this value.
|
increase this value.
|
||||||
*/
|
*/
|
||||||
#define CLOCKS_PER_SEC 72000000
|
#define CLOCKS_PER_SEC 72000000
|
||||||
#define GETMYTIME(_t) (*_t = barebones_clock())
|
#define GETMYTIME(_t) (*_t = barebones_clock())
|
||||||
#define MYTIMEDIFF(fin, ini) ((fin) - (ini))
|
#define MYTIMEDIFF(fin, ini) ((fin) - (ini))
|
||||||
#define TIMER_RES_DIVIDER 1
|
#define TIMER_RES_DIVIDER 1
|
||||||
#define SAMPLE_TIME_IMPLEMENTATION 1
|
#define SAMPLE_TIME_IMPLEMENTATION 1
|
||||||
#define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER)
|
#define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER)
|
||||||
|
|
||||||
/** Define Host specific (POSIX), or target specific global time variables. */
|
/** Define Host specific (POSIX), or target specific global time variables. */
|
||||||
static CORETIMETYPE start_time_val, stop_time_val;
|
static CORETIMETYPE start_time_val, stop_time_val;
|
||||||
@@ -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
|
example code) or zeroing some system parameters - e.g. setting the cpu clocks
|
||||||
cycles to 0.
|
cycles to 0.
|
||||||
*/
|
*/
|
||||||
void
|
void start_time(void) {
|
||||||
start_time(void)
|
|
||||||
{
|
|
||||||
GETMYTIME(&start_time_val);
|
GETMYTIME(&start_time_val);
|
||||||
}
|
}
|
||||||
/* Function : stop_time
|
/* Function : stop_time
|
||||||
@@ -88,9 +85,7 @@ start_time(void)
|
|||||||
example code) or other system parameters - e.g. reading the current value of
|
example code) or other system parameters - e.g. reading the current value of
|
||||||
cpu cycles counter.
|
cpu cycles counter.
|
||||||
*/
|
*/
|
||||||
void
|
void stop_time(void) {
|
||||||
stop_time(void)
|
|
||||||
{
|
|
||||||
GETMYTIME(&stop_time_val);
|
GETMYTIME(&stop_time_val);
|
||||||
}
|
}
|
||||||
/* Function : get_time
|
/* Function : get_time
|
||||||
@@ -103,10 +98,8 @@ stop_time(void)
|
|||||||
controlled by <TIMER_RES_DIVIDER>
|
controlled by <TIMER_RES_DIVIDER>
|
||||||
*/
|
*/
|
||||||
CORE_TICKS
|
CORE_TICKS
|
||||||
get_time(void)
|
get_time(void) {
|
||||||
{
|
CORE_TICKS elapsed = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
|
||||||
CORE_TICKS elapsed
|
|
||||||
= (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
|
|
||||||
return elapsed;
|
return elapsed;
|
||||||
}
|
}
|
||||||
/* Function : time_in_secs
|
/* Function : time_in_secs
|
||||||
@@ -116,9 +109,7 @@ get_time(void)
|
|||||||
floating point. Default implementation implemented by the EE_TICKS_PER_SEC
|
floating point. Default implementation implemented by the EE_TICKS_PER_SEC
|
||||||
macro above.
|
macro above.
|
||||||
*/
|
*/
|
||||||
secs_ret
|
secs_ret time_in_secs(CORE_TICKS ticks) {
|
||||||
time_in_secs(CORE_TICKS ticks)
|
|
||||||
{
|
|
||||||
secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
|
secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -129,23 +120,19 @@ ee_u32 default_num_contexts = 1;
|
|||||||
Target specific initialization code
|
Target specific initialization code
|
||||||
Test for some common mistakes.
|
Test for some common mistakes.
|
||||||
*/
|
*/
|
||||||
void
|
void portable_init(core_portable *p, int *argc, char *argv[]) {
|
||||||
portable_init(core_portable *p, int *argc, char *argv[])
|
// #error "Call board initialization routines in portable init (if needed), in particular
|
||||||
{
|
// initialize UART!\n"
|
||||||
// #error "Call board initialization routines in portable init (if needed), in particular initialize UART!\n"
|
|
||||||
|
|
||||||
(void)argc; // prevent unused warning
|
(void)argc; // prevent unused warning
|
||||||
(void)argv; // prevent unused warning
|
(void)argv; // prevent unused warning
|
||||||
tim1_init();
|
tim1_init();
|
||||||
|
|
||||||
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *))
|
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) {
|
||||||
{
|
ee_printf("ERROR! Please define ee_ptr_int to a type that holds a "
|
||||||
ee_printf(
|
"pointer!\n");
|
||||||
"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");
|
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
|
||||||
}
|
}
|
||||||
p->portable_id = 1;
|
p->portable_id = 1;
|
||||||
@@ -153,8 +140,6 @@ portable_init(core_portable *p, int *argc, char *argv[])
|
|||||||
/* Function : portable_fini
|
/* Function : portable_fini
|
||||||
Target specific final code
|
Target specific final code
|
||||||
*/
|
*/
|
||||||
void
|
void portable_fini(core_portable *p) {
|
||||||
portable_fini(core_portable *p)
|
|
||||||
{
|
|
||||||
p->portable_id = 0;
|
p->portable_id = 0;
|
||||||
}
|
}
|
||||||
@@ -76,8 +76,7 @@ int core_main(void);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef COMPILER_FLAGS
|
#ifndef COMPILER_FLAGS
|
||||||
#define COMPILER_FLAGS \
|
#define COMPILER_FLAGS "-o3" /* "Please put compiler flags here (e.g. -o3)" */
|
||||||
"-o3" /* "Please put compiler flags here (e.g. -o3)" */
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef MEM_LOCATION
|
#ifndef MEM_LOCATION
|
||||||
#define MEM_LOCATION "STACK"
|
#define MEM_LOCATION "STACK"
|
||||||
@@ -91,14 +90,14 @@ int core_main(void);
|
|||||||
ee_ptr_int needs to be the data type used to hold pointers, otherwise
|
ee_ptr_int needs to be the data type used to hold pointers, otherwise
|
||||||
coremark may fail!!!
|
coremark may fail!!!
|
||||||
*/
|
*/
|
||||||
typedef signed short ee_s16;
|
typedef signed short ee_s16;
|
||||||
typedef unsigned short ee_u16;
|
typedef unsigned short ee_u16;
|
||||||
typedef signed int ee_s32;
|
typedef signed int ee_s32;
|
||||||
typedef double ee_f32;
|
typedef double ee_f32;
|
||||||
typedef unsigned char ee_u8;
|
typedef unsigned char ee_u8;
|
||||||
typedef unsigned int ee_u32;
|
typedef unsigned int ee_u32;
|
||||||
typedef ee_u32 ee_ptr_int;
|
typedef ee_u32 ee_ptr_int;
|
||||||
typedef size_t ee_size_t;
|
typedef size_t ee_size_t;
|
||||||
#define NULL ((void *)0)
|
#define NULL ((void *)0)
|
||||||
/* align_mem :
|
/* align_mem :
|
||||||
This macro is used to align an offset to point to a 32b value. It is
|
This macro is used to align an offset to point to a 32b value. It is
|
||||||
@@ -157,8 +156,8 @@ typedef ee_u32 CORE_TICKS;
|
|||||||
#ifndef MULTITHREAD
|
#ifndef MULTITHREAD
|
||||||
#define MULTITHREAD 1
|
#define MULTITHREAD 1
|
||||||
#define USE_PTHREAD 0
|
#define USE_PTHREAD 0
|
||||||
#define USE_FORK 0
|
#define USE_FORK 0
|
||||||
#define USE_SOCKET 0
|
#define USE_SOCKET 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration : MAIN_HAS_NOARGC
|
/* Configuration : MAIN_HAS_NOARGC
|
||||||
@@ -192,8 +191,7 @@ typedef ee_u32 CORE_TICKS;
|
|||||||
*/
|
*/
|
||||||
extern ee_u32 default_num_contexts;
|
extern ee_u32 default_num_contexts;
|
||||||
|
|
||||||
typedef struct CORE_PORTABLE_S
|
typedef struct CORE_PORTABLE_S {
|
||||||
{
|
|
||||||
ee_u8 portable_id;
|
ee_u8 portable_id;
|
||||||
} core_portable;
|
} core_portable;
|
||||||
|
|
||||||
@@ -201,8 +199,7 @@ typedef struct CORE_PORTABLE_S
|
|||||||
void portable_init(core_portable *p, int *argc, char *argv[]);
|
void portable_init(core_portable *p, int *argc, char *argv[]);
|
||||||
void portable_fini(core_portable *p);
|
void portable_fini(core_portable *p);
|
||||||
|
|
||||||
#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) \
|
#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN)
|
||||||
&& !defined(VALIDATION_RUN)
|
|
||||||
#if (TOTAL_DATA_SIZE == 1200)
|
#if (TOTAL_DATA_SIZE == 1200)
|
||||||
#define PROFILE_RUN 1
|
#define PROFILE_RUN 1
|
||||||
#elif (TOTAL_DATA_SIZE == 2000)
|
#elif (TOTAL_DATA_SIZE == 2000)
|
||||||
@@ -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
|
||||||
@@ -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 <retrosoc/core/soc.h>
|
||||||
#include <rs_printf.h>
|
#include <retrosoc/lib/printf.h>
|
||||||
#include <rs_i2c.h>
|
#include <retrosoc/hal/i2c.h>
|
||||||
#include <es8388.h>
|
#include <retrosoc/board/es8388.h>
|
||||||
|
|
||||||
#define ES8388_PHONE_VOLUME 3
|
#define ES8388_PHONE_VOLUME 3
|
||||||
#define ES8388_SPEAK_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)0x80,
|
||||||
(uint8_t)0, (uint8_t)0x00,
|
(uint8_t)0, (uint8_t)0x00,
|
||||||
(uint8_t)1, (uint8_t)0x58,
|
(uint8_t)1, (uint8_t)0x58,
|
||||||
@@ -38,16 +38,25 @@ uint8_t es8388_init_cfg[] = {
|
|||||||
(uint8_t)49, (uint8_t)ES8388_SPEAK_VOLUME,
|
(uint8_t)49, (uint8_t)ES8388_SPEAK_VOLUME,
|
||||||
};
|
};
|
||||||
|
|
||||||
void es8388_init() {
|
void es8388_init(void) {
|
||||||
int init_cfg_len = sizeof(es8388_init_cfg)/sizeof(uint8_t);
|
const uint32_t init_cfg_len = sizeof(es8388_init_cfg) / sizeof(es8388_init_cfg[0]);
|
||||||
printf("[ES8388] init cfg len: %d\n", init_cfg_len);
|
|
||||||
for(int i = 0; i < init_cfg_len; i += 2) {
|
printf("[ES8388] init cfg len: %u\n", init_cfg_len);
|
||||||
i2c0_wr_nbyte(ES8388_DEV_ADDR, (uint16_t)es8388_init_cfg[i], I2C_DEV_ADDR_8BIT, 1, es8388_init_cfg + i + 1);
|
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};
|
uint8_t rxdata[60] = {0};
|
||||||
i2c0_rd_nbyte(ES8388_DEV_ADDR, (uint16_t)0, I2C_DEV_ADDR_8BIT, 53, rxdata);
|
if (rs_i2c0_read(ES8388_DEV_ADDR, 0U, RS_I2C_DEVICE_ADDRESS_8BIT, 53U, rxdata,
|
||||||
for(int i = 0; i < 53; ++i) {
|
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]);
|
printf("[ES8388] reg: %d val:%x\n", i, rxdata[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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
|
|
||||||
@@ -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 */
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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/
|
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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. */
|
/ 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_MON 1
|
||||||
#define FF_NORTC_MDAY 1
|
#define FF_NORTC_MDAY 1
|
||||||
#define FF_NORTC_YEAR 2025
|
#define FF_NORTC_YEAR 2025
|
||||||
@@ -1,27 +1,27 @@
|
|||||||
#include <firmware.h>
|
#include <retrosoc/core/soc.h>
|
||||||
#include <rs_printf.h>
|
#include <retrosoc/lib/printf.h>
|
||||||
#include <rs_tim.h>
|
#include <retrosoc/hal/timer.h>
|
||||||
#include <userip.h>
|
#include <userip.h>
|
||||||
|
|
||||||
|
|
||||||
void userip_main(int argc, char **argv) {
|
void userip_main(int argc, char **argv) {
|
||||||
// user custom area HACK:
|
// user custom area HACK:
|
||||||
(void)argv;
|
(void)argv;
|
||||||
if(argc == 0) {
|
if (argc == 0) {
|
||||||
printf("[FIXED IP] archinfo test\n");
|
printf("[FIXED IP] archinfo test\n");
|
||||||
printf("[ARCHINFO SYS] %x\n", reg_user_ip_reg0);
|
printf("[ARCHINFO SYS] %x\n", reg_user_ip_reg0);
|
||||||
printf("[ARCHINFO IDL] %x\n", reg_user_ip_reg1);
|
printf("[ARCHINFO IDL] %x\n", reg_user_ip_reg1);
|
||||||
printf("[ARCHINFO IDH] %x\n", reg_user_ip_reg2);
|
printf("[ARCHINFO IDH] %x\n", reg_user_ip_reg2);
|
||||||
} else if(argc == 1) {
|
} else if (argc == 1) {
|
||||||
reg_user_ip_reg1 = 2;
|
reg_user_ip_reg1 = 2;
|
||||||
printf("div val: %x\n", reg_user_ip_reg1);
|
printf("div val: %x\n", reg_user_ip_reg1);
|
||||||
reg_user_ip_reg2 = 0;
|
reg_user_ip_reg2 = 0;
|
||||||
for(int i = 0; i < 6; ++i) printf("tim val: %d\n", reg_user_ip_reg2);
|
for (int i = 0; i < 6; ++i)
|
||||||
} else if(argc == 2) {
|
printf("tim val: %d\n", reg_user_ip_reg2);
|
||||||
|
} else if (argc == 2) {
|
||||||
printf("[reg0] %x\n", reg_user_ip_reg0);
|
printf("[reg0] %x\n", reg_user_ip_reg0);
|
||||||
reg_user_ip_reg1 = (uint32_t)0xfffe;
|
reg_user_ip_reg1 = (uint32_t)0xfffe;
|
||||||
printf("do val: %x\n", reg_user_ip_reg5);
|
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);
|
delay_ms(1);
|
||||||
reg_user_ip_reg5 = ~reg_user_ip_reg5;
|
reg_user_ip_reg5 = ~reg_user_ip_reg5;
|
||||||
printf("[%d]do val: %x\n", i, 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);
|
printf("pd val: %x\n", reg_user_ip_reg4);
|
||||||
|
|
||||||
reg_user_ip_reg1 = (uint32_t)0xfffe;
|
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);
|
printf("[%d]di val: %x\n", i, reg_user_ip_reg6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,4 +2,4 @@
|
|||||||
#define USERIP_H__
|
#define USERIP_H__
|
||||||
|
|
||||||
void userip_main(int argc, char **argv);
|
void userip_main(int argc, char **argv);
|
||||||
#endif
|
#endif
|
||||||
@@ -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 "lv_port_disp.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <rs_lcd.h>
|
#include <retrosoc/hal/lcd.h>
|
||||||
#include <rs_printf.h>
|
#include <retrosoc/lib/printf.h>
|
||||||
|
|
||||||
#define MY_DISP_HOR_RES 240
|
#define MY_DISP_HOR_RES 240
|
||||||
#define MY_DISP_VER_RES 135
|
#define MY_DISP_VER_RES 135
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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
|
||||||
+7
-7
@@ -14,7 +14,7 @@ from scripts.setup_helpers import atomic_write, download_file, ensure_git_repo
|
|||||||
|
|
||||||
|
|
||||||
APP_DIR = Path(__file__).resolve().parent
|
APP_DIR = Path(__file__).resolve().parent
|
||||||
FATFS_DIR = APP_DIR / "fatfs"
|
FATFS_DIR = APP_DIR / "middleware/fatfs"
|
||||||
COREMARK_DIR = APP_DIR / "coremark/coremark-main"
|
COREMARK_DIR = APP_DIR / "coremark/coremark-main"
|
||||||
|
|
||||||
|
|
||||||
@@ -30,9 +30,9 @@ def patch_fatfs(source: Path) -> None:
|
|||||||
fatfs_source = source / "ff.c"
|
fatfs_source = source / "ff.c"
|
||||||
content = fatfs_source.read_text(encoding="utf-8")
|
content = fatfs_source.read_text(encoding="utf-8")
|
||||||
original_content = content
|
original_content = content
|
||||||
include = "#include <rs_string.h>"
|
include = "#include <retrosoc/lib/string.h>"
|
||||||
if include not in content:
|
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:
|
if legacy_include in content:
|
||||||
content = content.replace(legacy_include, include)
|
content = content.replace(legacy_include, include)
|
||||||
break
|
break
|
||||||
@@ -46,10 +46,10 @@ def patch_coremark() -> None:
|
|||||||
header = COREMARK_DIR / "coremark.h"
|
header = COREMARK_DIR / "coremark.h"
|
||||||
content = header.read_text(encoding="utf-8")
|
content = header.read_text(encoding="utf-8")
|
||||||
original_content = content
|
original_content = content
|
||||||
include = "#include <rs_printf.h>"
|
include = "#include <retrosoc/lib/printf.h>"
|
||||||
legacy_include = "#include <tinyprintf.h>"
|
for legacy_include in ("#include <tinyprintf.h>", "#include <rs_printf.h>"):
|
||||||
if legacy_include in content:
|
if legacy_include in content:
|
||||||
content = content.replace(legacy_include, include)
|
content = content.replace(legacy_include, include)
|
||||||
if include not in content:
|
if include not in content:
|
||||||
marker = '#include "core_portme.h"'
|
marker = '#include "core_portme.h"'
|
||||||
if marker not in content:
|
if marker not in content:
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
||||||
@@ -8,5 +8,5 @@ HAVE_SRAM_MACRO := NO
|
|||||||
HAVE_SVA := NO
|
HAVE_SVA := NO
|
||||||
ISA := RV32IM
|
ISA := RV32IM
|
||||||
HAVE_CSR := NO
|
HAVE_CSR := NO
|
||||||
PROG_TYPE := BASE
|
APP := bringup
|
||||||
LINK_TYPE := ld2_psram
|
LINK_TYPE := ld2_psram
|
||||||
@@ -8,5 +8,5 @@ HAVE_SRAM_MACRO := NO
|
|||||||
HAVE_SVA := NO
|
HAVE_SVA := NO
|
||||||
ISA := RV32IM
|
ISA := RV32IM
|
||||||
HAVE_CSR := NO
|
HAVE_CSR := NO
|
||||||
PROG_TYPE := BASE
|
APP := bringup
|
||||||
LINK_TYPE := ld2_psram
|
LINK_TYPE := ld2_psram
|
||||||
@@ -8,5 +8,5 @@ HAVE_SRAM_MACRO := NO
|
|||||||
HAVE_SVA := NO
|
HAVE_SVA := NO
|
||||||
ISA := RV32IM
|
ISA := RV32IM
|
||||||
HAVE_CSR := NO
|
HAVE_CSR := NO
|
||||||
PROG_TYPE := BASE
|
APP := bringup
|
||||||
LINK_TYPE := ld2_psram
|
LINK_TYPE := ld2_psram
|
||||||
@@ -8,5 +8,5 @@ HAVE_SRAM_MACRO := NO
|
|||||||
HAVE_SVA := NO
|
HAVE_SVA := NO
|
||||||
ISA := RV32IM
|
ISA := RV32IM
|
||||||
HAVE_CSR := NO
|
HAVE_CSR := NO
|
||||||
PROG_TYPE := BASE
|
APP := bringup
|
||||||
LINK_TYPE := ld2_psram
|
LINK_TYPE := ld2_psram
|
||||||
@@ -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).
|
||||||
@@ -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.
@@ -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;
|
||||||
|
}
|
||||||
@@ -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.
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
// binary, for any purpose, commercial or non-commercial, and by any
|
||||||
// means.
|
// means.
|
||||||
|
|
||||||
#include <firmware.h>
|
#include <retrosoc/core/soc.h>
|
||||||
#include <libdef.h>
|
#include <libdef.h>
|
||||||
|
|
||||||
// user custom area
|
// user custom area
|
||||||
File renamed without changes.
@@ -2,7 +2,7 @@
|
|||||||
.global _start
|
.global _start
|
||||||
.type _start,@function
|
.type _start,@function
|
||||||
|
|
||||||
#include "system_csr.h"
|
#include "retrosoc/arch/riscv/system_csr.h"
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
#ifdef CSR_ENABLE
|
#ifdef CSR_ENABLE
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
// See the Mulan PSL v2 for more details.
|
// See the Mulan PSL v2 for more details.
|
||||||
|
|
||||||
#include <system_csr.h>
|
#include <retrosoc/arch/riscv/system_csr.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Global interrupt disabled
|
* \brief Global interrupt disabled
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef TINY1WIRE_H__
|
|
||||||
#define TINY1WIRE_H__
|
|
||||||
|
|
||||||
void ip_1wire_test(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef TINYADVTIM_H__
|
|
||||||
#define TINYADVTIM_H__
|
|
||||||
|
|
||||||
void ip_advtim_test();
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef TINYARCHINFO_H__
|
|
||||||
#define TINYARCHINFO_H__
|
|
||||||
|
|
||||||
void ip_archinfo_test(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#ifndef TINYBENCH_H__
|
|
||||||
#define TINYBENCH_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
uint32_t tinybench(bool verbose, uint32_t *instns_p);
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef TINYCRC_H__
|
|
||||||
#define TINYCRC_H__
|
|
||||||
|
|
||||||
void ip_crc_test(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
@@ -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
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#ifndef TINYGPIO_H__
|
|
||||||
#define TINYGPIO_H__
|
|
||||||
|
|
||||||
void ip_gpio_test(int argc, char **argv);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef TINYHPUART_H__
|
|
||||||
#define TINYHPUART_H__
|
|
||||||
|
|
||||||
void ip_hpuart_test(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
@@ -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
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#ifndef TINYI2S_H__
|
|
||||||
#define TINYI2S_H__
|
|
||||||
|
|
||||||
void ip_i2s_test(int argc, char **argv);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#ifndef TINYIRQ_H__
|
|
||||||
#define TINYIRQ_H__
|
|
||||||
|
|
||||||
void irq_test(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef TINYPS2_H__
|
|
||||||
#define TINYPS2_H__
|
|
||||||
|
|
||||||
void ip_ps2_test(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef TINYPWM_H__
|
|
||||||
#define TINYPWM_H__
|
|
||||||
|
|
||||||
void ip_pwm_test(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
@@ -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
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef TINYRNG_H__
|
|
||||||
#define TINYRNG_H__
|
|
||||||
|
|
||||||
void ip_rng_test(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef TINYRTC_H__
|
|
||||||
#define TINYRTC_H__
|
|
||||||
|
|
||||||
void ip_rtc_test(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
Reference in new issue
Block a user