From 82bd46e53b28ce7c3f9857889c2c6b841bc3feef Mon Sep 17 00:00:00 2001 From: lowfatcode Date: Thu, 30 Jan 2020 15:58:49 +0000 Subject: [PATCH 01/14] Crashes on many examples - looking into it. --- 32blit-stm32/Inc/stm32h7xx_it.h | 2 ++ 32blit-stm32/Src/32blit.c | 56 ++++++++++++++++++++------------- 32blit-stm32/Src/ltdc.c | 2 ++ 32blit-stm32/Src/main.c | 16 +++++----- 32blit-stm32/Src/stm32h7xx_it.c | 15 +++++++++ 32blit/engine/engine.cpp | 7 ++++- examples/go | 42 +++++++++++++++++++++++++ tools/wsl-flash | 2 +- 8 files changed, 109 insertions(+), 33 deletions(-) create mode 100644 examples/go diff --git a/32blit-stm32/Inc/stm32h7xx_it.h b/32blit-stm32/Inc/stm32h7xx_it.h index 9cacc58c2..9e5502546 100644 --- a/32blit-stm32/Inc/stm32h7xx_it.h +++ b/32blit-stm32/Inc/stm32h7xx_it.h @@ -61,6 +61,8 @@ void TIM3_IRQHandler(void); void TIM4_IRQHandler(void); void TIM6_DAC_IRQHandler(void); void OTG_HS_IRQHandler(void); +void LTDC_IRQHandler(void); + /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c index 33d568b52..4557c9262 100644 --- a/32blit-stm32/Src/32blit.c +++ b/32blit-stm32/Src/32blit.c @@ -8,6 +8,7 @@ #include "tim.h" #include "rng.h" #include "spi.h" +#include "ltdc.h" #include "spi-st7272a.h" #include "i2c.h" #include "i2c-msa301.h" @@ -33,6 +34,7 @@ FRESULT SD_FileOpenError = FR_INVALID_PARAMETER; uint32_t total_samples = 0; uint8_t dma_status = 0; +bool needs_render = true; static blit::screen_mode mode = blit::screen_mode::lores; @@ -106,13 +108,22 @@ uint32_t blit_update_dac(FIL *audio_file) { } void blit_tick() { + if(needs_render) { + blit::render(blit::now()); + + needs_render = false; + blit::LED.r = ~blit::LED.r; + } + + blit::LED.g++; + blit_process_input(); blit_update_led(); blit_update_vibration(); - if(blit::tick(blit::now())){ - blit_flip(); - } + + + blit::tick(blit::now()); } bool blit_sd_detected() { @@ -155,10 +166,10 @@ void blit_init() { for(int x = 0; xCDSR & LTDC_CDSR_VSYNCS)); - // set the LTDC layer framebuffer pointer shadow register LTDC_Layer1->CFBAR = (uint32_t)(&__ltdc_start + (ltdc_buffer_id * 320 * 240 * 2)); // force LTDC driver to reload shadow registers @@ -368,10 +393,6 @@ void blit_flip() { } else { // LORES mode - // wait for next frame if LTDC hardware currently drawing, ensures - // no tearing - while (!(LTDC->CDSR & LTDC_CDSR_VSYNCS)); - // pixel double the framebuffer to the LTDC buffer rgb *src = (rgb *)blit::fb.data; @@ -393,16 +414,7 @@ void blit_flip() { dest += 320; } - SCB_CleanInvalidateDCache_by_Addr((uint32_t *)&__ltdc_start, 320 * 240 * 2); - - // set the LTDC layer framebuffer pointer shadow register - LTDC_Layer1->CFBAR = (uint32_t)(&__ltdc_start); - // force LTDC driver to reload shadow registers - LTDC->SRCR = LTDC_SRCR_IMR; - - // No need to swap framebuffer since we've copied from the engine's - // 160 x 120 framebuffer to the 320 x 240 LTDC buffer - ltdc_buffer_id = 0; + // SCB_CleanInvalidateDCache_by_Addr((uint32_t *)&__ltdc_start, 320 * 240 * 2); } } diff --git a/32blit-stm32/Src/ltdc.c b/32blit-stm32/Src/ltdc.c index 9210792cd..7a9dc719e 100644 --- a/32blit-stm32/Src/ltdc.c +++ b/32blit-stm32/Src/ltdc.c @@ -71,8 +71,10 @@ void MX_LTDC_Init(void) { Error_Handler(); } + } + void HAL_LTDC_MspInit(LTDC_HandleTypeDef* ltdcHandle) { diff --git a/32blit-stm32/Src/main.c b/32blit-stm32/Src/main.c index 49a20103d..f5b2f3f3a 100644 --- a/32blit-stm32/Src/main.c +++ b/32blit-stm32/Src/main.c @@ -106,7 +106,7 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); - MX_DMA_Init(); + //MX_DMA_Init(); MX_TIM4_Init(); MX_TIM3_Init(); MX_DAC1_Init(); @@ -119,13 +119,17 @@ int main(void) //MX_USB_OTG_HS_USB_Init(); MX_SPI1_Init(); MX_SPI4_Init(); - MX_TIM6_Init(); + //MX_TIM6_Init(); MX_TIM15_Init(); MX_FATFS_Init(); //MX_DMA2D_Init(); MX_RNG_Init(); - MX_USB_DEVICE_Init(); + //MX_USB_DEVICE_Init(); /* USER CODE BEGIN 2 */ + + + + blit_clear_framebuffer(); blit_init(); @@ -149,12 +153,6 @@ int main(void) { uint32_t t_start = blit::now(); - // TODO: this is really just experimental code and should - // be removed in favour of generic sound support - if(audio_file_available && blit_sd_detected()){ - total_samples += blit_update_dac(&audio_file); - } - blit_tick(); uint32_t t_elapsed = blit::now() - t_start; diff --git a/32blit-stm32/Src/stm32h7xx_it.c b/32blit-stm32/Src/stm32h7xx_it.c index b0f9069c3..dd23db650 100644 --- a/32blit-stm32/Src/stm32h7xx_it.c +++ b/32blit-stm32/Src/stm32h7xx_it.c @@ -23,6 +23,7 @@ #include "stm32h7xx_it.h" #include "fatfs.h" #include "dac.h" +#include "ltdc.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ @@ -248,6 +249,20 @@ void DMAMUX1_OVR_IRQHandler(void) /* USER CODE END DMAMUX1_OVR_IRQn 1 */ } + +/** +* @brief This function handles LTDC global interrupt. +*/ +void LTDC_IRQHandler(void) +{ + /* USER CODE BEGIN LTDC_IRQn 0 */ + /* USER CODE END LTDC_IRQn 0 */ + HAL_LTDC_IRQHandler(&hltdc); + /* USER CODE BEGIN LTDC_IRQn 1 */ + /* USER CODE END LTDC_IRQn 1 */ +} + + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/32blit/engine/engine.cpp b/32blit/engine/engine.cpp index 36b3483e2..e6f76146c 100644 --- a/32blit/engine/engine.cpp +++ b/32blit/engine/engine.cpp @@ -44,6 +44,7 @@ namespace blit { pending_update_time -= update_rate_ms; } +/* // render if new frame due pending_render_time += (time - last_tick_time); if (pending_render_time >= render_rate_ms) { @@ -52,8 +53,12 @@ namespace blit { has_rendered = true; } + + return has_rendered;*/ + last_tick_time = time; - return has_rendered; + + return true; } } diff --git a/examples/go b/examples/go new file mode 100644 index 000000000..6371c3ded --- /dev/null +++ b/examples/go @@ -0,0 +1,42 @@ +#!/bin/bash + +PROJECT=$(echo $1 | sed 's:/*$::') + +echo "32blit: Build and flash project $PROJECT" + +if [ -d "${PROJECT}" ] +then + + cd $PROJECT + + mkdir -p build.stm32 + + cd build.stm32 + + echo " - preparing" + + cmake .. -DCMAKE_TOOLCHAIN_FILE=../../../32blit.toolchain # > /dev/null + + echo " - building" + + make -j8 # > /dev/null + + ../../../tools/dfu build --force --out $PROJECT.dfu $PROJECT.bin + + echo " - flashing to device (make sure it's in DFU mode!)" + + ../../../tools/wsl-flash $PROJECT.dfu # > /dev/null + + cd .. + cd .. + + echo "..done! Reset your 32blit and happy hacking! :-)" +fi + +if [ ! -d "${PROJECT}" ] +then + echo "ERROR: Cannot find project $PROJECT. :-(" + exit 1 +fi + +exit 0 diff --git a/tools/wsl-flash b/tools/wsl-flash index 742db93d4..ca335d24e 100755 --- a/tools/wsl-flash +++ b/tools/wsl-flash @@ -18,4 +18,4 @@ echo "$FILEPATH_WIN$FILENAME_WIN" # Call DfuSeCommand.exe # Ideally you should use the modified version at https://github.com/pimoroni/DfuSE/ since it will reset the hardware after flashing -/mnt/c/Program\ Files\ \(x86\)/STMicroelectronics/Software/DfuSe\ v3.0.6/Sources/Binary/Release/DfuSeCommand.exe -c -d --r --fn "$FILEPATH_WIN" +/mnt/c/Program\ Files\ \(x86\)/STMicroelectronics/Software/DfuSe\ v3.0.6/Sources/Binary/Release/DfuSeCommand.exe -c -d --fn "$FILEPATH_WIN" From df6e76a750a58cdb2cea5329e87a16fb660a9b20 Mon Sep 17 00:00:00 2001 From: lowfatcode Date: Fri, 31 Jan 2020 10:30:52 +0000 Subject: [PATCH 02/14] Move frambuffers around and change hires flipping behaviour --- 32blit-stm32/STM32H750VBTx_FLASH.ld | 30 +++------ 32blit-stm32/Src/32blit.c | 99 ++++++++++------------------- 32blit-stm32/Src/main.c | 3 +- examples/platformer/platformer.cpp | 4 +- 4 files changed, 48 insertions(+), 88 deletions(-) diff --git a/32blit-stm32/STM32H750VBTx_FLASH.ld b/32blit-stm32/STM32H750VBTx_FLASH.ld index f83c99976..78a5f0858 100644 --- a/32blit-stm32/STM32H750VBTx_FLASH.ld +++ b/32blit-stm32/STM32H750VBTx_FLASH.ld @@ -42,9 +42,10 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ MEMORY { DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K -RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 212K -LTDC (rw) : ORIGIN = 0x24035000, LENGTH = 300K -RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K +RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 362K +LTDC (rw) : ORIGIN = 0x2405A800, LENGTH = 150K +RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 138K +FRAMEBUFFER (rw) : ORIGIN = 0x30022800, LENGTH = 150K RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K ITCMISR (xrw) : ORIGIN = 0x00000000, LENGTH = 4K ITCMRAM (xrw) : ORIGIN = 0x00001000, LENGTH = 60K @@ -146,7 +147,7 @@ SECTIONS . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; - } >DTCMRAM + } >RAM_D1 /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : @@ -157,7 +158,7 @@ SECTIONS . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); - } >DTCMRAM + } >RAM_D1 itcm_data = LOADADDR(.itcm); .itcm : @@ -177,23 +178,13 @@ SECTIONS __ltdc_end = .; } >LTDC - .ss (NOLOAD): - { - . = ALIGN(4); - *(.ss) /* spritesheet */ - } >RAM_D2 - .fb (NOLOAD): { . = ALIGN(4); - *(.fb) /* framebuffer */ - } >RAM_D1 - - .m (NOLOAD): - { - . = ALIGN(4); - *(.m) /* framebuffer */ - } >RAM_D2 + __fb_start = .; + KEEP(*(.fb)) /* framebuffer */ + __fb_end = .; + } >FRAMEBUFFER .dac_data (NOLOAD): { @@ -212,4 +203,3 @@ SECTIONS .ARM.attributes 0 : { *(.ARM.attributes) } } - diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c index 4557c9262..16b62ee24 100644 --- a/32blit-stm32/Src/32blit.c +++ b/32blit-stm32/Src/32blit.c @@ -24,6 +24,8 @@ using namespace blit; __attribute__((section(".dac_data"))) uint16_t dac_buffer[DAC_BUFFER_SIZE]; extern char __ltdc_start; +extern char __fb_start; + extern char itcm_text_start; extern char itcm_text_end; extern char itcm_data; @@ -40,9 +42,9 @@ static blit::screen_mode mode = blit::screen_mode::lores; /* configure the screen surface to point at the reserved LTDC framebuffer */ surface __ltdc((uint8_t *)&__ltdc_start, pixel_format::RGB565, size(320, 240)); -uint8_t ltdc_buffer_id = 0; -surface __fb(((uint8_t *)&__ltdc_start) + (320 * 240 * 2), pixel_format::RGB, size(160, 120)); +surface __fb_hires((uint8_t *)&__fb_start, pixel_format::RGB565, size(320, 240)); +surface __fb_lores((uint8_t *)&__fb_start, pixel_format::RGB, size(160, 120)); void DFUBoot(void) { @@ -108,8 +110,10 @@ uint32_t blit_update_dac(FIL *audio_file) { } void blit_tick() { + if(needs_render) { blit::render(blit::now()); + needs_render = false; blit::LED.r = ~blit::LED.r; @@ -194,9 +198,9 @@ void blit_init() { blit::init(); - HAL_NVIC_SetPriority(LTDC_IRQn, 2, 0); + HAL_NVIC_SetPriority(LTDC_IRQn, 4, 4); HAL_NVIC_EnableIRQ(LTDC_IRQn); - HAL_LTDC_ProgramLineEvent(&hltdc, 220); + HAL_LTDC_ProgramLineEvent(&hltdc, 250); } void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *p) { @@ -206,7 +210,7 @@ void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *p) { blit::LED.b++; blit_update_led(); - HAL_LTDC_ProgramLineEvent(&hltdc, 220); + HAL_LTDC_ProgramLineEvent(&hltdc, 250); } int menu_item = 0; @@ -378,74 +382,41 @@ void blit_menu() { * In high-res mode it simply points LTDC at the freshly drawn buffer and gives 32blit the other buffer to draw into. */ void blit_flip() { - if(mode == screen_mode::hires) { - // HIRES mode - SCB_CleanInvalidateDCache_by_Addr((uint32_t *)blit::fb.data, 320 * 240 * 2); - - // set the LTDC layer framebuffer pointer shadow register - LTDC_Layer1->CFBAR = (uint32_t)(&__ltdc_start + (ltdc_buffer_id * 320 * 240 * 2)); - // force LTDC driver to reload shadow registers - LTDC->SRCR = LTDC_SRCR_IMR; - - // Swap blit's output framebuffer over - ltdc_buffer_id = ltdc_buffer_id == 0 ? 1 : 0; - blit::fb.data = (uint8_t *)(&__ltdc_start) + (ltdc_buffer_id * 320 * 240 * 2); - } else { - // LORES mode - - // pixel double the framebuffer to the LTDC buffer - rgb *src = (rgb *)blit::fb.data; - - uint16_t *dest = (uint16_t *)(&__ltdc_start); - for(uint8_t y = 0; y < 120; y++) { - // pixel double the current row while converting from RGBA to RGB565 - for(uint8_t x = 0; x < 160; x++) { - uint8_t r = src->r >> 3; - uint8_t g = src->g >> 2; - uint8_t b = src->b >> 3; - uint16_t c = (r << 11) | (g << 5) | (b); - *dest++ = c; - *dest++ = c; - src++; - } - - // copy the previous converted row (640 bytes / 320 x 2-byte pixels) - memcpy((uint8_t *)(dest), (uint8_t *)(dest) - 640, 640); - dest += 320; - } + if(mode == screen_mode::hires) { + memcpy((uint8_t *)(__ltdc.data), (uint8_t *)(__fb_hires.data), 320 * 240 * 2); + } else { + // pixel double the framebuffer to the LTDC buffer + rgb *src = (rgb *)__fb_lores.data; + + uint16_t *dest = (uint16_t *)(&__ltdc_start); + for(uint8_t y = 0; y < 120; y++) { + // pixel double the current row while converting from RGBA to RGB565 + for(uint8_t x = 0; x < 160; x++) { + uint8_t r = src->r >> 3; + uint8_t g = src->g >> 2; + uint8_t b = src->b >> 3; + uint16_t c = (r << 11) | (g << 5) | (b); + *dest++ = c; + *dest++ = c; + src++; + } - // SCB_CleanInvalidateDCache_by_Addr((uint32_t *)&__ltdc_start, 320 * 240 * 2); + // copy the previous converted row (640 bytes / 320 x 2-byte pixels) + memcpy((uint8_t *)(dest), (uint8_t *)(dest) - 640, 640); + dest += 320; } + } + + SCB_CleanInvalidateDCache_by_Addr((uint32_t *)&__ltdc_start, 320 * 240 * 2); } void set_screen_mode(blit::screen_mode new_mode) { mode = new_mode; if(mode == blit::screen_mode::hires) { - blit::fb = __ltdc; + blit::fb = __fb_hires; } else { - blit::fb = __fb; - } -} - -void blit_clear_framebuffer() { - // initialise the LTDC buffer with a checkerboard pattern so it's clear - // when it hasn't been written to yet - - uint16_t *pc = (uint16_t *)&__ltdc_start; - - // framebuffer 1 - for(uint16_t y = 0; y < 240; y++) { - for(uint16_t x = 0; x < 320; x++) { - *pc++ = (((x / 10) + (y / 10)) & 0b1) ? 0x7BEF : 0x38E7; - } - } - - // framebuffer 2 - for(uint16_t y = 0; y < 240; y++) { - for(uint16_t x = 0; x < 320; x++) { - *pc++ = (((x / 10) + (y / 10)) & 0b1) ? 0x38E7 : 0x7BEF; - } + blit::fb = __fb_lores; } } diff --git a/32blit-stm32/Src/main.c b/32blit-stm32/Src/main.c index f5b2f3f3a..7b17e65e7 100644 --- a/32blit-stm32/Src/main.c +++ b/32blit-stm32/Src/main.c @@ -129,8 +129,7 @@ int main(void) - - blit_clear_framebuffer(); + //NVIC_SetPriority(SysTick_IRQn, 0x0); blit_init(); char sd_card_label[12]; diff --git a/examples/platformer/platformer.cpp b/examples/platformer/platformer.cpp index d67384167..3a3fc4ed3 100644 --- a/examples/platformer/platformer.cpp +++ b/examples/platformer/platformer.cpp @@ -11,8 +11,8 @@ using namespace blit; size screen_size(160, 120); /* define storage for the framebuffer, spritesheet, and mask */ -rgba __ss[128 * 128] __SECTION__(".ss"); -uint8_t __m[320 * 240] __SECTION__(".m"); +rgba __ss[128 * 128]; +uint8_t __m[320 * 240]; /* create surfaces */ surface m((uint8_t *)__m, pixel_format::M, screen_size); From 25da81b58850605cc6e6efa996f02a62b164cd9f Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 31 Jan 2020 11:38:32 +0000 Subject: [PATCH 03/14] Try to bring ADC DMA online --- 32blit-stm32/Inc/stm32h7xx_it.h | 4 ++ 32blit-stm32/Src/32blit.c | 65 +++++++++++++++++++++++-- 32blit-stm32/Src/adc.c | 84 ++++++++++++++++++++++++++------- 32blit-stm32/Src/dac.c | 14 +++++- 32blit-stm32/Src/dma.c | 7 +++ 32blit-stm32/Src/stm32h7xx_it.c | 66 ++++++++++++++++++++++++-- hardware/STM32H750VBTx.ioc | 64 ++++++++++++++++++++++--- 7 files changed, 269 insertions(+), 35 deletions(-) diff --git a/32blit-stm32/Inc/stm32h7xx_it.h b/32blit-stm32/Inc/stm32h7xx_it.h index 9cacc58c2..8ce101637 100644 --- a/32blit-stm32/Inc/stm32h7xx_it.h +++ b/32blit-stm32/Inc/stm32h7xx_it.h @@ -57,6 +57,10 @@ void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); void DMA1_Stream0_IRQHandler(void); +void DMA1_Stream1_IRQHandler(void); +void DMA1_Stream2_IRQHandler(void); +void ADC_IRQHandler(void); +void ADC3_IRQHandler(void); void TIM3_IRQHandler(void); void TIM4_IRQHandler(void); void TIM6_DAC_IRQHandler(void); diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c index 33d568b52..c451af98b 100644 --- a/32blit-stm32/Src/32blit.c +++ b/32blit-stm32/Src/32blit.c @@ -27,6 +27,9 @@ extern char itcm_text_start; extern char itcm_text_end; extern char itcm_data; +ALIGN_32BYTES (static uint16_t adc1data[32]); +ALIGN_32BYTES (static uint16_t adc3data[32]); + FATFS filesystem; FRESULT SD_Error = FR_INVALID_PARAMETER; FRESULT SD_FileOpenError = FR_INVALID_PARAMETER; @@ -155,9 +158,12 @@ void blit_init() { for(int x = 0; xInstance == ADC1) { + SCB_InvalidateDCache_by_Addr((uint32_t *) &adc1data[0], 32); + } else if (hadc->Instance == ADC3) { + SCB_InvalidateDCache_by_Addr((uint32_t *) &adc3data[0], 32); + } +} + +void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { + blit::LED.r = 255; + blit_update_led(); + if(hadc->Instance == ADC1) { + SCB_InvalidateDCache_by_Addr((uint32_t *) &adc1data[16], 16); + /* + + int joystick_y = (adc1data[0] >> 1) - 16384; + joystick_y = std::max(-8192, std::min(8192, joystick_y)); + if(joystick_y < -1024) { + joystick_y += 1024; + } + else if(joystick_y > 1024) { + joystick_y -= 1024; + } else { + joystick_y = 0; + } + blit::joystick.y = joystick_y / 7168.0f; + + int joystick_x = (adc1data[1] >> 1) - 16384; + joystick_x = std::max(-8192, std::min(8192, joystick_x)); + if(joystick_x < -1024) { + joystick_x += 1024; + } + else if(joystick_x > 1024) { + joystick_x -= 1024; + } else { + joystick_x = 0; + } + blit::joystick.x = joystick_x / 7168.0f; + */ + } else if (hadc->Instance == ADC3) { + SCB_InvalidateDCache_by_Addr((uint32_t *) &adc3data[16], 16); + + } +} #define ACCEL_OVER_SAMPLE 16 @@ -486,7 +541,7 @@ void blit_process_input() { // read x axis of joystick bool joystick_button = false; - HAL_ADC_Start(&hadc1); + /*HAL_ADC_Start(&hadc1); ADC_update_joystick_axis(&hadc1, &blit::joystick.x); ADC_update_joystick_axis(&hadc1, &blit::joystick.y); blit::joystick.y = -blit::joystick.y; @@ -499,7 +554,7 @@ void blit_process_input() { { blit::battery = 6.6f * HAL_ADC_GetValue(&hadc3) / 65535.0f; } - HAL_ADC_Stop(&hadc3); + HAL_ADC_Stop(&hadc3);*/ // Read buttons blit::buttons = diff --git a/32blit-stm32/Src/adc.c b/32blit-stm32/Src/adc.c index 529dc4391..8198eb007 100644 --- a/32blit-stm32/Src/adc.c +++ b/32blit-stm32/Src/adc.c @@ -26,6 +26,8 @@ ADC_HandleTypeDef hadc1; ADC_HandleTypeDef hadc3; +DMA_HandleTypeDef hdma_adc1; +DMA_HandleTypeDef hdma_adc3; /* ADC1 init function */ void MX_ADC1_Init(void) @@ -36,18 +38,18 @@ void MX_ADC1_Init(void) /** Common config */ hadc1.Instance = ADC1; - hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; + hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; hadc1.Init.Resolution = ADC_RESOLUTION_16B; hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; - hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; hadc1.Init.LowPowerAutoWait = DISABLE; - hadc1.Init.ContinuousConvMode = DISABLE; + hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.NbrOfConversion = 2; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; - hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; - hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED; + hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; + hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; hadc1.Init.OversamplingMode = ENABLE; hadc1.Init.Oversampling.Ratio = 256; // Number of ADC samples to be summed together @@ -85,14 +87,6 @@ void MX_ADC1_Init(void) { Error_Handler(); } - /** Configure Regular Channel - */ - /*sConfig.Channel = ADC_CHANNEL_8; - sConfig.Rank = ADC_REGULAR_RANK_3; - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) - { - Error_Handler(); - }*/ } /* ADC3 init function */ @@ -103,18 +97,18 @@ void MX_ADC3_Init(void) /** Common config */ hadc3.Instance = ADC3; - hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; + hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; hadc3.Init.Resolution = ADC_RESOLUTION_16B; hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE; - hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV; hadc3.Init.LowPowerAutoWait = DISABLE; - hadc3.Init.ContinuousConvMode = DISABLE; + hadc3.Init.ContinuousConvMode = ENABLE; hadc3.Init.NbrOfConversion = 3; hadc3.Init.DiscontinuousConvMode = DISABLE; hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; - hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; - hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED; + hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; + hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; hadc3.Init.OversamplingMode = ENABLE; hadc3.Init.Oversampling.Ratio = 256; // Number of ADC samples to be summed together @@ -178,6 +172,28 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + /* ADC1 DMA Init */ + /* ADC1 Init */ + hdma_adc1.Instance = DMA1_Stream0; + hdma_adc1.Init.Request = DMA_REQUEST_ADC1; + hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; + hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + hdma_adc1.Init.Mode = DMA_NORMAL; + hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM; + hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1); + + /* ADC1 interrupt Init */ + HAL_NVIC_SetPriority(ADC_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(ADC_IRQn); /* USER CODE BEGIN ADC1_MspInit 1 */ /* USER CODE END ADC1_MspInit 1 */ @@ -205,6 +221,28 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC3, SYSCFG_SWITCH_PC3_OPEN); + /* ADC3 DMA Init */ + /* ADC3 Init */ + hdma_adc3.Instance = DMA1_Stream1; + hdma_adc3.Init.Request = DMA_REQUEST_ADC3; + hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_adc3.Init.MemInc = DMA_MINC_ENABLE; + hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + hdma_adc3.Init.Mode = DMA_NORMAL; + hdma_adc3.Init.Priority = DMA_PRIORITY_MEDIUM; + hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + if (HAL_DMA_Init(&hdma_adc3) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc3); + + /* ADC3 interrupt Init */ + HAL_NVIC_SetPriority(ADC3_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(ADC3_IRQn); /* USER CODE BEGIN ADC3_MspInit 1 */ /* USER CODE END ADC3_MspInit 1 */ @@ -228,6 +266,11 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) */ HAL_GPIO_DeInit(GPIOC, JOYSTICK_Y_Pin|JOYSTICK_X_Pin); + /* ADC1 DMA DeInit */ + HAL_DMA_DeInit(adcHandle->DMA_Handle); + + /* ADC1 interrupt Deinit */ + HAL_NVIC_DisableIRQ(ADC_IRQn); /* USER CODE BEGIN ADC1_MspDeInit 1 */ /* USER CODE END ADC1_MspDeInit 1 */ @@ -247,6 +290,11 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) */ HAL_GPIO_DeInit(USER_LEFT1_GPIO_Port, USER_LEFT1_Pin); + /* ADC3 DMA DeInit */ + HAL_DMA_DeInit(adcHandle->DMA_Handle); + + /* ADC3 interrupt Deinit */ + HAL_NVIC_DisableIRQ(ADC3_IRQn); /* USER CODE BEGIN ADC3_MspDeInit 1 */ /* USER CODE END ADC3_MspDeInit 1 */ diff --git a/32blit-stm32/Src/dac.c b/32blit-stm32/Src/dac.c index e4ea7b350..c58d615ae 100644 --- a/32blit-stm32/Src/dac.c +++ b/32blit-stm32/Src/dac.c @@ -80,7 +80,7 @@ void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle) /* DAC1 DMA Init */ /* DAC1_CH2 Init */ - hdma_dac1_ch2.Instance = DMA1_Stream0; + hdma_dac1_ch2.Instance = DMA1_Stream2; hdma_dac1_ch2.Init.Request = DMA_REQUEST_DAC2; hdma_dac1_ch2.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_dac1_ch2.Init.PeriphInc = DMA_PINC_DISABLE; @@ -88,7 +88,7 @@ void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle) hdma_dac1_ch2.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_dac1_ch2.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_dac1_ch2.Init.Mode = DMA_CIRCULAR; - hdma_dac1_ch2.Init.Priority = DMA_PRIORITY_HIGH; + hdma_dac1_ch2.Init.Priority = DMA_PRIORITY_LOW; hdma_dac1_ch2.Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma_dac1_ch2.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_dac1_ch2.Init.MemBurst = DMA_MBURST_SINGLE; @@ -99,6 +99,16 @@ void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle) Error_Handler(); } + pSyncConfig.SyncSignalID = HAL_DMAMUX1_SYNC_EXTI0; + pSyncConfig.SyncPolarity = HAL_DMAMUX_SYNC_NO_EVENT; + pSyncConfig.SyncEnable = DISABLE; + pSyncConfig.EventEnable = ENABLE; + pSyncConfig.RequestNumber = 1; + if (HAL_DMAEx_ConfigMuxSync(&hdma_dac1_ch2, &pSyncConfig) != HAL_OK) + { + Error_Handler(); + } + __HAL_LINKDMA(dacHandle,DMA_Handle2,hdma_dac1_ch2); /* USER CODE BEGIN DAC1_MspInit 1 */ diff --git a/32blit-stm32/Src/dma.c b/32blit-stm32/Src/dma.c index 611fdd565..de743897d 100644 --- a/32blit-stm32/Src/dma.c +++ b/32blit-stm32/Src/dma.c @@ -40,11 +40,18 @@ void MX_DMA_Init(void) /* DMA controller clock enable */ __HAL_RCC_DMA1_CLK_ENABLE(); + __HAL_RCC_DMA2_CLK_ENABLE(); /* DMA interrupt init */ /* DMA1_Stream0_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn); + /* DMA1_Stream1_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn); + /* DMA1_Stream2_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn); /* DMAMUX1_OVR_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMAMUX1_OVR_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMAMUX1_OVR_IRQn); diff --git a/32blit-stm32/Src/stm32h7xx_it.c b/32blit-stm32/Src/stm32h7xx_it.c index b0f9069c3..3647415a6 100644 --- a/32blit-stm32/Src/stm32h7xx_it.c +++ b/32blit-stm32/Src/stm32h7xx_it.c @@ -62,8 +62,13 @@ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ +extern DMA_HandleTypeDef hdma_adc1; +extern DMA_HandleTypeDef hdma_adc3; +extern ADC_HandleTypeDef hadc1; +extern ADC_HandleTypeDef hadc3; extern PCD_HandleTypeDef hpcd_USB_OTG_HS; extern DMA_HandleTypeDef hdma_dac1_ch2; +extern LTDC_HandleTypeDef hltdc; /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -212,13 +217,54 @@ void DMA1_Stream0_IRQHandler(void) /* USER CODE BEGIN DMA1_Stream0_IRQn 0 */ /* USER CODE END DMA1_Stream0_IRQn 0 */ - HAL_DMA_IRQHandler(&hdma_dac1_ch2); - + HAL_DMA_IRQHandler(&hdma_adc1); /* USER CODE BEGIN DMA1_Stream0_IRQn 1 */ - + /* USER CODE END DMA1_Stream0_IRQn 1 */ } +/** + * @brief This function handles DMA1 stream1 global interrupt. + */ +void DMA1_Stream1_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */ + + /* USER CODE END DMA1_Stream1_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_adc3); + /* USER CODE BEGIN DMA1_Stream1_IRQn 1 */ + + /* USER CODE END DMA1_Stream1_IRQn 1 */ +} + +/** + * @brief This function handles DMA1 stream2 global interrupt. + */ +void DMA1_Stream2_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Stream2_IRQn 0 */ + + /* USER CODE END DMA1_Stream2_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_dac1_ch2); + /* USER CODE BEGIN DMA1_Stream2_IRQn 1 */ + + /* USER CODE END DMA1_Stream2_IRQn 1 */ +} + +/** + * @brief This function handles ADC1 and ADC2 global interrupts. + */ +void ADC_IRQHandler(void) +{ + /* USER CODE BEGIN ADC_IRQn 0 */ + + /* USER CODE END ADC_IRQn 0 */ + HAL_ADC_IRQHandler(&hadc1); + /* USER CODE BEGIN ADC_IRQn 1 */ + + /* USER CODE END ADC_IRQn 1 */ +} + /** * @brief This function handles USB On The Go HS global interrupt. */ @@ -248,6 +294,20 @@ void DMAMUX1_OVR_IRQHandler(void) /* USER CODE END DMAMUX1_OVR_IRQn 1 */ } +/** + * @brief This function handles ADC3 global interrupt. + */ +void ADC3_IRQHandler(void) +{ + /* USER CODE BEGIN ADC3_IRQn 0 */ + + /* USER CODE END ADC3_IRQn 0 */ + HAL_ADC_IRQHandler(&hadc3); + /* USER CODE BEGIN ADC3_IRQn 1 */ + + /* USER CODE END ADC3_IRQn 1 */ +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/hardware/STM32H750VBTx.ioc b/hardware/STM32H750VBTx.ioc index e9a1156d1..aed645cd4 100644 --- a/hardware/STM32H750VBTx.ioc +++ b/hardware/STM32H750VBTx.ioc @@ -2,12 +2,15 @@ ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_4 ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_10 ADC1.ClockPrescaler=ADC_CLOCK_ASYNC_DIV4 -ADC1.ContinuousConvMode=DISABLE -ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,ContinuousConvMode,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,NbrOfConversion,Resolution,master,OversamplingMode,RightBitShift,Ratio,ClockPrescaler +ADC1.ContinuousConvMode=ENABLE +ADC1.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR +ADC1.EOCSelection=ADC_EOC_SEQ_CONV +ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,ContinuousConvMode,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,NbrOfConversion,Resolution,master,OversamplingMode,RightBitShift,Ratio,ClockPrescaler,EOCSelection,ConversionDataManagement,Overrun ADC1.NbrOfConversion=2 ADC1.NbrOfConversionFlag=1 ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE ADC1.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.Overrun=ADC_OVR_DATA_OVERWRITTEN ADC1.OversamplingMode=ENABLE ADC1.Rank-0\#ChannelRegularConversion=1 ADC1.Rank-1\#ChannelRegularConversion=2 @@ -21,12 +24,16 @@ ADC3.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_11 ADC3.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_0 ADC3.Channel-2\#ChannelRegularConversion=ADC_CHANNEL_1 ADC3.ClockPrescaler=ADC_CLOCK_ASYNC_DIV4 -ADC3.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,Rank-2\#ChannelRegularConversion,Channel-2\#ChannelRegularConversion,SamplingTime-2\#ChannelRegularConversion,OffsetNumber-2\#ChannelRegularConversion,NbrOfConversion,OversamplingMode,Ratio,RightBitShift,ClockPrescaler +ADC3.ContinuousConvMode=ENABLE +ADC3.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR +ADC3.EOCSelection=ADC_EOC_SEQ_CONV +ADC3.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,Rank-2\#ChannelRegularConversion,Channel-2\#ChannelRegularConversion,SamplingTime-2\#ChannelRegularConversion,OffsetNumber-2\#ChannelRegularConversion,NbrOfConversion,OversamplingMode,Ratio,RightBitShift,ClockPrescaler,ContinuousConvMode,EOCSelection,Overrun,ConversionDataManagement ADC3.NbrOfConversion=3 ADC3.NbrOfConversionFlag=1 ADC3.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE ADC3.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE ADC3.OffsetNumber-2\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC3.Overrun=ADC_OVR_DATA_OVERWRITTEN ADC3.OversamplingMode=ENABLE ADC3.Rank-0\#ChannelRegularConversion=1 ADC3.Rank-1\#ChannelRegularConversion=2 @@ -45,10 +52,46 @@ DAC1.IPParameters=DAC_Channel-DAC_OUT2,DAC_Trigger-DAC_OUT2 DMA2D.ColorMode=DMA2D_OUTPUT_RGB565 DMA2D.IPParameters=ColorMode,Mode DMA2D.Mode=DMA2D_R2M +Dma.ADC1.1.Direction=DMA_PERIPH_TO_MEMORY +Dma.ADC1.1.EventEnable=DISABLE +Dma.ADC1.1.FIFOMode=DMA_FIFOMODE_DISABLE +Dma.ADC1.1.Instance=DMA1_Stream0 +Dma.ADC1.1.MemDataAlignment=DMA_MDATAALIGN_HALFWORD +Dma.ADC1.1.MemInc=DMA_MINC_ENABLE +Dma.ADC1.1.Mode=DMA_NORMAL +Dma.ADC1.1.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD +Dma.ADC1.1.PeriphInc=DMA_PINC_DISABLE +Dma.ADC1.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING +Dma.ADC1.1.Priority=DMA_PRIORITY_LOW +Dma.ADC1.1.RequestNumber=1 +Dma.ADC1.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber +Dma.ADC1.1.SignalID=NONE +Dma.ADC1.1.SyncEnable=DISABLE +Dma.ADC1.1.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT +Dma.ADC1.1.SyncRequestNumber=1 +Dma.ADC1.1.SyncSignalID=NONE +Dma.ADC3.2.Direction=DMA_PERIPH_TO_MEMORY +Dma.ADC3.2.EventEnable=DISABLE +Dma.ADC3.2.FIFOMode=DMA_FIFOMODE_DISABLE +Dma.ADC3.2.Instance=DMA1_Stream1 +Dma.ADC3.2.MemDataAlignment=DMA_MDATAALIGN_HALFWORD +Dma.ADC3.2.MemInc=DMA_MINC_ENABLE +Dma.ADC3.2.Mode=DMA_NORMAL +Dma.ADC3.2.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD +Dma.ADC3.2.PeriphInc=DMA_PINC_DISABLE +Dma.ADC3.2.Polarity=HAL_DMAMUX_REQ_GEN_RISING +Dma.ADC3.2.Priority=DMA_PRIORITY_LOW +Dma.ADC3.2.RequestNumber=1 +Dma.ADC3.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber +Dma.ADC3.2.SignalID=NONE +Dma.ADC3.2.SyncEnable=DISABLE +Dma.ADC3.2.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT +Dma.ADC3.2.SyncRequestNumber=1 +Dma.ADC3.2.SyncSignalID=NONE Dma.DAC1_CH2.0.Direction=DMA_MEMORY_TO_PERIPH Dma.DAC1_CH2.0.EventEnable=ENABLE Dma.DAC1_CH2.0.FIFOMode=DMA_FIFOMODE_DISABLE -Dma.DAC1_CH2.0.Instance=DMA1_Stream0 +Dma.DAC1_CH2.0.Instance=DMA1_Stream2 Dma.DAC1_CH2.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD Dma.DAC1_CH2.0.MemInc=DMA_MINC_ENABLE Dma.DAC1_CH2.0.Mode=DMA_CIRCULAR @@ -64,7 +107,9 @@ Dma.DAC1_CH2.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT Dma.DAC1_CH2.0.SyncRequestNumber=1 Dma.DAC1_CH2.0.SyncSignalID=NONE Dma.Request0=DAC1_CH2 -Dma.RequestsNb=1 +Dma.Request1=ADC1 +Dma.Request2=ADC3 +Dma.RequestsNb=3 File.Version=6 GPIO.groupedBy=Group By Peripherals HRTIM.IPParameters=PrescalerRatio_MASTER,SyncOptions @@ -218,12 +263,17 @@ Mcu.UserConstants= Mcu.UserName=STM32H750VBTx MxCube.Version=5.4.0 MxDb.Version=DB.5.0.40 +NVIC.ADC3_IRQn=true\:0\:0\:false\:false\:true\:true\:true +NVIC.ADC_IRQn=true\:0\:0\:false\:false\:true\:true\:true NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.DMA1_Stream0_IRQn=true\:0\:0\:false\:false\:true\:false\:true +NVIC.DMA1_Stream1_IRQn=true\:0\:0\:false\:false\:true\:false\:true +NVIC.DMA1_Stream2_IRQn=true\:0\:0\:false\:false\:true\:false\:true NVIC.DMAMUX1_OVR_IRQn=true\:0\:0\:false\:false\:true\:false\:true NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.ForceEnableDMAVector=false NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.LTDC_IRQn=true\:0\:0\:false\:false\:true\:true\:true NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false @@ -508,7 +558,7 @@ PH1-OSC_OUT\ (PH1).Locked=true PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT PinOutPanel.RotationAngle=0 -ProjectManager.AskForMigrate=false +ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false ProjectManager.CompilerOptimize=6 ProjectManager.ComputerToolchain=false @@ -534,7 +584,7 @@ ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=Makefile ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-MX_DMA_Init-DMA-false-HAL-true,3-SystemClock_Config-RCC-false-HAL-false,4-MX_TIM4_Init-TIM4-false-HAL-true,5-MX_TIM3_Init-TIM3-false-HAL-true,6-MX_DAC1_Init-DAC1-false-HAL-true,7-MX_HRTIM_Init-HRTIM-false-HAL-true,8-MX_I2C4_Init-I2C4-false-HAL-true,9-MX_LTDC_Init-LTDC-false-HAL-true,10-MX_QUADSPI_Init-QUADSPI-false-HAL-true,11-MX_ADC1_Init-ADC1-false-HAL-true,12-MX_ADC3_Init-ADC3-false-HAL-true,13-MX_USB_OTG_HS_USB_Init-USB_OTG_HS-false-HAL-true,14-MX_SPI1_Init-SPI1-false-HAL-true,15-MX_SPI4_Init-SPI4-false-HAL-true,16-MX_TIM6_Init-TIM6-false-HAL-true,17-MX_TIM15_Init-TIM15-false-HAL-true,18-MX_FATFS_Init-FATFS-false-HAL-false,19-MX_DMA2D_Init-DMA2D-false-HAL-true,20-MX_HASH_Init-HASH-false-HAL-true,21-MX_RNG_Init-RNG-false-HAL-true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-MX_BDMA_Init-BDMA-false-HAL-true,3-SystemClock_Config-RCC-false-HAL-false,4-MX_TIM4_Init-TIM4-false-HAL-true,5-MX_TIM3_Init-TIM3-false-HAL-true,6-MX_DAC1_Init-DAC1-false-HAL-true,7-MX_HRTIM_Init-HRTIM-false-HAL-true,8-MX_I2C4_Init-I2C4-false-HAL-true,9-MX_LTDC_Init-LTDC-false-HAL-true,10-MX_QUADSPI_Init-QUADSPI-false-HAL-true,11-MX_ADC1_Init-ADC1-false-HAL-true,12-MX_ADC3_Init-ADC3-false-HAL-true,13-MX_USB_OTG_HS_USB_Init-USB_OTG_HS-false-HAL-true,14-MX_SPI1_Init-SPI1-false-HAL-true,15-MX_SPI4_Init-SPI4-false-HAL-true,16-MX_TIM6_Init-TIM6-false-HAL-true,17-MX_TIM15_Init-TIM15-false-HAL-true,18-MX_FATFS_Init-FATFS-false-HAL-false,19-MX_DMA2D_Init-DMA2D-false-HAL-true,20-MX_HASH_Init-HASH-false-HAL-true,21-MX_RNG_Init-RNG-false-HAL-true,22-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true QUADSPI.ClockMode=QSPI_CLOCK_MODE_3 QUADSPI.ClockPrescaler=128 QUADSPI.IPParameters=ClockPrescaler,ClockMode From 83000a154fa5969b02a92e38e6ef86b5ddf14f06 Mon Sep 17 00:00:00 2001 From: lowfatcode Date: Fri, 31 Jan 2020 11:56:07 +0000 Subject: [PATCH 04/14] Only enble line interrupt after render completes --- 32blit-stm32/Src/32blit.c | 41 ++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c index 16b62ee24..dd3935966 100644 --- a/32blit-stm32/Src/32blit.c +++ b/32blit-stm32/Src/32blit.c @@ -37,6 +37,7 @@ FRESULT SD_FileOpenError = FR_INVALID_PARAMETER; uint32_t total_samples = 0; uint8_t dma_status = 0; bool needs_render = true; +uint32_t flip_cycle_count = 0; static blit::screen_mode mode = blit::screen_mode::lores; @@ -111,10 +112,11 @@ uint32_t blit_update_dac(FIL *audio_file) { void blit_tick() { - if(needs_render) { + if(needs_render) { blit::render(blit::now()); - + HAL_LTDC_ProgramLineEvent(&hltdc, 252); + needs_render = false; blit::LED.r = ~blit::LED.r; } @@ -170,10 +172,12 @@ void blit_init() { for(int x = 0; xDEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CYCCNT = 0; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + ST7272A_RESET(); st7272a_set_bgr(); @@ -200,7 +204,7 @@ void blit_init() { HAL_NVIC_SetPriority(LTDC_IRQn, 4, 4); HAL_NVIC_EnableIRQ(LTDC_IRQn); - HAL_LTDC_ProgramLineEvent(&hltdc, 250); + HAL_LTDC_ProgramLineEvent(&hltdc, 252); } void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *p) { @@ -209,8 +213,6 @@ void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *p) { needs_render = true; blit::LED.b++; blit_update_led(); - - HAL_LTDC_ProgramLineEvent(&hltdc, 250); } int menu_item = 0; @@ -383,7 +385,12 @@ void blit_menu() { */ void blit_flip() { if(mode == screen_mode::hires) { - memcpy((uint8_t *)(__ltdc.data), (uint8_t *)(__fb_hires.data), 320 * 240 * 2); + uint32_t c = (320 * 240 * 2) / 4; + uint32_t *d = (uint32_t *)(__ltdc.data); + uint32_t *s = (uint32_t *)(__fb_hires.data); + while(c--) { + *d++ = *s++; + } } else { // pixel double the framebuffer to the LTDC buffer rgb *src = (rgb *)__fb_lores.data; @@ -402,10 +409,16 @@ void blit_flip() { } // copy the previous converted row (640 bytes / 320 x 2-byte pixels) - memcpy((uint8_t *)(dest), (uint8_t *)(dest) - 640, 640); + uint32_t c = 640 / 4; + uint32_t *d = (uint32_t *)(dest); + uint32_t *s = (uint32_t *)(dest - 320); + while(c--) { + *d++ = *s++; + } + dest += 320; } - } + } SCB_CleanInvalidateDCache_by_Addr((uint32_t *)&__ltdc_start, 320 * 240 * 2); } @@ -442,7 +455,7 @@ void blit_update_led() { } void ADC_update_joystick_axis(ADC_HandleTypeDef *adc, float *axis){ - if (HAL_ADC_PollForConversion(adc, 1000000) == HAL_OK) + if (HAL_ADC_PollForConversion(adc, 1) == HAL_OK) { int adc_reading = (HAL_ADC_GetValue(adc) >> 1) - 16384; adc_reading = std::max(-8192, std::min(8192, adc_reading)); @@ -478,7 +491,7 @@ void blit_process_input() { HAL_ADC_Start(&hadc3); ADC_update_joystick_axis(&hadc3, &blit::hack_left); ADC_update_joystick_axis(&hadc3, &blit::hack_right); - if (HAL_ADC_PollForConversion(&hadc3, 1000000) == HAL_OK) + if (HAL_ADC_PollForConversion(&hadc3, 1) == HAL_OK) { blit::battery = 6.6f * HAL_ADC_GetValue(&hadc3) / 65535.0f; } From 604d8f05394856d60fd123ee2d6f91ab97bba7eb Mon Sep 17 00:00:00 2001 From: lowfatcode Date: Fri, 31 Jan 2020 13:22:07 +0000 Subject: [PATCH 05/14] Faster flips --- 32blit-stm32/Src/32blit.c | 31 +++++++++++++++++++++++-------- examples/particle/particle.cpp | 15 +++++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c index dd3935966..41c6081df 100644 --- a/32blit-stm32/Src/32blit.c +++ b/32blit-stm32/Src/32blit.c @@ -45,7 +45,7 @@ static blit::screen_mode mode = blit::screen_mode::lores; surface __ltdc((uint8_t *)&__ltdc_start, pixel_format::RGB565, size(320, 240)); surface __fb_hires((uint8_t *)&__fb_start, pixel_format::RGB565, size(320, 240)); -surface __fb_lores((uint8_t *)&__fb_start, pixel_format::RGB, size(160, 120)); +surface __fb_lores((uint8_t *)&__fb_start, pixel_format::RGBA, size(160, 120)); void DFUBoot(void) { @@ -115,6 +115,10 @@ void blit_tick() { if(needs_render) { blit::render(blit::now()); + // debug cycle count for flip + //blit::fb.pen(rgba(255, 255, 255)); + //blit::fb.text(std::to_string(flip_cycle_count), &minimal_font[0][0], point(10, 20)); + HAL_LTDC_ProgramLineEvent(&hltdc, 252); needs_render = false; @@ -384,27 +388,36 @@ void blit_menu() { * In high-res mode it simply points LTDC at the freshly drawn buffer and gives 32blit the other buffer to draw into. */ void blit_flip() { + uint32_t scc = DWT->CYCCNT; + if(mode == screen_mode::hires) { - uint32_t c = (320 * 240 * 2) / 4; + uint32_t c = (320 * 240 * 2) / 4 / 8; uint32_t *d = (uint32_t *)(__ltdc.data); uint32_t *s = (uint32_t *)(__fb_hires.data); while(c--) { *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; } } else { // pixel double the framebuffer to the LTDC buffer - rgb *src = (rgb *)__fb_lores.data; - + uint32_t *src = (uint32_t *)__fb_lores.data; uint16_t *dest = (uint16_t *)(&__ltdc_start); for(uint8_t y = 0; y < 120; y++) { // pixel double the current row while converting from RGBA to RGB565 for(uint8_t x = 0; x < 160; x++) { - uint8_t r = src->r >> 3; - uint8_t g = src->g >> 2; - uint8_t b = src->b >> 3; - uint16_t c = (r << 11) | (g << 5) | (b); + uint32_t s = *src; + + uint16_t c = ((s & 0xf8000000) >> 27) | ((s & 0x00fc0000) >> 13) | ((s & 0x0000f800)); + *dest++ = c; *dest++ = c; + src++; } @@ -420,6 +433,8 @@ void blit_flip() { } } + flip_cycle_count = DWT->CYCCNT - scc; + SCB_CleanInvalidateDCache_by_Addr((uint32_t *)&__ltdc_start, 320 * 240 * 2); } diff --git a/examples/particle/particle.cpp b/examples/particle/particle.cpp index 16756eb3e..ee1373513 100644 --- a/examples/particle/particle.cpp +++ b/examples/particle/particle.cpp @@ -226,9 +226,24 @@ void render_basic_rain() { } } +uint32_t prev_buttons = blit::buttons; void render(uint32_t time_ms) { +uint16_t width; +uint16_t height; + if ((blit::buttons ^ prev_buttons) & blit::button::A) { + blit::set_screen_mode(blit::lores); + width = 160; + height = 120; + } + else if ((blit::buttons ^ prev_buttons) & blit::button::B) { + blit::set_screen_mode(blit::hires); + width = 320; + height = 240; + } + prev_buttons = blit::buttons; + fb.pen(rgba(0, 0, 0, 255)); fb.clear(); From 50af11aac0b54a6aff2a2405fd5d5d08d9595bfc Mon Sep 17 00:00:00 2001 From: lowfatcode Date: Fri, 31 Jan 2020 13:28:59 +0000 Subject: [PATCH 06/14] Faster lores flip --- 32blit-stm32/Src/32blit.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c index 41c6081df..58b55f4e9 100644 --- a/32blit-stm32/Src/32blit.c +++ b/32blit-stm32/Src/32blit.c @@ -116,8 +116,8 @@ void blit_tick() { blit::render(blit::now()); // debug cycle count for flip - //blit::fb.pen(rgba(255, 255, 255)); - //blit::fb.text(std::to_string(flip_cycle_count), &minimal_font[0][0], point(10, 20)); + blit::fb.pen(rgba(255, 255, 255)); + blit::fb.text(std::to_string(flip_cycle_count), &minimal_font[0][0], point(10, 20)); HAL_LTDC_ProgramLineEvent(&hltdc, 252); @@ -407,29 +407,18 @@ void blit_flip() { } else { // pixel double the framebuffer to the LTDC buffer uint32_t *src = (uint32_t *)__fb_lores.data; - uint16_t *dest = (uint16_t *)(&__ltdc_start); + uint32_t *dest = (uint32_t *)(&__ltdc_start); for(uint8_t y = 0; y < 120; y++) { // pixel double the current row while converting from RGBA to RGB565 for(uint8_t x = 0; x < 160; x++) { - uint32_t s = *src; - - uint16_t c = ((s & 0xf8000000) >> 27) | ((s & 0x00fc0000) >> 13) | ((s & 0x0000f800)); - - *dest++ = c; - *dest++ = c; - - src++; + uint32_t s = *src++; + uint16_t c = ((s & 0xf8000000) >> 27) | ((s & 0x00fc0000) >> 13) | ((s & 0x0000f800)); + *(dest) = c | (c << 16); + *(dest + 160) = c | (c << 16); + dest++; } - // copy the previous converted row (640 bytes / 320 x 2-byte pixels) - uint32_t c = 640 / 4; - uint32_t *d = (uint32_t *)(dest); - uint32_t *s = (uint32_t *)(dest - 320); - while(c--) { - *d++ = *s++; - } - - dest += 320; + dest += 160; // skip the doubled row } } From 55ba5783fee141a163992004fb9a6fd9ad30a828 Mon Sep 17 00:00:00 2001 From: lowfatcode Date: Fri, 31 Jan 2020 13:29:42 +0000 Subject: [PATCH 07/14] Aaaaand remove the debugging text... --- 32blit-stm32/Src/32blit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c index 58b55f4e9..7b5906ff2 100644 --- a/32blit-stm32/Src/32blit.c +++ b/32blit-stm32/Src/32blit.c @@ -116,8 +116,8 @@ void blit_tick() { blit::render(blit::now()); // debug cycle count for flip - blit::fb.pen(rgba(255, 255, 255)); - blit::fb.text(std::to_string(flip_cycle_count), &minimal_font[0][0], point(10, 20)); +// blit::fb.pen(rgba(255, 255, 255)); + // blit::fb.text(std::to_string(flip_cycle_count), &minimal_font[0][0], point(10, 20)); HAL_LTDC_ProgramLineEvent(&hltdc, 252); From ba627d5af8eb4e92e9447adb4090266e34878c45 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 31 Jan 2020 14:22:38 +0000 Subject: [PATCH 08/14] Working ADC DMA This change completes the switch over from polling ADC to an interrupt-driven DMA setup. ADC polling was previously calling hangups presumably with some register or issue with SysTick. And this method is nicer. ADC3 currently has something of a hack to align the channel reads to the 32 sample circular buffer. --- 32blit-stm32/Src/32blit.c | 112 +++++++++++++++++--------------------- 32blit-stm32/Src/adc.c | 28 +++++++--- 2 files changed, 71 insertions(+), 69 deletions(-) diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c index c451af98b..bc59ca5e5 100644 --- a/32blit-stm32/Src/32blit.c +++ b/32blit-stm32/Src/32blit.c @@ -27,8 +27,10 @@ extern char itcm_text_start; extern char itcm_text_end; extern char itcm_data; -ALIGN_32BYTES (static uint16_t adc1data[32]); -ALIGN_32BYTES (static uint16_t adc3data[32]); +#define ADC_BUFFER_SIZE 32 + +__attribute__((section(".dac_data"))) ALIGN_32BYTES(__IO uint16_t adc1data[ADC_BUFFER_SIZE]); +__attribute__((section(".dac_data"))) ALIGN_32BYTES(__IO uint16_t adc3data[ADC_BUFFER_SIZE]); FATFS filesystem; FRESULT SD_Error = FR_INVALID_PARAMETER; @@ -158,12 +160,12 @@ void blit_init() { for(int x = 0; x> 1) - 16384; - adc_reading = std::max(-8192, std::min(8192, adc_reading)); - if (adc_reading < -1024) { - adc_reading += 1024; - } - else if (adc_reading > 1024) { - adc_reading -= 1024; - } - else { - adc_reading = 0; - } - *axis = adc_reading / 7168.0f; - } +void HAL_ADC_ErrorCallback(ADC_HandleTypeDef* hadc){ } -*/ void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc){ - blit::LED.g = 255; - blit_update_led(); if(hadc->Instance == ADC1) { - SCB_InvalidateDCache_by_Addr((uint32_t *) &adc1data[0], 32); + SCB_InvalidateDCache_by_Addr((uint32_t *) &adc1data[0], ADC_BUFFER_SIZE); } else if (hadc->Instance == ADC3) { - SCB_InvalidateDCache_by_Addr((uint32_t *) &adc3data[0], 32); + SCB_InvalidateDCache_by_Addr((uint32_t *) &adc3data[0], ADC_BUFFER_SIZE); } } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { - blit::LED.r = 255; - blit_update_led(); if(hadc->Instance == ADC1) { - SCB_InvalidateDCache_by_Addr((uint32_t *) &adc1data[16], 16); - /* + SCB_InvalidateDCache_by_Addr((uint32_t *) &adc1data[ADC_BUFFER_SIZE / 2], ADC_BUFFER_SIZE / 2); + + int joystick_x = (adc1data[0] >> 1) - 16384; + joystick_x = std::max(-8192, std::min(8192, joystick_x)); + if(joystick_x < -1024) { + joystick_x += 1024; + } + else if(joystick_x > 1024) { + joystick_x -= 1024; + } else { + joystick_x = 0; + } + blit::joystick.x = joystick_x / 7168.0f; - int joystick_y = (adc1data[0] >> 1) - 16384; + int joystick_y = (adc1data[1] >> 1) - 16384; joystick_y = std::max(-8192, std::min(8192, joystick_y)); if(joystick_y < -1024) { joystick_y += 1024; @@ -511,23 +503,36 @@ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { } else { joystick_y = 0; } - blit::joystick.y = joystick_y / 7168.0f; + blit::joystick.y = -joystick_y / 7168.0f; - int joystick_x = (adc1data[1] >> 1) - 16384; - joystick_x = std::max(-8192, std::min(8192, joystick_x)); - if(joystick_x < -1024) { - joystick_x += 1024; + } else if (hadc->Instance == ADC3) { + SCB_InvalidateDCache_by_Addr((uint32_t *) &adc3data[ADC_BUFFER_SIZE / 2], ADC_BUFFER_SIZE / 2); + + int hack_left = (adc3data[0] >> 1) - 16384; + hack_left = std::max(-8192, std::min(8192, hack_left)); + if(hack_left < -1024) { + hack_left += 1024; } - else if(joystick_x > 1024) { - joystick_x -= 1024; + else if(hack_left > 1024) { + hack_left -= 1024; } else { - joystick_x = 0; + hack_left = 0; } - blit::joystick.x = joystick_x / 7168.0f; - */ - } else if (hadc->Instance == ADC3) { - SCB_InvalidateDCache_by_Addr((uint32_t *) &adc3data[16], 16); + blit::hack_left = hack_left / 7168.0f; + + int hack_right = (adc3data[1] >> 1) - 16384; + hack_right = std::max(-8192, std::min(8192, hack_right)); + if(hack_right < -1024) { + hack_right += 1024; + } + else if(hack_right > 1024) { + hack_right -= 1024; + } else { + hack_right = 0; + } + blit::hack_right = -hack_right / 7168.0f; + blit::battery = 6.6 * adc3data[2] / 65535.0f; } } @@ -541,21 +546,6 @@ void blit_process_input() { // read x axis of joystick bool joystick_button = false; - /*HAL_ADC_Start(&hadc1); - ADC_update_joystick_axis(&hadc1, &blit::joystick.x); - ADC_update_joystick_axis(&hadc1, &blit::joystick.y); - blit::joystick.y = -blit::joystick.y; - HAL_ADC_Stop(&hadc1); - - HAL_ADC_Start(&hadc3); - ADC_update_joystick_axis(&hadc3, &blit::hack_left); - ADC_update_joystick_axis(&hadc3, &blit::hack_right); - if (HAL_ADC_PollForConversion(&hadc3, 1000000) == HAL_OK) - { - blit::battery = 6.6f * HAL_ADC_GetValue(&hadc3) / 65535.0f; - } - HAL_ADC_Stop(&hadc3);*/ - // Read buttons blit::buttons = (!HAL_GPIO_ReadPin(DPAD_UP_GPIO_Port, DPAD_UP_Pin) ? blit::DPAD_UP : 0) | diff --git a/32blit-stm32/Src/adc.c b/32blit-stm32/Src/adc.c index 8198eb007..a3d1482c5 100644 --- a/32blit-stm32/Src/adc.c +++ b/32blit-stm32/Src/adc.c @@ -38,7 +38,7 @@ void MX_ADC1_Init(void) /** Common config */ hadc1.Instance = ADC1; - hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; + hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV8; hadc1.Init.Resolution = ADC_RESOLUTION_16B; hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; @@ -97,13 +97,13 @@ void MX_ADC3_Init(void) /** Common config */ hadc3.Instance = ADC3; - hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; + hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV8; hadc3.Init.Resolution = ADC_RESOLUTION_16B; hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE; hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV; hadc3.Init.LowPowerAutoWait = DISABLE; hadc3.Init.ContinuousConvMode = ENABLE; - hadc3.Init.NbrOfConversion = 3; + hadc3.Init.NbrOfConversion = 4; hadc3.Init.DiscontinuousConvMode = DISABLE; hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; @@ -147,7 +147,19 @@ void MX_ADC3_Init(void) { Error_Handler(); } - + /** Configure Regular Channel + * Reading ADC channel twice, just to make sure + * I kid. This is actually here because the DMA transfer is circular, + * and 3 readings into a 32-sample buffer means we have a phase problem. + * Adding this reading will ensure our 3 ADC readings are always left-aligned. + * TODO: There must be a sensible way to fix this. + */ + sConfig.Channel = ADC_CHANNEL_1; + sConfig.Rank = ADC_REGULAR_RANK_4; + if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK) + { + Error_Handler(); + } } void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) @@ -181,9 +193,9 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; - hdma_adc1.Init.Mode = DMA_NORMAL; + hdma_adc1.Init.Mode = DMA_CIRCULAR; hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM; - hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_ENABLE; if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) { Error_Handler(); @@ -230,9 +242,9 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) hdma_adc3.Init.MemInc = DMA_MINC_ENABLE; hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; - hdma_adc3.Init.Mode = DMA_NORMAL; + hdma_adc3.Init.Mode = DMA_CIRCULAR; hdma_adc3.Init.Priority = DMA_PRIORITY_MEDIUM; - hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_ENABLE; if (HAL_DMA_Init(&hdma_adc3) != HAL_OK) { Error_Handler(); From 9817905d5c409869aa4afd5987c5a929a5db4eee Mon Sep 17 00:00:00 2001 From: lowfatcode Date: Fri, 31 Jan 2020 15:12:12 +0000 Subject: [PATCH 09/14] Add P_RGBA blend support for surface --- 32blit-stm32/Src/main.c | 2 +- 32blit/graphics/blend.cpp | 33 ++++ 32blit/graphics/surface.cpp | 2 +- examples/particle/particle.cpp | 306 +++------------------------------ 4 files changed, 58 insertions(+), 285 deletions(-) diff --git a/32blit-stm32/Src/main.c b/32blit-stm32/Src/main.c index 7b17e65e7..6988e4caf 100644 --- a/32blit-stm32/Src/main.c +++ b/32blit-stm32/Src/main.c @@ -237,7 +237,7 @@ void SystemClock_Config(void) PeriphClkInitStruct.PLL3.PLL3N = 129; PeriphClkInitStruct.PLL3.PLL3P = 2; PeriphClkInitStruct.PLL3.PLL3Q = 2; - PeriphClkInitStruct.PLL3.PLL3R = 53; + PeriphClkInitStruct.PLL3.PLL3R = 45; PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_1; PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE; PeriphClkInitStruct.PLL3.PLL3FRACN = 0; diff --git a/32blit/graphics/blend.cpp b/32blit/graphics/blend.cpp index 779704939..36c8991af 100644 --- a/32blit/graphics/blend.cpp +++ b/32blit/graphics/blend.cpp @@ -253,6 +253,39 @@ namespace blit { } while (--count); } + + void P_RGBA(surface *src, int32_t src_offset, surface *dest, int32_t dest_offset, uint16_t count, int16_t src_step) { + uint8_t *ps = (uint8_t *)src->data; // source pointer + rgba *pd = (rgba *)dest->data; // destination pointer + uint8_t *pm = nullptr; // mask pointer + uint16_t ga = dest->alpha + 1; // global alpha + + if (dest->mask) { + pm = dest->mask->data; + pm += dest_offset; + } + + ps += src_offset; + pd += dest_offset; + + rgba* palette = src->palette.data(); + + do { + rgba *pps = &palette[*ps]; + + COMBINE_ALPHA(a, pps->a, ga, pm) + + if (a == 255) { + pd->r = pps->r; pd->g = pps->g; pd->b = pps->b; + } else if (a == 0) { + } else { + RGB_BLEND(pps->r, pps->g, pps->b, pd->r, pd->g, pd->b, a) + } + + ps += src_step; + pd++; + } while (--count); + } void P_RGB(surface *src, int32_t src_offset, surface *dest, int32_t dest_offset, uint16_t count, int16_t src_step) { uint8_t *ps = (uint8_t *)src->data; // source pointer diff --git a/32blit/graphics/surface.cpp b/32blit/graphics/surface.cpp index 7054f08cf..358801215 100644 --- a/32blit/graphics/surface.cpp +++ b/32blit/graphics/surface.cpp @@ -35,7 +35,7 @@ namespace blit { switch (format) { case pixel_format::RGBA: { bf = RGBA_RGBA; - bbf = { nullptr, nullptr, nullptr, nullptr, nullptr }; + bbf = { nullptr, nullptr, nullptr, P_RGBA, nullptr }; }break; case pixel_format::RGB: { bf = RGBA_RGB; diff --git a/examples/particle/particle.cpp b/examples/particle/particle.cpp index ee1373513..342b62555 100644 --- a/examples/particle/particle.cpp +++ b/examples/particle/particle.cpp @@ -1,295 +1,35 @@ -#include -#include -#include -#include +// Tearing test -#include "particle.hpp" - -using namespace blit; - - - -/* setup */ -void init() { - blit::set_screen_mode(screen_mode::hires); -} - -struct test_particle { - vec2 pos; - vec2 vel; - int age; - bool generated = false; -}; - - -struct smoke_particle : particle { - float age_boost; - - smoke_particle(vec2 pos, vec2 vel, float age_boost) : particle(pos, vel), age_boost(age_boost) {}; -}; - -particle* generate_smoke() { - return new smoke_particle( - vec2((rand() % 20) - 10, (rand() % 20) - 10), - vec2(((rand() % 40) - 20) / 2, (rand() % 20) - 60), - (rand() % 3000) / 3000.0f - ); -} - -generator smoke_generator(150, 4000, generate_smoke); - -void render_smoke() { - for (auto p : smoke_generator.particles) { - smoke_particle *sp = static_cast(p); - float age = sp->age + sp->age_boost; - int alpha = (255 - (age * 75.0f)) / 8.0f; - int radius = (age * 150.0f) / 16.0f; - fb.pen(rgba(255, 255, 255, alpha)); - fb.circle(p->pos + point(50, 240), radius); - } -} - -/* -void smoke_generate(test_particle &p) { - p.pos = vec2((rand() % 20) - 10, (rand() % 20) - 10); - p.vel = vec2(((rand() % 40) - 20) / 2, (rand() % 20) - 60); - p.age = rand() % 200; - p.generated = true; -}; - -void smoke(uint32_t time_ms) { - static test_particle s[150]; - static int generate_index = 0; - static uint32_t last_time_ms = time_ms; - - int elapsed_ms = time_ms - last_time_ms; - float td = (elapsed_ms) / 1000.0f; - - smoke_generate(s[generate_index++]); - if (generate_index >= 150) - generate_index = 0; - - float w = sin(time_ms / 1000.0f) * 0.05f; - - for (auto &p : s) { - if (p.generated) { - p.pos += p.vel * td; - p.vel += vec2(w, 0); - p.age++; - - int alpha = (255 - (p.age / 2)) / 8.0f; - int radius = (p.age) / 16.0f; - fb.pen(rgba(255, 255, 255, alpha)); - fb.circle(p.pos + point(50, 240), radius); - } - } - - - last_time_ms = time_ms; -}; -*/ - -void spark_generate(test_particle &p) { - p.pos = vec2((rand() % 10) - 5, -100); - p.vel = vec2(((rand() % 40) - 20), (rand() % 80) - 70); - p.age = 0;// rand() % 255; - p.generated = true; -}; - -void spark(uint32_t time_ms) { - static test_particle s[500]; - static int generate_index = 0; - static uint32_t last_time_ms = time_ms; - - int elapsed_ms = time_ms - last_time_ms; - float td = (elapsed_ms) / 1000.0f; - - spark_generate(s[generate_index++]); - if (generate_index >= 500) - generate_index = 0; - - float w = sin(time_ms / 1000.0f) * 0.05f; - - vec2 gravity = vec2(0, 9.8 * 2) * td; - - for (auto &p : s) { - if (p.generated) { - p.vel += gravity; - p.pos += p.vel * td; - if (p.pos.y > 0) - p.vel.y *= -0.7f; - p.age++; - - int a = p.age / 2; - int r = 255 - (p.age / 2); - int g = 255 - (a * 2); - g = g < 0 ? 0 : g; - int b = 255 - (a * 4); - b = b < 0 ? 0 : b; - - int bloom = (255 - a) / 64; - fb.pen(rgba(r, g, b, 16)); - fb.circle(p.pos + point(160, 240), bloom); - fb.pen(rgba(r, g, b, 16)); - fb.circle(p.pos + point(160, 240), bloom / 2); - - fb.pen(rgba(r, g, b)); - fb.pixel(p.pos + point(160, 240)); - - } - } - - last_time_ms = time_ms; -}; - - -void rain_generate(test_particle &p) { - p.pos = vec2((rand() % 80) - 40, (rand() % 10) - 250); - p.vel = vec2(0, 140); - p.age = 0;// rand() % 255; - p.generated = true; -}; - -vec2 g = vec2(0, 9.8 * 5); - -void rain(uint32_t time_ms) { - static test_particle s[200]; - static int generate_index = 0; - static uint32_t last_time_ms = time_ms; - - int elapsed_ms = time_ms - last_time_ms; - float td = (elapsed_ms) / 1000.0f; - - rain_generate(s[generate_index++]); - if (generate_index >= 200) - generate_index = 0; - - float w = sin(time_ms / 1000.0f) * 0.05f; - - vec2 gravity = g * td; - - for (auto &p : s) { - if (p.generated) { - p.vel += gravity; - p.pos += p.vel * td; - - int floor = -3; - if (p.pos.x > 20 && p.pos.x < 46) - floor = -33; - - if (p.pos.y >= floor) { - p.pos.y = floor; - float bounce = ((rand() % 10)) / 80.0f; - p.vel.y *= -bounce; - p.vel.x = ((rand() % 30) - 15); - } - p.age++; - - int a = p.age / 2; - int r = 150 - (a / 2); - int g = 150 - (a / 2); - int b = 255;// -(a * 4); - - if(p.vel.length() > 20) { - fb.pen(rgba(r, g, b, 100)); - fb.pixel(p.pos + point(270, 239)); - fb.pen(rgba(r, g, b, 160)); - fb.pixel(p.pos + point(270, 241)); - } - fb.pen(rgba(r, g, b, 180)); - fb.pixel(p.pos + point(270, 242)); - } - } - - last_time_ms = time_ms; -}; +#include "32blit.hpp" +uint16_t width = 160; +uint16_t height = 120; +uint32_t prev_buttons = blit::buttons; +uint32_t updates = 0; -particle* generate_basic_rain() { - return new particle( - vec2((std::rand() % 120) + 100, 0), - vec2(0, 100) - ); +void init(void) { + blit::set_screen_mode(blit::lores); } -generator basic_rain_generator(250, 4000, generate_basic_rain); - -void render_basic_rain() { - for (auto p : basic_rain_generator.particles) { - particle *sp = static_cast(p); - if (sp->pos.y >= 239) { - sp->pos.y = 239; - } - fb.pen(rgba(128, 128, 255)); - fb.pixel(sp->pos); - } +void update(uint32_t time) { + updates++; } -uint32_t prev_buttons = blit::buttons; -void render(uint32_t time_ms) { +void render(uint32_t time) { + static uint32_t renders = 0; -uint16_t width; -uint16_t height; - if ((blit::buttons ^ prev_buttons) & blit::button::A) { - blit::set_screen_mode(blit::lores); - width = 160; - height = 120; + if (blit::buttons) { + blit::fb.pen(blit::rgba(127, 127, 127)); + blit::fb.clear(); + } else { + blit::fb.pen(blit::rgba(0, 0, 0)); + blit::fb.clear(); + if (renders&1) { + blit::fb.pen(blit::rgba(255, 255, 255)); + blit::fb.rectangle(blit::rect(70, 50, 20, 20)); + } } - else if ((blit::buttons ^ prev_buttons) & blit::button::B) { - blit::set_screen_mode(blit::hires); - width = 320; - height = 240; - } - prev_buttons = blit::buttons; - - fb.pen(rgba(0, 0, 0, 255)); - fb.clear(); - - //render_smoke(); - - uint32_t ms_start = now(); - //spark(time_ms); - //smoke(time_ms); - //rain(time_ms); - render_basic_rain(); - uint32_t ms_end = now(); - - // draw grid - fb.alpha = 255; - fb.pen(rgba(255, 255, 255)); - fb.rectangle(rect(0, 0, 320, 14)); - fb.pen(rgba(0, 0, 0)); - fb.text("Rain demo", &minimal_font[0][0], point(5, 4)); - - /* fb.pen(rgba(255, 255, 255)); - fb.text("Smoke:", &minimal_font[0][0], point(10, 20)); - fb.text("Sparks:", &minimal_font[0][0], point(120, 20)); - fb.text("Rain:", &minimal_font[0][0], point(220, 20)); */ - - // draw FPS meter - /*fb.alpha = 255; - fb.pen(rgba(0, 0, 0)); - fb.rectangle(rect(1, 240 - 10, 12, 9)); - fb.pen(rgba(255, 255, 255, 200)); - std::string fms = std::to_string(ms_end - ms_start); - fb.text(fms, &minimal_font[0][0], rect(3, 240 - 9, 10, 16)); - - int block_size = 4; - for (int i = 0; i < (ms_end - ms_start); i++) { - fb.pen(rgba(i * 5, 255 - (i * 5), 0)); - fb.rectangle(rect(i * (block_size + 1) + 1 + 13, fb.bounds.h - block_size - 1, block_size, block_size)); - }*/ - - fb.watermark(); -} - -void update(uint32_t time_ms) { -// smoke_generator.update(time_ms); - basic_rain_generator.update(time_ms); - - if (pressed(button::DPAD_LEFT)) { - g.rotate(0.1f); - } + renders++; } \ No newline at end of file From 8a2fe51f108e87e441994b0d92e5783d2c562822 Mon Sep 17 00:00:00 2001 From: lowfatcode Date: Fri, 31 Jan 2020 15:13:32 +0000 Subject: [PATCH 10/14] Whoops --- 32blit-stm32/Src/main.c | 2 +- examples/particle/particle.cpp | 306 ++++++++++++++++++++++++++++++--- 2 files changed, 284 insertions(+), 24 deletions(-) diff --git a/32blit-stm32/Src/main.c b/32blit-stm32/Src/main.c index 6988e4caf..7b17e65e7 100644 --- a/32blit-stm32/Src/main.c +++ b/32blit-stm32/Src/main.c @@ -237,7 +237,7 @@ void SystemClock_Config(void) PeriphClkInitStruct.PLL3.PLL3N = 129; PeriphClkInitStruct.PLL3.PLL3P = 2; PeriphClkInitStruct.PLL3.PLL3Q = 2; - PeriphClkInitStruct.PLL3.PLL3R = 45; + PeriphClkInitStruct.PLL3.PLL3R = 53; PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_1; PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE; PeriphClkInitStruct.PLL3.PLL3FRACN = 0; diff --git a/examples/particle/particle.cpp b/examples/particle/particle.cpp index 342b62555..19e696d42 100644 --- a/examples/particle/particle.cpp +++ b/examples/particle/particle.cpp @@ -1,35 +1,295 @@ -// Tearing test +#include +#include +#include +#include -#include "32blit.hpp" +#include "particle.hpp" + +using namespace blit; -uint16_t width = 160; -uint16_t height = 120; -uint32_t prev_buttons = blit::buttons; -uint32_t updates = 0; -void init(void) { - blit::set_screen_mode(blit::lores); +/* setup */ +void init() { + blit::set_screen_mode(screen_mode::hires); } -void update(uint32_t time) { - updates++; +struct test_particle { + vec2 pos; + vec2 vel; + int age; + bool generated = false; +}; + + +struct smoke_particle : particle { + float age_boost; + + smoke_particle(vec2 pos, vec2 vel, float age_boost) : particle(pos, vel), age_boost(age_boost) {}; +}; + +particle* generate_smoke() { + return new smoke_particle( + vec2((rand() % 20) - 10, (rand() % 20) - 10), + vec2(((rand() % 40) - 20) / 2, (rand() % 20) - 60), + (rand() % 3000) / 3000.0f + ); +} + +generator smoke_generator(150, 4000, generate_smoke); + +void render_smoke() { + for (auto p : smoke_generator.particles) { + smoke_particle *sp = static_cast(p); + float age = sp->age + sp->age_boost; + int alpha = (255 - (age * 75.0f)) / 8.0f; + int radius = (age * 150.0f) / 16.0f; + fb.pen(rgba(255, 255, 255, alpha)); + fb.circle(p->pos + point(50, 240), radius); + } } -void render(uint32_t time) { - static uint32_t renders = 0; +void smoke_generate(test_particle &p) { + p.pos = vec2((rand() % 20) - 10, (rand() % 20) - 10); + p.vel = vec2(((rand() % 40) - 20) / 2, (rand() % 20) - 60); + p.age = rand() % 200; + p.generated = true; +}; + +void smoke(uint32_t time_ms) { + static test_particle s[150]; + static int generate_index = 0; + static uint32_t last_time_ms = time_ms; + + int elapsed_ms = time_ms - last_time_ms; + float td = (elapsed_ms) / 1000.0f; + + smoke_generate(s[generate_index++]); + if (generate_index >= 150) + generate_index = 0; + + float w = sin(time_ms / 1000.0f) * 0.05f; + + for (auto &p : s) { + if (p.generated) { + p.pos += p.vel * td; + p.vel += vec2(w, 0); + p.age++; + + int alpha = (255 - (p.age / 2)) / 8.0f; + int radius = (p.age) / 16.0f; + fb.pen(rgba(255, 255, 255, alpha)); + fb.circle(p.pos + point(50, 240), radius); + } + } + + + last_time_ms = time_ms; +}; + + +void spark_generate(test_particle &p) { + p.pos = vec2((rand() % 10) - 5, -100); + p.vel = vec2(((rand() % 40) - 20), (rand() % 80) - 70); + p.age = 0;// rand() % 255; + p.generated = true; +}; + +void spark(uint32_t time_ms) { + static test_particle s[500]; + static int generate_index = 0; + static uint32_t last_time_ms = time_ms; + + int elapsed_ms = time_ms - last_time_ms; + float td = (elapsed_ms) / 1000.0f; + + spark_generate(s[generate_index++]); + if (generate_index >= 500) + generate_index = 0; + + float w = sin(time_ms / 1000.0f) * 0.05f; + + vec2 gravity = vec2(0, 9.8 * 2) * td; + + for (auto &p : s) { + if (p.generated) { + p.vel += gravity; + p.pos += p.vel * td; + if (p.pos.y > 0) + p.vel.y *= -0.7f; + p.age++; + + int a = p.age / 2; + int r = 255 - (p.age / 2); + int g = 255 - (a * 2); + g = g < 0 ? 0 : g; + int b = 255 - (a * 4); + b = b < 0 ? 0 : b; + + int bloom = (255 - a) / 64; + fb.pen(rgba(r, g, b, 16)); + fb.circle(p.pos + point(160, 240), bloom); + fb.pen(rgba(r, g, b, 16)); + fb.circle(p.pos + point(160, 240), bloom / 2); + + fb.pen(rgba(r, g, b)); + fb.pixel(p.pos + point(160, 240)); - if (blit::buttons) { - blit::fb.pen(blit::rgba(127, 127, 127)); - blit::fb.clear(); - } else { - blit::fb.pen(blit::rgba(0, 0, 0)); - blit::fb.clear(); - if (renders&1) { - blit::fb.pen(blit::rgba(255, 255, 255)); - blit::fb.rectangle(blit::rect(70, 50, 20, 20)); - } } - renders++; + } + + last_time_ms = time_ms; +}; + + +void rain_generate(test_particle &p) { + p.pos = vec2((rand() % 80) - 40, (rand() % 10) - 250); + p.vel = vec2(0, 140); + p.age = 0;// rand() % 255; + p.generated = true; +}; + +vec2 g = vec2(0, 9.8 * 5); + +void rain(uint32_t time_ms) { + static test_particle s[200]; + static int generate_index = 0; + static uint32_t last_time_ms = time_ms; + + int elapsed_ms = time_ms - last_time_ms; + float td = (elapsed_ms) / 1000.0f; + + rain_generate(s[generate_index++]); + if (generate_index >= 200) + generate_index = 0; + + float w = sin(time_ms / 1000.0f) * 0.05f; + + vec2 gravity = g * td; + + for (auto &p : s) { + if (p.generated) { + p.vel += gravity; + p.pos += p.vel * td; + + int floor = -3; + if (p.pos.x > 20 && p.pos.x < 46) + floor = -33; + + if (p.pos.y >= floor) { + p.pos.y = floor; + float bounce = ((rand() % 10)) / 80.0f; + p.vel.y *= -bounce; + p.vel.x = ((rand() % 30) - 15); + } + p.age++; + + int a = p.age / 2; + int r = 150 - (a / 2); + int g = 150 - (a / 2); + int b = 255;// -(a * 4); + + if(p.vel.length() > 20) { + fb.pen(rgba(r, g, b, 100)); + fb.pixel(p.pos + point(270, 239)); + fb.pen(rgba(r, g, b, 160)); + fb.pixel(p.pos + point(270, 241)); + } + fb.pen(rgba(r, g, b, 180)); + fb.pixel(p.pos + point(270, 242)); + } + } + + last_time_ms = time_ms; +}; + + + +particle* generate_basic_rain() { + return new particle( + vec2((std::rand() % 120) + 100, 0), + vec2(0, 100) + ); +} + +generator basic_rain_generator(250, 4000, generate_basic_rain); + +void render_basic_rain() { + for (auto p : basic_rain_generator.particles) { + particle *sp = static_cast(p); + if (sp->pos.y >= 239) { + sp->pos.y = 239; + } + fb.pen(rgba(128, 128, 255)); + fb.pixel(sp->pos); + } +} + +uint32_t prev_buttons = blit::buttons; + +void render(uint32_t time_ms) { + +uint16_t width; +uint16_t height; + if ((blit::buttons ^ prev_buttons) & blit::button::A) { + blit::set_screen_mode(blit::lores); + width = 160; + height = 120; + } + else if ((blit::buttons ^ prev_buttons) & blit::button::B) { + blit::set_screen_mode(blit::hires); + width = 320; + height = 240; + } + prev_buttons = blit::buttons; + + fb.pen(rgba(0, 0, 0, 255)); + fb.clear(); + + //render_smoke(); + + uint32_t ms_start = now(); + spark(time_ms); + smoke(time_ms); + rain(time_ms); + //render_basic_rain(); + uint32_t ms_end = now(); + + // draw grid + fb.alpha = 255; + fb.pen(rgba(255, 255, 255)); + fb.rectangle(rect(0, 0, 320, 14)); + fb.pen(rgba(0, 0, 0)); + fb.text("Rain demo", &minimal_font[0][0], point(5, 4)); + + /* fb.pen(rgba(255, 255, 255)); + fb.text("Smoke:", &minimal_font[0][0], point(10, 20)); + fb.text("Sparks:", &minimal_font[0][0], point(120, 20)); + fb.text("Rain:", &minimal_font[0][0], point(220, 20)); */ + + // draw FPS meter + /*fb.alpha = 255; + fb.pen(rgba(0, 0, 0)); + fb.rectangle(rect(1, 240 - 10, 12, 9)); + fb.pen(rgba(255, 255, 255, 200)); + std::string fms = std::to_string(ms_end - ms_start); + fb.text(fms, &minimal_font[0][0], rect(3, 240 - 9, 10, 16)); + + int block_size = 4; + for (int i = 0; i < (ms_end - ms_start); i++) { + fb.pen(rgba(i * 5, 255 - (i * 5), 0)); + fb.rectangle(rect(i * (block_size + 1) + 1 + 13, fb.bounds.h - block_size - 1, block_size, block_size)); + }*/ + + fb.watermark(); +} + +void update(uint32_t time_ms) { +// smoke_generator.update(time_ms); + basic_rain_generator.update(time_ms); + + if (pressed(button::DPAD_LEFT)) { + g.rotate(0.1f); + } } \ No newline at end of file From f826341dbd4b0e2f4c26cd20452ed0559153e2d0 Mon Sep 17 00:00:00 2001 From: lowfatcode Date: Fri, 31 Jan 2020 15:14:33 +0000 Subject: [PATCH 11/14] Missing declaration --- 32blit/graphics/blend.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/32blit/graphics/blend.hpp b/32blit/graphics/blend.hpp index 19a20a2e2..5bed20dbc 100644 --- a/32blit/graphics/blend.hpp +++ b/32blit/graphics/blend.hpp @@ -21,6 +21,7 @@ namespace blit { extern void P_P(uint8_t *pen, surface *dest, uint32_t offset, uint16_t count); extern void P_P(surface *src, int32_t src_offset, surface *dest, int32_t dest_offset, uint16_t count, int16_t src_step); extern void P_RGB(surface *src, int32_t src_offset, surface *dest, int32_t dest_offset, uint16_t count, int16_t src_step); + extern void P_RGBA(surface *src, int32_t src_offset, surface *dest, int32_t dest_offset, uint16_t count, int16_t src_step); extern void P_RGB565(surface *src, int32_t src_offset, surface *dest, int32_t dest_offset, uint16_t count, int16_t src_step); } \ No newline at end of file From c58e250e12c87f1299f6d39f75c3bf8d839602b0 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 31 Jan 2020 15:25:15 +0000 Subject: [PATCH 12/14] Drop old syntax, rename m to mask --- examples/raycaster/raycaster.cpp | 54 +++++++++++++++----------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/examples/raycaster/raycaster.cpp b/examples/raycaster/raycaster.cpp index 69aaa8e89..536a31378 100644 --- a/examples/raycaster/raycaster.cpp +++ b/examples/raycaster/raycaster.cpp @@ -11,8 +11,7 @@ using namespace blit; const uint16_t screen_width = 160; const uint16_t screen_height = 120; -uint8_t __ss[160 * 160] __SECTION__(".ss"); -uint8_t __m[160 * 120] __SECTION__(".m"); +uint8_t __m[160 * 120]; float z_buffer[SCREEN_WIDTH]; float lut_camera_displacement[SCREEN_WIDTH]; @@ -24,10 +23,7 @@ const int num_stars = 100; std::vector stars(num_stars); /* create surfaces */ -//surface ss((uint8_t *)__ss, size(160, 160), pixel_format::P); -surface m((uint8_t *)__m, pixel_format::M, size(screen_width, screen_height)); - -//spritesheet my_sprites(ss, 8, 8); +surface mask((uint8_t *)__m, pixel_format::M, size(screen_width, screen_height)); player player1{ vec2(0,0), vec2(0,0), vec2(0,0), 0 }; @@ -315,9 +311,9 @@ void render(uint32_t time) { uint32_t ms_start = now(); // clear the mask - m.alpha = 255; - m.pen(rgba(0)); - m.clear(); + mask.alpha = 255; + mask.pen(rgba(0)); + mask.clear(); // clear the canvas fb.alpha = 255; @@ -348,9 +344,9 @@ void render(uint32_t time) { fb.pen(rgba(10, 36, 24)); fb.mask = nullptr; - for (int y = 0; y < m.bounds.h; y++) { - for (int x = 0; x < m.bounds.w; x++) { - uint8_t v = *m.ptr(x, y); + for (int y = 0; y < mask.bounds.h; y++) { + for (int x = 0; x < mask.bounds.w; x++) { + uint8_t v = *mask.ptr(x, y); fb.alpha = v; fb.pixel(point(x, y)); } @@ -615,8 +611,8 @@ void render_world(uint32_t time) { //printf("render_world: updating z_buffer\n"); z_buffer[column] = perpendicular_wall_distance; - //m.pen(int(alpha)); - m.pen(200); + //mask.pen(int(alpha)); + mask.pen(200); float line_distance = abs(perpendicular_wall_distance - last_wall_distance); @@ -626,23 +622,23 @@ void render_world(uint32_t time) { for (int c = column - width; c < column + width; c++) { int alpha = (abs(column - c) * 160) / width; - m.pen(160 - alpha); - m.line(point(c, start_y), point(c, end_y)); + mask.pen(160 - alpha); + mask.line(point(c, start_y), point(c, end_y)); }; - /*m.rectangle(rect( + /*mask.rectangle(rect( point(column - width, start_y), point(column + width, end_y) ));*/ - //m.line(point(column-1, start_y), point(column-1, end_y)); - //m.line(point(column, start_y), point(column, end_y)); - //m.line(point(column+1, start_y), point(column+1, end_y)); + //mask.line(point(column-1, start_y), point(column-1, end_y)); + //mask.line(point(column, start_y), point(column, end_y)); + //mask.line(point(column+1, start_y), point(column+1, end_y)); } else { for (int r = end_y - width; r < end_y + width; r++) { int alpha = (abs(end_y - r) * 160) / width; - m.pen(160 - alpha); - m.pixel(point(column, r)); - /*m.rectangle(rect( + mask.pen(160 - alpha); + mask.pixel(point(column, r)); + /*mask.rectangle(rect( point(column, end_y - width - width + 2), point(column + 1, end_y + 2) ));*/ @@ -692,8 +688,8 @@ void render_world(uint32_t time) { fb.line(point(column, start_y), point(column, end_y)); - /*m.pen(rgba(255)); - m.line(point(column, start_y), point(column, end_y)); + /*mask.pen(rgba(255)); + mask.line(point(column, start_y), point(column, end_y)); */ @@ -894,7 +890,7 @@ void update_player_camera_plane(void) { } void edges() { - uint8_t *p = (uint8_t *)m.data + 160; + uint8_t *p = (uint8_t *)mask.data + 160; for (uint16_t y = 1; y < 119; y++) { p++; @@ -908,7 +904,7 @@ void edges() { p++; } - p = (uint8_t *)m.data + (120 * 160) - 1 - 160; + p = (uint8_t *)mask.data + (120 * 160) - 1 - 160; for (uint16_t y = 1; y < 119; y++) { p--; @@ -927,7 +923,7 @@ void blur(uint8_t passes) { uint8_t last; for (uint8_t pass = 0; pass < passes; pass++) { - uint8_t *p = (uint8_t *)m.data; + uint8_t *p = (uint8_t *)mask.data; for (uint16_t y = 0; y < 120; y++) { last = *p; p++; @@ -945,7 +941,7 @@ void blur(uint8_t passes) { // vertical for (uint8_t pass = 0; pass < passes; pass++) { for (uint16_t x = 0; x < 160; x++) { - uint8_t *p = (uint8_t *)m.data + x; + uint8_t *p = (uint8_t *)mask.data + x; last = *p; p += 160; From e4be893aceb7c6c96107da353ea5b04fb20f36e6 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 31 Jan 2020 15:59:15 +0000 Subject: [PATCH 13/14] Optimise input handling --- 32blit-stm32/Src/32blit.c | 152 ++++++++++++++++++-------------------- 32blit-stm32/Src/adc.c | 4 +- 2 files changed, 73 insertions(+), 83 deletions(-) diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c index 8eacfa15e..3f48f3463 100644 --- a/32blit-stm32/Src/32blit.c +++ b/32blit-stm32/Src/32blit.c @@ -116,16 +116,12 @@ uint32_t blit_update_dac(FIL *audio_file) { } void blit_tick() { - - if(needs_render) { + if(needs_render) { blit::render(blit::now()); - - // debug cycle count for flip -// blit::fb.pen(rgba(255, 255, 255)); - // blit::fb.text(std::to_string(flip_cycle_count), &minimal_font[0][0], point(10, 20)); + blit::fb.pen(rgba(255, 255, 255)); + blit::fb.text(std::to_string(flip_cycle_count), &minimal_font[0][0], point(0, 0)); HAL_LTDC_ProgramLineEvent(&hltdc, 252); - needs_render = false; } @@ -421,7 +417,7 @@ void blit_flip() { } } - flip_cycle_count = DWT->CYCCNT - scc; + //flip_cycle_count = DWT->CYCCNT - scc; SCB_CleanInvalidateDCache_by_Addr((uint32_t *)&__ltdc_start, 320 * 240 * 2); } @@ -471,59 +467,8 @@ void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc){ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if(hadc->Instance == ADC1) { SCB_InvalidateDCache_by_Addr((uint32_t *) &adc1data[ADC_BUFFER_SIZE / 2], ADC_BUFFER_SIZE / 2); - - int joystick_x = (adc1data[0] >> 1) - 16384; - joystick_x = std::max(-8192, std::min(8192, joystick_x)); - if(joystick_x < -1024) { - joystick_x += 1024; - } - else if(joystick_x > 1024) { - joystick_x -= 1024; - } else { - joystick_x = 0; - } - blit::joystick.x = joystick_x / 7168.0f; - - int joystick_y = (adc1data[1] >> 1) - 16384; - joystick_y = std::max(-8192, std::min(8192, joystick_y)); - if(joystick_y < -1024) { - joystick_y += 1024; - } - else if(joystick_y > 1024) { - joystick_y -= 1024; - } else { - joystick_y = 0; - } - blit::joystick.y = -joystick_y / 7168.0f; - } else if (hadc->Instance == ADC3) { SCB_InvalidateDCache_by_Addr((uint32_t *) &adc3data[ADC_BUFFER_SIZE / 2], ADC_BUFFER_SIZE / 2); - - int hack_left = (adc3data[0] >> 1) - 16384; - hack_left = std::max(-8192, std::min(8192, hack_left)); - if(hack_left < -1024) { - hack_left += 1024; - } - else if(hack_left > 1024) { - hack_left -= 1024; - } else { - hack_left = 0; - } - blit::hack_left = hack_left / 7168.0f; - - int hack_right = (adc3data[1] >> 1) - 16384; - hack_right = std::max(-8192, std::min(8192, hack_right)); - if(hack_right < -1024) { - hack_right += 1024; - } - else if(hack_right > 1024) { - hack_right -= 1024; - } else { - hack_right = 0; - } - blit::hack_right = -hack_right / 7168.0f; - - blit::battery = 6.6f * adc3data[2] / 65535.0f; } } @@ -533,6 +478,10 @@ uint8_t tilt_sample_offset = 0; int16_t acceleration_data_buffer[3 * ACCEL_OVER_SAMPLE] = {0}; void blit_process_input() { + static uint32_t last_battery_update = 0; + static uint32_t last_tilt_update = 0; + + uint32_t scc = DWT->CYCCNT; static uint32_t blit_last_buttons = 0; // read x axis of joystick bool joystick_button = false; @@ -551,40 +500,81 @@ void blit_process_input() { (!HAL_GPIO_ReadPin(BUTTON_MENU_GPIO_Port, BUTTON_MENU_Pin) ? blit::MENU : 0) | (!HAL_GPIO_ReadPin(JOYSTICK_BUTTON_GPIO_Port, JOYSTICK_BUTTON_Pin) ? blit::JOYSTICK : 0); - // Read accelerometer - msa301_get_accel(&hi2c4, &acceleration_data_buffer[tilt_sample_offset * 3]); + // Process ADC readings + int joystick_x = (adc1data[0] >> 1) - 16384; + joystick_x = std::max(-8192, std::min(8192, joystick_x)); + if(joystick_x < -1024) { + joystick_x += 1024; + } + else if(joystick_x > 1024) { + joystick_x -= 1024; + } else { + joystick_x = 0; + } + blit::joystick.x = joystick_x / 7168.0f; - uint8_t status = bq24295_get_status(&hi2c4); - blit::battery_vbus_status = status >> 6; // 00 - Unknown, 01 - USB Host, 10 - Adapter port, 11 - OTG - blit::battery_charge_status = (status >> 4) & 0b11; // 00 - Not Charging, 01 - Pre-charge, 10 - Fast Charging, 11 - Charge Termination Done + int joystick_y = (adc1data[1] >> 1) - 16384; + joystick_y = std::max(-8192, std::min(8192, joystick_y)); + if(joystick_y < -1024) { + joystick_y += 1024; + } + else if(joystick_y > 1024) { + joystick_y -= 1024; + } else { + joystick_y = 0; + } + blit::joystick.y = -joystick_y / 7168.0f; - blit::battery_fault = bq24295_get_fault(&hi2c4); + blit::hack_left = (adc3data[0] >> 1) / 32768.0f; + blit::hack_right = (adc3data[1] >> 1) / 32768.0f; - tilt_sample_offset += 1; - if(tilt_sample_offset >= ACCEL_OVER_SAMPLE){ - tilt_sample_offset = 0; - } + blit::battery = 6.6f * adc3data[2] / 65535.0f; + + if(blit::now() - last_battery_update > 5000) { + uint8_t status = bq24295_get_status(&hi2c4); + blit::battery_vbus_status = status >> 6; // 00 - Unknown, 01 - USB Host, 10 - Adapter port, 11 - OTG + blit::battery_charge_status = (status >> 4) & 0b11; // 00 - Not Charging, 01 - Pre-charge, 10 - Fast Charging, 11 - Charge Termination Done - float tilt_x = 0, tilt_y = 0, tilt_z = 0; - for(int x = 0; x < ACCEL_OVER_SAMPLE; x++) { - int offset = x * 3; - tilt_x += acceleration_data_buffer[offset + 0]; - tilt_y += acceleration_data_buffer[offset + 1]; - tilt_z += acceleration_data_buffer[offset + 2]; + blit::battery_fault = bq24295_get_fault(&hi2c4); + + last_battery_update = blit::now(); } - blit::tilt = vec3( - -(tilt_x / ACCEL_OVER_SAMPLE), - -(tilt_y / ACCEL_OVER_SAMPLE), - -(tilt_z / ACCEL_OVER_SAMPLE) - ); - blit::tilt.normalize(); + if(blit::now() - last_tilt_update > 10) { + // Do tilt every 8th tick of this function + // TODO: Find a better way to handle this + // Read accelerometer + msa301_get_accel(&hi2c4, &acceleration_data_buffer[tilt_sample_offset * 3]); + + tilt_sample_offset += 1; + if(tilt_sample_offset >= ACCEL_OVER_SAMPLE){ + tilt_sample_offset = 0; + } + + float tilt_x = 0, tilt_y = 0, tilt_z = 0; + for(int x = 0; x < ACCEL_OVER_SAMPLE; x++) { + int offset = x * 3; + tilt_x += acceleration_data_buffer[offset + 0]; + tilt_y += acceleration_data_buffer[offset + 1]; + tilt_z += acceleration_data_buffer[offset + 2]; + } + + blit::tilt = vec3( + -(tilt_x / ACCEL_OVER_SAMPLE), + -(tilt_y / ACCEL_OVER_SAMPLE), + -(tilt_z / ACCEL_OVER_SAMPLE) + ); + blit::tilt.normalize(); + + last_tilt_update = blit::now(); + } if(blit::buttons & blit::MENU && !(blit_last_buttons & blit::MENU)) { blit_menu(); } blit_last_buttons = blit::buttons; + flip_cycle_count = DWT->CYCCNT - scc; } char *get_fr_err_text(FRESULT err){ diff --git a/32blit-stm32/Src/adc.c b/32blit-stm32/Src/adc.c index a3d1482c5..10fd7e4a7 100644 --- a/32blit-stm32/Src/adc.c +++ b/32blit-stm32/Src/adc.c @@ -38,7 +38,7 @@ void MX_ADC1_Init(void) /** Common config */ hadc1.Instance = ADC1; - hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV8; + hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; hadc1.Init.Resolution = ADC_RESOLUTION_16B; hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; @@ -97,7 +97,7 @@ void MX_ADC3_Init(void) /** Common config */ hadc3.Instance = ADC3; - hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV8; + hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; hadc3.Init.Resolution = ADC_RESOLUTION_16B; hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE; hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV; From d3a4076caff18726e728c834c6d8d0ca67aa337d Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Fri, 31 Jan 2020 16:00:56 +0000 Subject: [PATCH 14/14] Remove cycle count --- 32blit-stm32/Src/32blit.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/32blit-stm32/Src/32blit.c b/32blit-stm32/Src/32blit.c index 3f48f3463..c00e69522 100644 --- a/32blit-stm32/Src/32blit.c +++ b/32blit-stm32/Src/32blit.c @@ -118,8 +118,6 @@ uint32_t blit_update_dac(FIL *audio_file) { void blit_tick() { if(needs_render) { blit::render(blit::now()); - blit::fb.pen(rgba(255, 255, 255)); - blit::fb.text(std::to_string(flip_cycle_count), &minimal_font[0][0], point(0, 0)); HAL_LTDC_ProgramLineEvent(&hltdc, 252); needs_render = false; @@ -574,7 +572,7 @@ void blit_process_input() { } blit_last_buttons = blit::buttons; - flip_cycle_count = DWT->CYCCNT - scc; + //flip_cycle_count = DWT->CYCCNT - scc; } char *get_fr_err_text(FRESULT err){