Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c36dd58539 |
6
.clang-format
Normal file
6
.clang-format
Normal file
@@ -0,0 +1,6 @@
|
||||
# -*- mode: yaml -*-
|
||||
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 4
|
||||
ColumnLimit: 100
|
||||
BreakBeforeBraces: WebKit # Only break at start of functions
|
||||
@@ -7,7 +7,9 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS ON)
|
||||
|
||||
set(HAL_DEFINES
|
||||
PY32F002Ax5
|
||||
# PY32F002Ax5
|
||||
PY32F003x6
|
||||
# USE_FULL_LL_DRIVER
|
||||
)
|
||||
|
||||
set(HAL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/py32f0-sdk)
|
||||
@@ -49,7 +51,8 @@ target_sources(py32-hal PRIVATE
|
||||
${HAL_DIR}/Libraries/PY32F0xx_LL_BSP/Src/py32f0xx_bsp_printf.c
|
||||
# Startup code
|
||||
${HAL_DIR}/Libraries/CMSIS/Device/PY32F0xx/Source/system_py32f0xx.c
|
||||
${HAL_DIR}/Libraries/CMSIS/Device/PY32F0xx/Source/gcc/startup_py32f002a.s
|
||||
#${HAL_DIR}/Libraries/CMSIS/Device/PY32F0xx/Source/gcc/startup_py32f002a.s
|
||||
${HAL_DIR}/Libraries/CMSIS/Device/PY32F0xx/Source/gcc/startup_py32f003.s
|
||||
)
|
||||
|
||||
# Set up target executable
|
||||
@@ -61,8 +64,21 @@ target_link_libraries(puya32-playground
|
||||
|
||||
target_sources(puya32-playground PRIVATE
|
||||
src/main.c
|
||||
src/neopixel.c
|
||||
)
|
||||
|
||||
# # example
|
||||
# add_executable(ll_tim1_dma)
|
||||
|
||||
# target_link_libraries(ll_tim1_dma
|
||||
# PRIVATE py32-hal
|
||||
# )
|
||||
|
||||
# target_sources(ll_tim1_dma PRIVATE
|
||||
# py32f0-sdk/Examples/PY32F0xx/LL/TIM/TIM1_DMA/main.c
|
||||
# py32f0-sdk/Examples/PY32F0xx/LL/TIM/TIM1_DMA/py32f0xx_it.c
|
||||
# )
|
||||
|
||||
# clang-format
|
||||
add_custom_target(check-format
|
||||
find include/ src/ -iname '*.[ch]' -exec clang-format -Werror --dry-run {} +
|
||||
|
||||
@@ -28,15 +28,16 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TARGET_FLAGS}")
|
||||
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp -MMD -MP")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fdata-sections -ffunction-sections")
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-Og -g3")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-Os -g0")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g3")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-Os -g0")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${TARGET_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T \"${CMAKE_SOURCE_DIR}/py32f0-sdk/Libraries/LDScripts/py32f002ax5.ld\"")
|
||||
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T \"${CMAKE_SOURCE_DIR}/py32f0-sdk/Libraries/LDScripts/py32f002ax5.ld\"")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T \"${CMAKE_SOURCE_DIR}/py32f0-sdk/Libraries/LDScripts/py32f003x6.ld\"")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --specs=nano.specs --specs=nosys.specs")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--print-memory-usage")
|
||||
|
||||
104
src/main.c
104
src/main.c
@@ -1,75 +1,95 @@
|
||||
#include "neopixel.h"
|
||||
|
||||
#include <py32f0xx_bsp_clock.h>
|
||||
#include <py32f0xx_bsp_printf.h>
|
||||
#include <py32f0xx_ll_bus.h>
|
||||
#include <py32f0xx_ll_gpio.h>
|
||||
#include <py32f0xx_ll_rcc.h>
|
||||
#include <py32f0xx_bsp_printf.h>
|
||||
#include <py32f0xx_ll_utils.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define LED_PIN LL_GPIO_PIN_0
|
||||
|
||||
static void init(void)
|
||||
{
|
||||
/* LL_RCC_HSI_Enable(); */
|
||||
/* while(LL_RCC_HSI_IsReady() != 1); */
|
||||
BSP_RCC_HSI_24MConfig();
|
||||
|
||||
/* LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); */
|
||||
/* LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSISYS); */
|
||||
/* while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSISYS); */
|
||||
|
||||
/* LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); */
|
||||
/* LL_Init1msTick(8000000); */
|
||||
/* LL_SetSystemCoreClock(8000000); */
|
||||
|
||||
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
|
||||
|
||||
LL_GPIO_SetPinMode(GPIOA, LED_PIN, LL_GPIO_MODE_OUTPUT);
|
||||
|
||||
neopixel_init();
|
||||
|
||||
BSP_USART_Config(115200);
|
||||
|
||||
LL_Init1msTick(8000000);
|
||||
LL_SetSystemCoreClock(8000000);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
init();
|
||||
static const uint8_t sintbl[] = {0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, 34, 37,
|
||||
40, 43, 46, 49, 51, 54, 57, 60, 63, 65, 68, 71, 73,
|
||||
76, 78, 81, 83, 85, 88, 90, 92, 94, 96, 98, 100, 102,
|
||||
104, 106, 107, 109, 111, 112, 113, 115, 116, 117, 118, 120, 121,
|
||||
122, 122, 123, 124, 125, 125, 126, 126, 126, 127, 127, 127};
|
||||
|
||||
printf("Hello, PY32F002A!\r\n");
|
||||
|
||||
while(1) {
|
||||
LL_GPIO_TogglePin(GPIOA, LED_PIN);
|
||||
LL_mDelay(1000);
|
||||
static uint8_t sin_(uint8_t pos) {
|
||||
if (pos <= 63) {
|
||||
return 128 + sintbl[pos];
|
||||
} else if (pos <= 127) {
|
||||
return 128 + sintbl[63 - (pos - 64)];
|
||||
} else if (pos <= 191) {
|
||||
return 128 - sintbl[pos - 128];
|
||||
} else {
|
||||
return 128 - sintbl[63 - (pos - 192)];
|
||||
}
|
||||
}
|
||||
|
||||
void NMI_Handler(void)
|
||||
int main(void)
|
||||
{
|
||||
init();
|
||||
|
||||
printf("Hello, PY32F002A!\r\n");
|
||||
|
||||
unsigned i = 0;
|
||||
unsigned val[8];
|
||||
while (true) {
|
||||
for (int p = 0;p < 4;++p) {
|
||||
val[p] = neopixel_build_val(sin_(i+p*32), sin_(i+p*32+85), sin_(i+p*32+2*85));
|
||||
}
|
||||
//neopixel_set_all(sin_(i), sin_(i+85), sin_(i+2*85), 8);
|
||||
neopixel_set_raw(val, 4);
|
||||
LL_mDelay(1);
|
||||
++i;
|
||||
/* for (int c = 0; c < 3; ++c) { */
|
||||
/* for (int i = 0; i < 256; ++i) { */
|
||||
/* /\* neopixel_set_raw(val); *\/ */
|
||||
/* neopixel_set_all(c == 0 ? i : 0, c == 1 ? i : 0, c == 2 ? i : 0, 8); */
|
||||
/* LL_mDelay(10); */
|
||||
/* } */
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
|
||||
void NMI_Handler(void) {}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System service call via SWI instruction.
|
||||
*/
|
||||
void SVC_Handler(void)
|
||||
{
|
||||
}
|
||||
* @brief This function handles System service call via SWI instruction.
|
||||
*/
|
||||
void SVC_Handler(void) {}
|
||||
|
||||
/**
|
||||
* @brief This function handles Pendable request for system service.
|
||||
*/
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
}
|
||||
* @brief This function handles Pendable request for system service.
|
||||
*/
|
||||
void PendSV_Handler(void) {}
|
||||
|
||||
/**
|
||||
* @brief This function handles System tick timer.
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
}
|
||||
* @brief This function handles System tick timer.
|
||||
*/
|
||||
void SysTick_Handler(void) {}
|
||||
|
||||
116
src/neopixel.c
Normal file
116
src/neopixel.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "neopixel.h"
|
||||
|
||||
#include <py32f0xx_ll_bus.h>
|
||||
#include <py32f0xx_ll_dma.h>
|
||||
#include <py32f0xx_ll_gpio.h>
|
||||
#include <py32f0xx_ll_system.h>
|
||||
#include <py32f0xx_ll_tim.h>
|
||||
#include <py32f0xx_ll_utils.h>
|
||||
|
||||
void neopixel_init(void)
|
||||
{
|
||||
#ifdef NEOPIXEL_USE_DMA
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
|
||||
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SYSCFG | LL_APB1_GRP2_PERIPH_TIM1);
|
||||
#else
|
||||
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM1);
|
||||
#endif
|
||||
|
||||
LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_1, LL_GPIO_MODE_ALTERNATE);
|
||||
LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_1, LL_GPIO_AF_13); // TIM1_CH4 on PA1
|
||||
|
||||
LL_TIM_EnableCounter(TIM1);
|
||||
LL_TIM_EnableUpdateEvent(TIM1);
|
||||
LL_TIM_EnableARRPreload(TIM1);
|
||||
LL_TIM_SetPrescaler(TIM1, __LL_TIM_CALC_PSC(SystemCoreClock, 8000000));
|
||||
LL_TIM_SetAutoReload(TIM1, 10);
|
||||
LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH4);
|
||||
LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH4);
|
||||
LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH4, LL_TIM_OCMODE_PWM1);
|
||||
LL_TIM_OC_ConfigOutput(TIM1, LL_TIM_CHANNEL_CH4, LL_TIM_OCPOLARITY_HIGH);
|
||||
LL_TIM_OC_SetCompareCH4(TIM1, 0);
|
||||
LL_TIM_EnableAllOutputs(TIM1);
|
||||
|
||||
#ifdef NEOPIXEL_USE_DMA
|
||||
LL_DMA_ConfigTransfer(DMA1, LL_DMA_CHANNEL_1,
|
||||
LL_DMA_DIRECTION_MEMORY_TO_PERIPH | LL_DMA_MODE_NORMAL |
|
||||
LL_DMA_PERIPH_NOINCREMENT | LL_DMA_MEMORY_INCREMENT |
|
||||
LL_DMA_PDATAALIGN_HALFWORD | LL_DMA_MDATAALIGN_HALFWORD |
|
||||
LL_DMA_PRIORITY_VERYHIGH);
|
||||
LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_1, (uintptr_t)&(TIM1->CCR4));
|
||||
LL_TIM_EnableDMAReq_UPDATE(TIM1);
|
||||
LL_SYSCFG_SetDMARemap_CH1(LL_SYSCFG_DMA_MAP_TIM1_UP);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const uint8_t gammatbl[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4,
|
||||
4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9,
|
||||
9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
|
||||
18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28,
|
||||
29, 30, 30, 31, 32, 33, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43,
|
||||
43, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
|
||||
61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 81,
|
||||
82, 83, 84, 85, 87, 88, 89, 90, 91, 93, 94, 95, 97, 98, 99, 100, 102, 103, 105,
|
||||
106, 107, 109, 110, 111, 113, 114, 116, 117, 119, 120, 121, 123, 124, 126, 127, 129, 130, 132,
|
||||
133, 135, 137, 138, 140, 141, 143, 145, 146, 148, 149, 151, 153, 154, 156, 158, 159, 161, 163,
|
||||
165, 166, 168, 170, 172, 173, 175, 177, 179, 181, 182, 184, 186, 188, 190, 192, 194, 196, 197,
|
||||
199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 234, 236,
|
||||
238, 240, 242, 244, 246, 248, 251, 253, 255};
|
||||
|
||||
#ifdef NEOPIXEL_USE_DMA
|
||||
static uint16_t buf[NEOPIXEL_MAX_LEN*24+1] = {0};
|
||||
|
||||
void neopixel_set_raw(const unsigned *val, unsigned count)
|
||||
{
|
||||
if (LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1)) {
|
||||
while (!LL_DMA_IsActiveFlag_TC1(DMA1)) {
|
||||
}
|
||||
LL_DMA_ClearFlag_TC1(DMA1);
|
||||
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
|
||||
}
|
||||
for (int pix = 0;pix < count;++pix) {
|
||||
unsigned tmp = val[pix];
|
||||
for (int i = 0; i < 24; ++i) {
|
||||
buf[i+pix*24] = (tmp & 0x800000) ? 6 : 3;
|
||||
tmp <<= 1;
|
||||
}
|
||||
}
|
||||
buf[count*24] = 0;
|
||||
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uintptr_t)buf);
|
||||
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, count*24+1);
|
||||
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
|
||||
}
|
||||
#else
|
||||
void neopixel_set_raw(unsigned val)
|
||||
{
|
||||
LL_TIM_ClearFlag_UPDATE(TIM1);
|
||||
while (!LL_TIM_IsActiveFlag_UPDATE(TIM1)) {
|
||||
}
|
||||
LL_TIM_ClearFlag_UPDATE(TIM1);
|
||||
unsigned tmp = val;
|
||||
for (int i = 0; i < 24; ++i) {
|
||||
LL_TIM_OC_SetCompareCH4(TIM1, (tmp & 0x800000) ? 6 : 3);
|
||||
while (!LL_TIM_IsActiveFlag_UPDATE(TIM1)) {
|
||||
}
|
||||
LL_TIM_ClearFlag_UPDATE(TIM1);
|
||||
tmp <<= 1;
|
||||
}
|
||||
LL_TIM_OC_SetCompareCH4(TIM1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void neopixel_set_all(uint8_t r, uint8_t g, uint8_t b, unsigned count)
|
||||
{
|
||||
unsigned val[NEOPIXEL_MAX_LEN];
|
||||
const unsigned raw = neopixel_build_val(r, g, b);
|
||||
for (int i = 0; i < count; ++i)
|
||||
val[i] = raw;
|
||||
neopixel_set_raw(val, count);
|
||||
}
|
||||
|
||||
unsigned neopixel_build_val(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
return (gammatbl[g] << 16) | (gammatbl[r] << 8) | gammatbl[b];
|
||||
}
|
||||
11
src/neopixel.h
Normal file
11
src/neopixel.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define NEOPIXEL_USE_DMA
|
||||
#define NEOPIXEL_MAX_LEN 8
|
||||
|
||||
void neopixel_init(void);
|
||||
void neopixel_set_raw(const unsigned *val, unsigned count);
|
||||
void neopixel_set_all(uint8_t r, uint8_t g, uint8_t b, unsigned count);
|
||||
unsigned neopixel_build_val(uint8_t r, uint8_t g, uint8_t b);
|
||||
Reference in New Issue
Block a user