diff options
-rw-r--r-- | STM32L011x4.ld | 1 | ||||
-rw-r--r-- | buttons.h | 9 | ||||
-rw-r--r-- | cfg/halconf.h | 10 | ||||
-rw-r--r-- | cfg/mcuconf.h | 2 | ||||
-rw-r--r-- | dogs.c | 71 | ||||
-rw-r--r-- | dogs.h | 3 | ||||
-rw-r--r-- | main.c | 162 |
7 files changed, 174 insertions, 84 deletions
diff --git a/STM32L011x4.ld b/STM32L011x4.ld index c583d02..5fec90f 100644 --- a/STM32L011x4.ld +++ b/STM32L011x4.ld @@ -79,6 +79,7 @@ REGION_ALIAS("DATA_RAM_LMA", flash0); REGION_ALIAS("BSS_RAM", ram0);
/* RAM region to be used for the default heap.*/
+/* tcsullivan: Set to ram1 so bss reports actual size used. */
REGION_ALIAS("HEAP_RAM", ram1);
/* Generic rules inclusion.*/
@@ -12,6 +12,15 @@ #ifndef BUTTONS_H_ #define BUTTONS_H_ +#define BUTTON_JOYUL (1 << 7) +#define BUTTON_JOYUR (1 << 6) +#define BUTTON_JOYDR (1 << 5) +#define BUTTON_JOYDL (1 << 4) +#define BUTTON_JOY (1 << 3) +#define BUTTON_1 (1 << 2) +#define BUTTON_2 (1 << 1) +#define BUTTON_3 (1 << 0) + extern unsigned char button_state; void buttons_init(); diff --git a/cfg/halconf.h b/cfg/halconf.h index 4d6ea7e..fe4c478 100644 --- a/cfg/halconf.h +++ b/cfg/halconf.h @@ -142,7 +142,7 @@ * @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
-#define HAL_USE_SERIAL TRUE
+#define HAL_USE_SERIAL FALSE
#endif
/**
@@ -230,7 +230,7 @@ * @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
-#define ADC_USE_WAIT TRUE
+#define ADC_USE_WAIT FALSE
#endif
/**
@@ -238,7 +238,7 @@ * @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
-#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#define ADC_USE_MUTUAL_EXCLUSION FALSE
#endif
/*===========================================================================*/
@@ -447,7 +447,7 @@ * @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
-#define SPI_USE_WAIT TRUE
+#define SPI_USE_WAIT FALSE
#endif
/**
@@ -463,7 +463,7 @@ * @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
-#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#define SPI_USE_MUTUAL_EXCLUSION FALSE
#endif
/**
diff --git a/cfg/mcuconf.h b/cfg/mcuconf.h index ccb4a6f..f02fe10 100644 --- a/cfg/mcuconf.h +++ b/cfg/mcuconf.h @@ -131,7 +131,7 @@ * SERIAL driver system settings.
*/
#define STM32_SERIAL_USE_USART2 FALSE
-#define STM32_SERIAL_USE_LPUART1 TRUE
+#define STM32_SERIAL_USE_LPUART1 FALSE
/*
* SPI driver system settings.
@@ -17,10 +17,16 @@ #define SET_CMD palClearPad(GPIOC, 15) #define CS_HIGH palSetPad(GPIOA, 4) #define CS_LOW palClearPad(GPIOA, 4) - unsigned char dogs_buffer[DISP_WIDTH * DISP_HEIGHT / 8]; +static volatile bool dogs_spi_done = false; + static void dogs_init_display(); +static void dogs_spi_callback(SPIDriver *spid) +{ + if (spiIsBufferComplete(spid)) + dogs_spi_done = true; +} void dogs_init() { @@ -35,27 +41,32 @@ void dogs_init() palSetPad(GPIOC, 14); palClearPad(GPIOC, 15); - static const SPIConfig ls_spicfg = { + static const SPIConfig spicfg = { false, - NULL, - SPI_CR1_BR_2 | SPI_CR1_BR_1, + dogs_spi_callback, + 0, // cr1 0 }; - spiStart(&SPID1, &ls_spicfg); + spiStart(&SPID1, &spicfg); dogs_init_display(); dogs_clear(); + dogs_flush(); } void dogs_write_data(unsigned char byte) { SET_DATA; - spiSend(&SPID1, 1, &byte); + dogs_spi_done = false; + spiStartSend(&SPID1, 1, &byte); + while (!dogs_spi_done); } void dogs_write_cmd(unsigned char byte) { SET_CMD; - spiSend(&SPID1, 1, &byte); + dogs_spi_done = false; + spiStartSend(&SPID1, 1, &byte); + while (!dogs_spi_done); } void dogs_set_column(unsigned int col) @@ -144,10 +155,17 @@ void dogs_init_display() void dogs_clear() { unsigned char *ptr = dogs_buffer; - for (unsigned int i = 0; i < sizeof(dogs_buffer); i++) { + unsigned int count = sizeof(dogs_buffer); + for (; count > 8; count -= 8) { + *ptr++ = 0; + *ptr++ = 0; + *ptr++ = 0; + *ptr++ = 0; + *ptr++ = 0; + *ptr++ = 0; + *ptr++ = 0; *ptr++ = 0; } - dogs_flush(); } void dogs_flush() @@ -157,9 +175,40 @@ void dogs_flush() for (int page = 0; page < 8; page++) { dogs_set_page(page); dogs_set_column(30); - for (int i = 0; i < 102; i++) - dogs_write_data(*ptr++); + + SET_DATA; + dogs_spi_done = false; + spiStartSend(&SPID1, 102, ptr); + ptr += 102; + while (!dogs_spi_done); } CS_HIGH; } +void draw_pixel(int x, int y, bool state) +{ + if (state) + dogs_buffer[y / 8 * DISP_WIDTH + x] |= (1 << (y % 8)); + else + dogs_buffer[y / 8 * DISP_WIDTH + x] &= ~(1 << (y % 8)); +} + +void draw_bitmap(int x, int y, const unsigned char *buffer) +{ + // Prepare source information + const unsigned char *src = buffer; + const int width = *src++; + const int height = *src++; + int sbit = 0; + + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + draw_pixel(x + i, y + j, *src & (1 << sbit)); + if (++sbit == 8) { + sbit = 0; + ++src; + } + } + } +} + @@ -21,5 +21,8 @@ void dogs_init(); void dogs_clear(); void dogs_flush(); +void draw_pixel(int x, int y, bool state); +void draw_bitmap(int x, int y, const unsigned char *buffer); + #endif // DOGS_H_ @@ -1,67 +1,95 @@ -/**
- * main.c - Firmware entry point and main loop for game or testing.
- * Copyright (C) 2020 Clyne Sullivan
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * See the GNU General Public License for more details.
- */
-
-#include "buttons.h"
-#include "ch.h"
-#include "dogs.h"
-#include "hal.h"
-
-/*
- * Progress:
- * - Serial through LPUART1 works (38400 baud, takes over swdio pins)
- * - Display comm. over SPI, can clear screen
- * - Can read buttons through PAL (through interrupts now)
- */
-
-THD_WORKING_AREA(waThread2, 96);
-THD_FUNCTION(Thread2, arg)
-{
- (void)arg;
-
- dogs_init();
-
- while (1) {
- chThdSleepMilliseconds(100);
- dogs_buffer[0] = button_state;
- dogs_buffer[1] = button_state;
- dogs_buffer[2] = button_state;
- dogs_buffer[3] = button_state;
- dogs_flush();
- }
-}
-
-THD_TABLE_BEGIN
- THD_TABLE_THREAD(0, "game", waThread2, Thread2, NULL)
-THD_TABLE_END
-
-int main(void)
-{
- halInit();
- chSysInit();
-
- buttons_init();
-
- // Below code for serial -- note that it cuts off debugging, and MUST be used in a thread
- //chThdSleepMilliseconds(2000);
- //palSetPadMode(GPIOA, 13, PAL_MODE_ALTERNATE(6));
- //palSetPadMode(GPIOA, 14, PAL_MODE_ALTERNATE(6));
- //sdStart(&LPSD1, NULL);
- //chnWrite(&LPSD1, (const uint8_t *)"Hello World!\r\n", 14);
-
-
-
- /* This is now the idle thread loop, you may perform here a low priority
- task but YOU MUST NEVER TRY TO SLEEP OR WAIT in this loop. Note that
- this tasks runs at the lowest priority level so any instruction added
- here will be executed after all other tasks have been started. */
- while (1);
-}
-
+/** + * main.c - Firmware entry point and main loop for game or testing. + * Copyright (C) 2020 Clyne Sullivan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * See the GNU General Public License for more details. + */ + +#include "buttons.h" +#include "ch.h" +#include "dogs.h" +#include "hal.h" + +/* + * Progress: + * - Serial through LPUART1 works (38400 baud, takes over swdio pins) + * - Display comm. over SPI, can clear screen + * - Can read buttons through PAL (through interrupts now) + */ + +THD_WORKING_AREA(waThread2, 96); +THD_FUNCTION(Thread2, arg) +{ + (void)arg; + + dogs_init(); + + const unsigned char testbitmap[] = { + 8, 8, + 0b00111100, + 0b01100110, + 0b01000010, + 0b01111110, + 0b01100110, + 0b01000010, + 0b11000000, + 0b11000000, + }; + + + int x = 0, y = 0; + while (1) { + chThdSleepMilliseconds(100); + + unsigned char b = button_state; + if ((b & (BUTTON_JOYUR | BUTTON_JOYUL)) == (BUTTON_JOYUR | BUTTON_JOYUL)) + y--; + else if ((b & (BUTTON_JOYUR | BUTTON_JOYDR)) == (BUTTON_JOYUR | BUTTON_JOYDR)) + x++; + else if ((b & (BUTTON_JOYDR | BUTTON_JOYDL)) == (BUTTON_JOYDR | BUTTON_JOYDL)) + y++; + else if ((b & (BUTTON_JOYDL | BUTTON_JOYUL)) == (BUTTON_JOYDL | BUTTON_JOYUL)) + x--; + + dogs_clear(); + draw_bitmap(x, y, testbitmap); + dogs_flush(); + } +} + +THD_TABLE_BEGIN + THD_TABLE_THREAD(0, "game", waThread2, Thread2, NULL) +THD_TABLE_END + +int main(void) +{ + halInit(); + chSysInit(); + + buttons_init(); + + // Below code for serial -- note that it cuts off debugging, and MUST be used in a thread + //chThdSleepMilliseconds(2000); + //palSetPadMode(GPIOA, 13, PAL_MODE_ALTERNATE(6)); + //palSetPadMode(GPIOA, 14, PAL_MODE_ALTERNATE(6)); + //sdStart(&LPSD1, NULL); + //chnWrite(&LPSD1, (const uint8_t *)"Hello World!\r\n", 14); + + + + /* This is now the idle thread loop, you may perform here a low priority + task but YOU MUST NEVER TRY TO SLEEP OR WAIT in this loop. Note that + this tasks runs at the lowest priority level so any instruction added + here will be executed after all other tasks have been started. */ + while (1); +} + +void HardFault_Handler() +{ + while (1); +} + |