]> code.bitgloo.com Git - clyne/stm-game.git/commitdiff
display optimization; sprites
authorClyne Sullivan <clyne@bitgloo.com>
Sun, 29 Nov 2020 13:04:13 +0000 (08:04 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Sun, 29 Nov 2020 13:04:13 +0000 (08:04 -0500)
STM32L011x4.ld
buttons.h
cfg/halconf.h
cfg/mcuconf.h
dogs.c
dogs.h
main.c

index c583d02dd69eb1fbe7ee326e9722a99bc4f297c6..5fec90f22d21fd8969f8c494f1233a33432156e6 100644 (file)
@@ -79,6 +79,7 @@ REGION_ALIAS("DATA_RAM_LMA", flash0);
 REGION_ALIAS("BSS_RAM", ram0);\r
 \r
 /* RAM region to be used for the default heap.*/\r
+/* tcsullivan: Set to ram1 so bss reports actual size used. */\r
 REGION_ALIAS("HEAP_RAM", ram1);\r
 \r
 /* Generic rules inclusion.*/\r
index bade3cfb6a4c06d68437747890d0765aa96b0c64..62fc364ed2092e34fe56941830789607ea63d577 100644 (file)
--- a/buttons.h
+++ b/buttons.h
 #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();
index 4d6ea7e8ac8efd989de932d1ea8d4a23f509c3b4..fe4c478846760424c15154769d93af70c8c0d321 100644 (file)
  * @brief   Enables the SERIAL subsystem.\r
  */\r
 #if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)\r
-#define HAL_USE_SERIAL                      TRUE\r
+#define HAL_USE_SERIAL                      FALSE\r
 #endif\r
 \r
 /**\r
  * @note    Disabling this option saves both code and data space.\r
  */\r
 #if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)\r
-#define ADC_USE_WAIT                        TRUE\r
+#define ADC_USE_WAIT                        FALSE\r
 #endif\r
 \r
 /**\r
  * @note    Disabling this option saves both code and data space.\r
  */\r
 #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)\r
-#define ADC_USE_MUTUAL_EXCLUSION            TRUE\r
+#define ADC_USE_MUTUAL_EXCLUSION            FALSE\r
 #endif\r
 \r
 /*===========================================================================*/\r
  * @note    Disabling this option saves both code and data space.\r
  */\r
 #if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)\r
-#define SPI_USE_WAIT                        TRUE\r
+#define SPI_USE_WAIT                        FALSE\r
 #endif\r
 \r
 /**\r
  * @note    Disabling this option saves both code and data space.\r
  */\r
 #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)\r
-#define SPI_USE_MUTUAL_EXCLUSION            TRUE\r
+#define SPI_USE_MUTUAL_EXCLUSION            FALSE\r
 #endif\r
 \r
 /**\r
index ccb4a6f370ddc15f056349f56d8de4e4bd93f8a4..f02fe109a7249e6f1623d398e53f39a79cecfa9a 100644 (file)
  * SERIAL driver system settings.\r
  */\r
 #define STM32_SERIAL_USE_USART2             FALSE\r
-#define STM32_SERIAL_USE_LPUART1            TRUE\r
+#define STM32_SERIAL_USE_LPUART1            FALSE\r
 \r
 /*\r
  * SPI driver system settings.\r
diff --git a/dogs.c b/dogs.c
index 9f754d6df5ad41b2b6c3ac794cb0df70d3b54a21..b401c3959b9bd4224ca3ddf77036153a1df70738 100644 (file)
--- a/dogs.c
+++ b/dogs.c
 #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;
+            }
+        }
+    }
+}
+
diff --git a/dogs.h b/dogs.h
index 2660bf19f1369ef84542398b2d8c995b70b66365..1ae24bb089b4205df12398fafc9584761dd62912 100644 (file)
--- a/dogs.h
+++ b/dogs.h
@@ -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_
 
diff --git a/main.c b/main.c
index 126c47e1cbf2a5ff851b650651b0206c005fdbe4..e7949a8c38e5b5ee4f97c64b48a89ffc7b782b4c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,67 +1,95 @@
-/**\r
- * main.c - Firmware entry point and main loop for game or testing.\r
- * Copyright (C) 2020  Clyne Sullivan\r
- *\r
- * This program is free software: you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation, either version 3 of the License, or\r
- * (at your option) any later version.\r
- * See the GNU General Public License for more details.\r
- */\r
-\r
-#include "buttons.h"\r
-#include "ch.h"\r
-#include "dogs.h"\r
-#include "hal.h"\r
-\r
-/*\r
- * Progress:\r
- *  - Serial through LPUART1 works (38400 baud, takes over swdio pins)\r
- *  - Display comm. over SPI, can clear screen\r
- *  - Can read buttons through PAL (through interrupts now)\r
- */\r
-\r
-THD_WORKING_AREA(waThread2, 96);\r
-THD_FUNCTION(Thread2, arg)\r
-{\r
-    (void)arg;\r
-\r
-    dogs_init();\r
-\r
-    while (1) {\r
-        chThdSleepMilliseconds(100);\r
-        dogs_buffer[0] = button_state;\r
-        dogs_buffer[1] = button_state;\r
-        dogs_buffer[2] = button_state;\r
-        dogs_buffer[3] = button_state;\r
-        dogs_flush();\r
-    }\r
-}\r
-\r
-THD_TABLE_BEGIN\r
-    THD_TABLE_THREAD(0, "game", waThread2, Thread2, NULL)\r
-THD_TABLE_END\r
-\r
-int main(void)\r
-{\r
-    halInit();\r
-    chSysInit();\r
-\r
-    buttons_init();\r
-\r
-    // Below code for serial -- note that it cuts off debugging, and MUST be used in a thread\r
-    //chThdSleepMilliseconds(2000);\r
-    //palSetPadMode(GPIOA, 13, PAL_MODE_ALTERNATE(6));\r
-    //palSetPadMode(GPIOA, 14, PAL_MODE_ALTERNATE(6));\r
-    //sdStart(&LPSD1, NULL);\r
-    //chnWrite(&LPSD1, (const uint8_t *)"Hello World!\r\n", 14);\r
-\r
-\r
-\r
-    /* This is now the idle thread loop, you may perform here a low priority\r
-       task but YOU MUST NEVER TRY TO SLEEP OR WAIT in this loop. Note that\r
-       this tasks runs at the lowest priority level so any instruction added\r
-       here will be executed after all other tasks have been started. */\r
-    while (1);\r
-}\r
-\r
+/**
+ * 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);
+}
+