aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--STM32L011x4.ld1
-rw-r--r--buttons.h9
-rw-r--r--cfg/halconf.h10
-rw-r--r--cfg/mcuconf.h2
-rw-r--r--dogs.c71
-rw-r--r--dogs.h3
-rw-r--r--main.c162
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.*/
diff --git a/buttons.h b/buttons.h
index bade3cf..62fc364 100644
--- a/buttons.h
+++ b/buttons.h
@@ -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.
diff --git a/dogs.c b/dogs.c
index 9f754d6..b401c39 100644
--- a/dogs.c
+++ b/dogs.c
@@ -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;
+ }
+ }
+ }
+}
+
diff --git a/dogs.h b/dogs.h
index 2660bf1..1ae24bb 100644
--- 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 126c47e..e7949a8 100644
--- a/main.c
+++ b/main.c
@@ -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);
+}
+