generated from Embedded_Projects/CH32X035_Template
Initial RTOS support with LED driver.
Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
parent
1cc88f3d5e
commit
5e568857b2
|
@ -1,3 +1,6 @@
|
|||
[submodule "SDK"]
|
||||
path = SDK
|
||||
url = https://git.minori.work/Embedded_SDK/WCH_CH32X035.git
|
||||
[submodule "lib/freertos"]
|
||||
path = lib/freertos
|
||||
url = https://github.com/imi415/FreeRTOS-Kernel.git
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(ch32x035_template)
|
||||
project(ch32x035_freertos)
|
||||
|
||||
enable_language(CXX)
|
||||
enable_language(ASM)
|
||||
|
||||
# Different linker scripts
|
||||
set(TARGET_LDSCRIPT_FLASH "${CMAKE_SOURCE_DIR}/SDK/Ld/Link.ld")
|
||||
set(TARGET_LDSCRIPT_FLASH "${CMAKE_SOURCE_DIR}/SDK/Ld/CH32X035_FLASH.ld")
|
||||
set(TARGET_LDSCRIPT_PIOC_FLASH "${CMAKE_SOURCE_DIR}/SDK/Ld/CH32X035_PIOC_FLASH.ld")
|
||||
|
||||
set(TARGET_SOURCES
|
||||
"SDK/Core/core_riscv.c"
|
||||
|
@ -30,11 +31,14 @@ set(TARGET_SOURCES
|
|||
"SDK/Peripheral/src/ch32x035_wwdg.c"
|
||||
"SDK/Startup/startup_ch32x035.S"
|
||||
"board/ch32x035_it.c"
|
||||
"board/freertos_helpers.c"
|
||||
"board/system_ch32x035.c"
|
||||
"src/app_led1w.c"
|
||||
"src/main.c"
|
||||
)
|
||||
|
||||
set(TARGET_C_DEFINES
|
||||
"DEBUG_UART=1"
|
||||
)
|
||||
|
||||
set(TARGET_C_INCLUDES
|
||||
|
@ -47,6 +51,7 @@ set(TARGET_C_INCLUDES
|
|||
|
||||
# Shared libraries linked with application
|
||||
set(TARGET_LIBS
|
||||
"freertos_kernel"
|
||||
"c"
|
||||
"m"
|
||||
"nosys"
|
||||
|
@ -74,6 +79,16 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-common -fno-builtin -f
|
|||
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
|
||||
# FreeRTOS
|
||||
set(FREERTOS_PORT "GCC_RISC_V_WCH_RISC_V4C" CACHE STRING "")
|
||||
set(FREERTOS_HEAP "4" CACHE STRING "")
|
||||
|
||||
add_library(freertos_config INTERFACE)
|
||||
target_include_directories(freertos_config SYSTEM INTERFACE include)
|
||||
|
||||
add_subdirectory(lib/freertos)
|
||||
|
||||
|
||||
# Shared sources, includes and definitions
|
||||
add_compile_definitions(${TARGET_C_DEFINES})
|
||||
include_directories(${TARGET_C_INCLUDES})
|
||||
|
@ -84,9 +99,6 @@ link_libraries(${TARGET_LIBS})
|
|||
|
||||
# Create ELF
|
||||
add_executable("${CMAKE_PROJECT_NAME}_FLASH.elf" ${TARGET_SOURCES})
|
||||
target_compile_definitions("${CMAKE_PROJECT_NAME}_FLASH.elf"
|
||||
PRIVATE ${TARGET_C_DEFINES_XIP}
|
||||
)
|
||||
target_link_options("${CMAKE_PROJECT_NAME}_FLASH.elf"
|
||||
PRIVATE "-T${TARGET_LDSCRIPT_FLASH}"
|
||||
PRIVATE "-Wl,--Map=${CMAKE_PROJECT_NAME}_FLASH.map"
|
||||
|
@ -104,3 +116,23 @@ if(DEFINED TARGET_TOOLCHAIN_SIZE)
|
|||
COMMAND ${TARGET_TOOLCHAIN_SIZE} "${CMAKE_PROJECT_NAME}_FLASH.elf"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Create ELF
|
||||
add_executable("${CMAKE_PROJECT_NAME}_PIOC_FLASH.elf" ${TARGET_SOURCES})
|
||||
target_link_options("${CMAKE_PROJECT_NAME}_PIOC_FLASH.elf"
|
||||
PRIVATE "-T${TARGET_LDSCRIPT_PIOC_FLASH}"
|
||||
PRIVATE "-Wl,--Map=${CMAKE_PROJECT_NAME}_PIOC_FLASH.map"
|
||||
)
|
||||
set_property(TARGET "${CMAKE_PROJECT_NAME}_PIOC_FLASH.elf" APPEND
|
||||
PROPERTY ADDITIONAL_CLEAN_FILES "${CMAKE_PROJECT_NAME}_PIOC_FLASH.map"
|
||||
)
|
||||
add_custom_command(OUTPUT "${CMAKE_PROJECT_NAME}_PIOC_FLASH.hex"
|
||||
COMMAND ${CMAKE_OBJCOPY} "-O" "ihex" "${CMAKE_PROJECT_NAME}_PIOC_FLASH.elf" "${CMAKE_PROJECT_NAME}_PIOC_FLASH.hex"
|
||||
DEPENDS "${CMAKE_PROJECT_NAME}_PIOC_FLASH.elf"
|
||||
)
|
||||
add_custom_target("${CMAKE_PROJECT_NAME}_PIOC_FLASH_HEX" DEPENDS "${CMAKE_PROJECT_NAME}_PIOC_FLASH.hex")
|
||||
if(DEFINED TARGET_TOOLCHAIN_SIZE)
|
||||
add_custom_command(TARGET "${CMAKE_PROJECT_NAME}_PIOC_FLASH.elf" POST_BUILD
|
||||
COMMAND ${TARGET_TOOLCHAIN_SIZE} "${CMAKE_PROJECT_NAME}_PIOC_FLASH.elf"
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 49754ad11b59d5982e8e3368e4b5ba0c278295db
|
|
@ -1,37 +1,38 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32x035_it.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2023/04/06
|
||||
* Description : Main Interrupt Service Routines.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32x035_it.h"
|
||||
|
||||
void NMI_Handler(void) __attribute__((interrupt));
|
||||
void HardFault_Handler(void) __attribute__((interrupt));
|
||||
#define __IRQ __attribute__((interrupt(), used))
|
||||
#define __IRQ_WEAK __attribute__((interrupt(), weak))
|
||||
#define __IRQ_NAKED __attribute__((naked, used))
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NMI_Handler
|
||||
*
|
||||
* @brief This function handles NMI exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void NMI_Handler(void) {
|
||||
}
|
||||
void app_led1w_irq_handler(void);
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HardFault_Handler
|
||||
*
|
||||
* @brief This function handles Hard Fault exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void HardFault_Handler(void) {
|
||||
while (1) {
|
||||
__IRQ void NMI_Handler(void) {
|
||||
for (;;) {
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
|
||||
__IRQ void HardFault_Handler(void) {
|
||||
for (;;) {
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
|
||||
__IRQ_NAKED void Ecall_M_Mode_Handler(void) {
|
||||
asm volatile("j freertos_risc_v_exception_handler");
|
||||
}
|
||||
|
||||
__IRQ_NAKED void SysTick_Handler(void) {
|
||||
asm volatile(
|
||||
"addi sp, sp, -4\n" /* Push */
|
||||
"sw t0, 4(sp)\n" /* Save t0 on stack */
|
||||
"li t0, 0xE000F004\n" /* SysTick->SR */
|
||||
"sw zero, 0(t0)\n" /* Write 0 to clear */
|
||||
"lw t0, 4(sp)\n" /* Restore t0 from stack */
|
||||
"addi sp, sp, 4\n" /* Pop */
|
||||
"j freertos_risc_v_mtimer_interrupt_handler");
|
||||
}
|
||||
|
||||
__IRQ void DMA1_Channel3_IRQHandler(void) {
|
||||
app_led1w_irq_handler();
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Device */
|
||||
#include "ch32x035.h"
|
||||
#include "system_ch32x035.h"
|
||||
|
||||
/**
|
||||
* @brief Initialize SysTick interrupt.
|
||||
*
|
||||
*/
|
||||
void vPortSetupTimerInterrupt(void) {
|
||||
/* Configure SysTick and interrupts. */
|
||||
SysTick->SR = 0UL;
|
||||
SysTick->CTLR = 0UL;
|
||||
SysTick->CNT = 0UL;
|
||||
|
||||
NVIC_EnableIRQ(SysTicK_IRQn);
|
||||
|
||||
SysTick->CMP = (uint64_t)((SystemCoreClock / (configTICK_RATE_HZ * 8)) - 1);
|
||||
SysTick->CTLR = 0x1A; /* COUNTDOWN | AUTO RELOAD | HCLK/8 | INT */
|
||||
SysTick->CTLR |= 0x20; /* INIT */
|
||||
|
||||
SysTick->CTLR |= 0x01; /* EN */
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/* RISC-V related configuration */
|
||||
#define configMTIME_BASE_ADDRESS 0
|
||||
#define configMTIMECMP_BASE_ADDRESS 0
|
||||
|
||||
/* General configuration */
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configUSE_TICKLESS_IDLE 0
|
||||
#define configCPU_CLOCK_HZ 48000000 /* This is literally not used, keep it to make port.c happy. */
|
||||
#define configTICK_RATE_HZ 1000
|
||||
#define configMAX_PRIORITIES 8
|
||||
#define configMINIMAL_STACK_SIZE 128
|
||||
#define configMAX_TASK_NAME_LEN 16
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3
|
||||
#define configUSE_MUTEXES 0
|
||||
#define configUSE_RECURSIVE_MUTEXES 0
|
||||
#define configUSE_COUNTING_SEMAPHORES 0
|
||||
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
|
||||
#define configQUEUE_REGISTRY_SIZE 10
|
||||
#define configUSE_QUEUE_SETS 0
|
||||
#define configUSE_TIME_SLICING 0
|
||||
#define configUSE_NEWLIB_REENTRANT 1
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 0
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
|
||||
#define configSTACK_DEPTH_TYPE uint16_t
|
||||
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
|
||||
|
||||
/* Memory allocation related definitions. */
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configTOTAL_HEAP_SIZE 10240
|
||||
#define configAPPLICATION_ALLOCATED_HEAP 0
|
||||
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||
|
||||
/* Hook function related definitions. */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
|
||||
/* Run time and task stats gathering related definitions. */
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
|
||||
/* Co-routine related definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES 1
|
||||
|
||||
/* Software timer related definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY 3
|
||||
#define configTIMER_QUEUE_LENGTH 10
|
||||
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
|
||||
/* Define to trap errors during development. */
|
||||
#define configASSERT( x ) if( ( x ) == 0 ) for(;;) { }
|
||||
|
||||
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_xResumeFromISR 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_eTaskGetState 0
|
||||
#define INCLUDE_xEventGroupSetBitFromISR 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 0
|
||||
#define INCLUDE_xTaskAbortDelay 0
|
||||
#define INCLUDE_xTaskGetHandle 0
|
||||
#define INCLUDE_xTaskResumeFromISR 1
|
||||
|
||||
#define __freertos_irq_stack_top __stack_top
|
||||
|
||||
/* A header file that defines trace macro can be included here. */
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef APP_LED1W_H
|
||||
#define APP_LED1W_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void app_led1w_init(void);
|
||||
int app_led1w_write(uint8_t *data, uint16_t led_count);
|
||||
|
||||
#endif // APP_LED1W_H
|
|
@ -0,0 +1 @@
|
|||
Subproject commit a47bffbfc841f99dfbab1fac46a9d021ec9dbb0c
|
|
@ -11,7 +11,7 @@ set(TARGET_TOOLCHAIN_SIZE riscv64-elf-size)
|
|||
|
||||
set(CMAKE_C_FLAGS_INIT "-march=rv32imac_zicsr -mabi=ilp32")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-march=rv32imac_zicsr -mabi=ilp32")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-specs=nano.specs -specs=nosys.specs -nostartfiles -Wl,--print-memory-usage -Wl,--no-warn-rwx-segments")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-march=rv32imac -mabi=ilp32 -specs=nano.specs -specs=nosys.specs -nostartfiles -Wl,--print-memory-usage -Wl,--no-warn-rwx-segments")
|
||||
|
||||
# Make CMake happy about those compilers
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# Poor old Windows...
|
||||
if(WIN32)
|
||||
set(CMAKE_SYSTEM_NAME "Generic")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_COMPILER riscv64-multilib-elf-gcc)
|
||||
set(CMAKE_CXX_COMPILER riscv64-multilib-elf-g++)
|
||||
|
||||
# Optionally set size binary name, for elf section size reporting.
|
||||
set(TARGET_TOOLCHAIN_SIZE riscv64-multilib-elf-size)
|
||||
|
||||
set(CMAKE_C_FLAGS_INIT "-march=rv32imac_zicsr -mabi=ilp32")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-march=rv32imac_zicsr -mabi=ilp32")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-specs=nano.specs -specs=nosys.specs -nostartfiles -Wl,--print-memory-usage -Wl,--no-warn-rwx-segments")
|
||||
|
||||
# Make CMake happy about those compilers
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
|
@ -0,0 +1,122 @@
|
|||
#include <stdint.h>
|
||||
|
||||
/* SDK */
|
||||
#include "ch32x035.h"
|
||||
#include "ch32x035_dma.h"
|
||||
#include "ch32x035_gpio.h"
|
||||
#include "ch32x035_spi.h"
|
||||
|
||||
/* Private */
|
||||
#include "app_led1w.h"
|
||||
|
||||
#define APP_LED1W_MAXIMUM_LEDS 64
|
||||
#define APP_LED1W_ZERO_PADDING 32 /* Additional padding for a RESET condition (50uS) */
|
||||
|
||||
#define APP_LED1W_SPI_0B (0x08U) /* 4'b1000 */
|
||||
#define APP_LED1W_SPI_1B (0x0EU) /* 4'b1110 */
|
||||
|
||||
/* SPI buffer to store waveform data */
|
||||
static uint8_t s_led1w_spi_buf[APP_LED1W_MAXIMUM_LEDS * 3 * 8 / 2 + APP_LED1W_ZERO_PADDING];
|
||||
|
||||
static void app_led1w_encode(const uint8_t *data, uint16_t len);
|
||||
|
||||
void app_led1w_init(void) {
|
||||
/* Enable DMA and SPI clocks */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
|
||||
/* Initialize SPI peripheral */
|
||||
|
||||
SPI_InitTypeDef spi_init;
|
||||
|
||||
/*
|
||||
* 48MHz / 16 = 3MHz
|
||||
* Timing:
|
||||
* T0H: 334ns
|
||||
* T0L: 1002ns
|
||||
* T1H: 1002ns
|
||||
* T1L: 334ns
|
||||
*/
|
||||
|
||||
spi_init.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
|
||||
spi_init.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
||||
spi_init.SPI_Mode = SPI_Mode_Master;
|
||||
spi_init.SPI_CPOL = SPI_CPOL_Low;
|
||||
spi_init.SPI_CPHA = SPI_CPHA_1Edge;
|
||||
spi_init.SPI_NSS = SPI_NSS_Soft;
|
||||
spi_init.SPI_FirstBit = SPI_FirstBit_MSB;
|
||||
spi_init.SPI_DataSize = SPI_DataSize_8b;
|
||||
|
||||
SPI_Init(SPI1, &spi_init);
|
||||
|
||||
GPIO_InitTypeDef gpio_init;
|
||||
|
||||
gpio_init.GPIO_Pin = GPIO_Pin_7;
|
||||
gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
|
||||
GPIO_Init(GPIOA, &gpio_init);
|
||||
}
|
||||
|
||||
int app_led1w_write(uint8_t *data, uint16_t led_count) {
|
||||
uint16_t byte_count = led_count * 3 * 8 / 2;
|
||||
|
||||
if ((byte_count + APP_LED1W_ZERO_PADDING) > sizeof(s_led1w_spi_buf)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
app_led1w_encode(data, led_count * 3);
|
||||
|
||||
/* Initialize DMA peripheral */
|
||||
DMA_InitTypeDef dma_init;
|
||||
|
||||
dma_init.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DATAR;
|
||||
dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||
dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||||
dma_init.DMA_MemoryBaseAddr = (uint32_t)s_led1w_spi_buf;
|
||||
dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||||
dma_init.DMA_DIR = DMA_DIR_PeripheralDST;
|
||||
dma_init.DMA_Mode = DMA_Mode_Normal;
|
||||
dma_init.DMA_Priority = DMA_Priority_Medium;
|
||||
dma_init.DMA_M2M = DMA_M2M_Disable;
|
||||
dma_init.DMA_BufferSize = byte_count + APP_LED1W_ZERO_PADDING;
|
||||
|
||||
DMA_Init(DMA1_Channel3, &dma_init);
|
||||
|
||||
/* Enable SPI TX DMA request generation */
|
||||
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
|
||||
|
||||
DMA_Cmd(DMA1_Channel3, ENABLE);
|
||||
|
||||
NVIC_EnableIRQ(DMA1_Channel3_IRQn);
|
||||
|
||||
SPI_Cmd(SPI1, ENABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void app_led1w_encode(const uint8_t *data, uint16_t len) {
|
||||
for (uint32_t i = 0; i < APP_LED1W_ZERO_PADDING; i++) {
|
||||
s_led1w_spi_buf[i] = 0x00;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < len + 0; i++) {
|
||||
uint16_t buf_index = i * 4 + APP_LED1W_ZERO_PADDING; // Add 0 padding
|
||||
|
||||
for (uint8_t j = 0; j < 4; j++) {
|
||||
uint8_t bit_offset_l = (3 - j) * 2;
|
||||
uint8_t bit_offset_h = (3 - j) * 2 + 1;
|
||||
|
||||
uint8_t buf_payload = (data[i] >> bit_offset_l & 0x01U) ? APP_LED1W_SPI_1B : APP_LED1W_SPI_0B;
|
||||
buf_payload |= (((data[i] >> bit_offset_h) & 0x01U) ? APP_LED1W_SPI_1B : APP_LED1W_SPI_0B) << 4U;
|
||||
|
||||
s_led1w_spi_buf[buf_index + j] = buf_payload;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void app_led1w_irq_handler(void) {
|
||||
|
||||
}
|
85
src/main.c
85
src/main.c
|
@ -1,4 +1,89 @@
|
|||
#include <string.h>
|
||||
|
||||
/* Core */
|
||||
#include "ch32x035.h"
|
||||
|
||||
/* FreeRTOS */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* App */
|
||||
#include "app_led1w.h"
|
||||
|
||||
#define APP_GRAD_STEP 4
|
||||
|
||||
static void hello_task(void *parameters);
|
||||
|
||||
int main(void) {
|
||||
USART_Printf_Init(115200);
|
||||
|
||||
xTaskCreate(hello_task, "HELLO", 512, NULL, 4, NULL);
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
for (;;) {
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
|
||||
static void hello_task(void *parameters) {
|
||||
uint8_t data_payload[64 * 3];
|
||||
|
||||
app_led1w_init();
|
||||
|
||||
uint8_t color_r = 0xFF;
|
||||
uint8_t color_g = 0x00;
|
||||
uint8_t color_b = 0x00;
|
||||
|
||||
uint8_t dir_set = 0x01; /* 3'b001 */
|
||||
|
||||
memset(data_payload, 0x00, sizeof(data_payload));
|
||||
|
||||
for (;;) {
|
||||
for (uint8_t i = 63; i > 0; i--) {
|
||||
data_payload[3 * i] = data_payload[3 * (i - 1)];
|
||||
data_payload[3 * i + 1] = data_payload[3 * (i - 1) + 1];
|
||||
data_payload[3 * i + 2] = data_payload[3 * (i - 1) + 2];
|
||||
}
|
||||
|
||||
data_payload[0] = color_g;
|
||||
data_payload[1] = color_r;
|
||||
data_payload[2] = color_b;
|
||||
|
||||
switch (dir_set) {
|
||||
case 1: {
|
||||
color_r -= APP_GRAD_STEP;
|
||||
color_g += APP_GRAD_STEP;
|
||||
if (color_r < APP_GRAD_STEP) {
|
||||
dir_set = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
color_g -= APP_GRAD_STEP;
|
||||
color_b += APP_GRAD_STEP;
|
||||
if (color_g < APP_GRAD_STEP) {
|
||||
dir_set = 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: {
|
||||
color_b -= APP_GRAD_STEP;
|
||||
color_r += APP_GRAD_STEP;
|
||||
if (color_b < APP_GRAD_STEP) {
|
||||
dir_set = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
app_led1w_write(data_payload, 64);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(16));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue