diff options
-rw-r--r-- | src/drivers/ao_vga.c | 54 | ||||
-rw-r--r-- | src/stm-vga/ao_demo.c | 71 | ||||
-rw-r--r-- | src/stm-vga/ao_pins.h | 2 | ||||
-rw-r--r-- | src/stm/ao_dma_stm.c | 11 |
4 files changed, 112 insertions, 26 deletions
diff --git a/src/drivers/ao_vga.c b/src/drivers/ao_vga.c index 24a645c7..eecf58f0 100644 --- a/src/drivers/ao_vga.c +++ b/src/drivers/ao_vga.c @@ -55,21 +55,21 @@ const struct ao_modeline vga_640x480x30 = { .htotal = 800, .vactive = 480, - .vsync_start = 481, - .vsync_end = 484, - .vtotal = 497 + .vsync_start = 490, + .vsync_end = 492, + .vtotal = 525, }; #define mode vga_640x480x60 #define WIDTH_BYTES (AO_VGA_WIDTH >> 3) -#define SCANOUT ((WIDTH_BYTES + 2) >> 1) +#define SCANOUT ((WIDTH_BYTES+2) >> 1) uint32_t ao_vga_fb[AO_VGA_STRIDE * AO_VGA_HEIGHT]; static uint32_t *scanline; -#define DMA_INDEX STM_DMA_INDEX(STM_DMA_CHANNEL_SPI2_TX) +#define DMA_INDEX STM_DMA_INDEX(STM_DMA_CHANNEL_SPI1_TX) static int line; static int vblank; @@ -85,7 +85,7 @@ static int vblank; (0 << STM_DMA_CCR_TCIE) | \ (en << STM_DMA_CCR_EN)) -int vblank_off = 13; +int vblank_off = 25; void stm_tim2_isr(void) { @@ -94,21 +94,24 @@ void stm_tim2_isr(void) /* Disable */ stm_dma.channel[DMA_INDEX].ccr = DMA_CCR(0); /* Reset DMA engine for the next scanline */ + stm_dma.channel[DMA_INDEX].cmar = scanline; stm_dma.channel[DMA_INDEX].cndtr = SCANOUT; /* Enable */ stm_dma.channel[DMA_INDEX].ccr = DMA_CCR(1); } stm_tim2.sr = ~(1 << STM_TIM234_SR_CC2IF); line = stm_tim3.cnt; - if (vblank_off <= line && line < (AO_VGA_HEIGHT << 1) + vblank_off + 12) { + if (vblank_off <= line && line < (AO_VGA_HEIGHT << 1) + vblank_off) { vblank = 0; - if ((line - vblank_off) & 1) + if (((line - vblank_off) & 1) == 0) scanline += AO_VGA_STRIDE; } else { - scanline = ao_vga_fb; - vblank = 1; + if (!vblank) { + stm_systick_isr(); + scanline = ao_vga_fb; + vblank = 1; + } } - stm_dma.channel[DMA_INDEX].cmar = scanline; ao_arch_release_interrupts(); } @@ -159,27 +162,29 @@ ao_vga_fb_init(void) ao_text("UL", ao_vga_fb, AO_VGA_STRIDE, - 0); + 1); ao_text("BL", ao_vga_fb + (240 - 7) * AO_VGA_STRIDE, AO_VGA_STRIDE, - 0); + 1); + + memset(ao_vga_fb + 120 * AO_VGA_STRIDE, '\0', WIDTH_BYTES); } void ao_vga_init(void) { - /* Initialize spi2 using PB15 for output */ + /* Initialize spi1 using PB5 for output */ stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); - stm_ospeedr_set(&stm_gpiob, 15, STM_OSPEEDR_40MHz); - stm_afr_set(&stm_gpiob, 15, STM_AFR_AF5); + stm_ospeedr_set(&stm_gpiob, 5, STM_OSPEEDR_40MHz); + stm_afr_set(&stm_gpiob, 5, STM_AFR_AF5); /* turn on SPI */ - stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_SPI2EN); + stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SPI1EN); - stm_spi2.cr1 = ((1 << STM_SPI_CR1_BIDIMODE) | /* Two wire mode */ + stm_spi1.cr1 = ((1 << STM_SPI_CR1_BIDIMODE) | /* Two wire mode */ (1 << STM_SPI_CR1_BIDIOE) | (0 << STM_SPI_CR1_CRCEN) | /* CRC disabled */ (0 << STM_SPI_CR1_CRCNEXT) | @@ -193,18 +198,18 @@ ao_vga_init(void) (1 << STM_SPI_CR1_MSTR) | (0 << STM_SPI_CR1_CPOL) | /* Format 0 */ (0 << STM_SPI_CR1_CPHA)); - stm_spi2.cr2 = ((0 << STM_SPI_CR2_TXEIE) | + stm_spi1.cr2 = ((0 << STM_SPI_CR2_TXEIE) | (0 << STM_SPI_CR2_RXNEIE) | (0 << STM_SPI_CR2_ERRIE) | (0 << STM_SPI_CR2_SSOE) | (1 << STM_SPI_CR2_TXDMAEN) | (0 << STM_SPI_CR2_RXDMAEN)); - (void) stm_spi2.dr; - (void) stm_spi2.sr; + (void) stm_spi1.dr; + (void) stm_spi1.sr; - /* Grab the DMA channel for SPI2 MOSI */ - stm_dma.channel[DMA_INDEX].cpar = &stm_spi2.dr; + /* Grab the DMA channel for SPI1 MOSI */ + stm_dma.channel[DMA_INDEX].cpar = &stm_spi1.dr; stm_dma.channel[DMA_INDEX].cmar = ao_vga_fb; /* hclock on timer 2 */ @@ -225,7 +230,7 @@ ao_vga_init(void) /* Channel 2 trigger scanout */ /* wait for the time to start scanout */ - stm_tim2.ccr2 = 90; + stm_tim2.ccr2 = mode.htotal - mode.hsync_end; stm_tim2.ccmr1 = ((0 << STM_TIM234_CCMR1_OC2CE) | (STM_TIM234_CCMR1_OC2M_SET_HIGH_ON_MATCH << STM_TIM234_CCMR1_OC2M) | @@ -342,7 +347,6 @@ ao_vga_init(void) stm_ospeedr_set(&stm_gpiob, 4, STM_OSPEEDR_40MHz); stm_afr_set(&stm_gpiob, 4, STM_AFR_AF2); - /* Enable the scanline interrupt */ stm_nvic_set_priority(STM_ISR_TIM2_POS, 0); stm_nvic_set_enable(STM_ISR_TIM2_POS); diff --git a/src/stm-vga/ao_demo.c b/src/stm-vga/ao_demo.c index 582e4156..3b582cc2 100644 --- a/src/stm-vga/ao_demo.c +++ b/src/stm-vga/ao_demo.c @@ -24,6 +24,67 @@ #include <ao_boot.h> #include <ao_vga.h> +struct ao_task ball_task; + +#define BALL_WIDTH 5 +#define BALL_HEIGHT 5 + +static int ball_x; +static int ball_y; +static int ball_dx, ball_dy; + +uint8_t ball_enable; + +void +ao_ball(void) +{ + ball_dx = 1; + ball_dy = 1; + ball_x = 0; + ball_y = 0; + for (;;) { + while (!ball_enable) + ao_sleep(&ball_enable); + for (;;) { + ao_solid(AO_ALLONES, + AO_ALLONES, + ao_vga_fb + ball_y * AO_VGA_STRIDE, + AO_VGA_STRIDE, + ball_x, + BALL_WIDTH, + BALL_HEIGHT); + ao_delay(AO_MS_TO_TICKS(10)); + ao_solid(AO_ALLONES, + AO_ALLONES, + ao_vga_fb + ball_y * AO_VGA_STRIDE, + AO_VGA_STRIDE, + ball_x, + BALL_WIDTH, + BALL_HEIGHT); + if (!ball_enable) + break; + ball_x += ball_dx; + ball_y += ball_dy; + if (ball_x + BALL_WIDTH > AO_VGA_WIDTH) { + ball_x = AO_VGA_WIDTH - BALL_WIDTH; + ball_dx = -ball_dx; + } + if (ball_x < 0) { + ball_x = -ball_x; + ball_dx = -ball_dx; + } + if (ball_y + BALL_HEIGHT > AO_VGA_HEIGHT) { + ball_y = AO_VGA_HEIGHT - BALL_HEIGHT; + ball_dy = -ball_dy; + } + if (ball_y < 0) { + ball_y = -ball_y; + ball_dy = -ball_dy; + } + } + } +} + static void ao_video_toggle(void) { @@ -31,8 +92,17 @@ ao_video_toggle(void) ao_vga_enable(ao_cmd_lex_i); } +static void +ao_ball_toggle(void) +{ + ao_cmd_decimal(); + ball_enable = ao_cmd_lex_i; + ao_wakeup(&ball_enable); +} + __code struct ao_cmds ao_demo_cmds[] = { { ao_video_toggle, "V\0Toggle video" }, + { ao_ball_toggle, "B\0Toggle ball" }, { 0, NULL } }; @@ -52,6 +122,7 @@ main(void) ao_vga_init(); ao_usb_init(); + ao_add_task(&ball_task, ao_ball, "ball"); ao_cmd_register(&ao_demo_cmds[0]); ao_start_scheduler(); diff --git a/src/stm-vga/ao_pins.h b/src/stm-vga/ao_pins.h index 3526cb6c..0e5a1903 100644 --- a/src/stm-vga/ao_pins.h +++ b/src/stm-vga/ao_pins.h @@ -69,7 +69,7 @@ #define HAS_BEEP 0 #define PACKET_HAS_SLAVE 0 -#define STM_DMA1_5_STOLEN 1 +#define STM_DMA1_3_STOLEN 1 #define AO_BOOT_CHAIN 1 diff --git a/src/stm/ao_dma_stm.c b/src/stm/ao_dma_stm.c index 0c86b49a..a24c6d3a 100644 --- a/src/stm/ao_dma_stm.c +++ b/src/stm/ao_dma_stm.c @@ -48,7 +48,11 @@ ao_dma_isr(uint8_t index) { void stm_dma1_channel1_isr(void) { ao_dma_isr(STM_DMA_INDEX(1)); } void stm_dma1_channel2_isr(void) { ao_dma_isr(STM_DMA_INDEX(2)); } +#ifdef STM_DMA1_3_STOLEN +#define LEAVE_DMA_ON +#else void stm_dma1_channel3_isr(void) { ao_dma_isr(STM_DMA_INDEX(3)); } +#endif void stm_dma1_channel4_isr(void) { ao_dma_isr(STM_DMA_INDEX(4)); } #ifdef STM_DMA1_5_STOLEN #define LEAVE_DMA_ON @@ -179,6 +183,13 @@ ao_dma_init(void) continue; } #endif +#if STM_DMA1_3_STOLEN + if (index == STM_DMA_INDEX(3)) { + ao_dma_allocated[index] = 1; + ao_dma_mutex[index] = 0xff; + continue; + } +#endif stm_nvic_set_enable(STM_ISR_DMA1_CHANNEL1_POS + index); stm_nvic_set_priority(STM_ISR_DMA1_CHANNEL1_POS + index, 4); ao_dma_allocated[index] = 0; |