diff --git a/f103.pro b/f103-ledmatrix.pro
similarity index 97%
rename from f103.pro
rename to f103-ledmatrix.pro
index bdfeca4..00d38a8 100644
--- a/f103.pro
+++ b/f103-ledmatrix.pro
@@ -81,7 +81,8 @@ HEADERS += \
project/main.h \
project/utils/matcher.h \
project/utils/meanbuf.h \
- project/display.h
+ project/display.h \
+ project/matrixdsp.h
SOURCES += \
lib/cmsis/core_cm3.c \
@@ -138,7 +139,8 @@ SOURCES += \
project/utils/str_utils.c \
project/utils/matcher.c \
project/utils/meanbuf.c \
- project/display.c
+ project/display.c \
+ project/matrixdsp.c
DISTFILES += \
style.astylerc \
diff --git a/f103.pro.user b/f103.pro.user
deleted file mode 100644
index 60c5465..0000000
--- a/f103.pro.user
+++ /dev/null
@@ -1,299 +0,0 @@
-
-
-
-
-
- EnvironmentId
- {dfe3cb4a-0f3e-4da9-9c52-5d2c464adafb}
-
-
- ProjectExplorer.Project.ActiveTarget
- 0
-
-
- ProjectExplorer.Project.EditorSettings
-
- true
- false
- true
-
- Cpp
-
- CppGlobal
-
-
-
- QmlJS
-
- QmlJSGlobal
-
-
- 2
- UTF-8
- false
- 4
- true
- 80
- true
- true
- 1
- true
- false
- 0
- true
- 0
- 8
- true
- 1
- true
- true
- true
- true
-
-
-
- ProjectExplorer.Project.PluginSettings
-
-
-
- 1
-
-
-
-
- ProjectExplorer.Project.Target.0
-
- STLINK
- STLINK
- {15262c8f-05de-48ee-9452-3d289b21ba3e}
- 0
- -1
- 0
-
- /home/ondra/devel/f103
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- false
- -B -j 4
-
-
- 1
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- Debug
- Main
- Qt4ProjectManager.Qt4BuildConfiguration
- 2
- true
-
- 1
- 0
-
-
- false
- 1000
-
- true
-
- false
- false
- false
- false
- true
- 0.01
- 10
- true
- 1
- 25
-
- 1
- true
- false
- true
- valgrind
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
-
- 2
-
- flash
- /usr/bin/make
- %{buildDir}
- Run /usr/bin/make
- make flash
- ProjectExplorer.CustomExecutableRunConfiguration
- 3768
- false
- true
- false
- false
- true
-
-
- false
- 1000
-
- true
-
- false
- false
- false
- false
- true
- 0.01
- 10
- true
- 1
- 25
-
- 1
- true
- false
- true
- valgrind
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
-
-
- f103 (via GDB server or hardware debugger)
-
- BareMetal/home/ondra/devel/f103/f103.pro
-
- f103.pro
- 3768
- false
- true
- false
- false
- true
-
-
- false
- 1000
-
- true
-
- false
- false
- false
- false
- true
- 0.01
- 10
- true
- 1
- 25
-
- 1
- true
- false
- true
- valgrind
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
-
- 2
-
-
- /home/ondra/devel/f103/main.elf
- /home/ondra/devel/f103
- Run /home/ondra/devel/f103/main.elf
-
- ProjectExplorer.CustomExecutableRunConfiguration
- 3768
- false
- true
- false
- false
- true
-
- 3
-
-
-
- ProjectExplorer.Project.TargetCount
- 1
-
-
- ProjectExplorer.Project.Updater.FileVersion
- 18
-
-
- Version
- 18
-
-
diff --git a/project/hw_init.c b/project/hw_init.c
index 2e9b194..5a470a5 100644
--- a/project/hw_init.c
+++ b/project/hw_init.c
@@ -8,11 +8,13 @@
#include "utils/timebase.h"
#include "bus/event_queue.h"
+#include "com/debug.h"
// ---- Private prototypes --------
static void conf_gpio(void);
static void conf_usart(void);
+static void conf_spi(void);
static void conf_systick(void);
static void conf_subsystems(void);
static void conf_irq_prios(void);
@@ -27,6 +29,7 @@ void hw_init(void)
conf_gpio();
conf_usart();
conf_systick();
+ conf_spi();
conf_irq_prios();
conf_subsystems();
}
@@ -71,6 +74,7 @@ static void conf_subsystems(void)
static void conf_gpio(void)
{
GPIO_InitTypeDef gpio_cnf;
+ GPIO_StructInit(&gpio_cnf);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
@@ -96,6 +100,18 @@ static void conf_gpio(void)
// A0-sonar trig | UART2 - debug, UART1 - esp
gpio_cnf.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_9 | GPIO_Pin_10;
gpio_cnf.GPIO_Mode = GPIO_Mode_AF_PP;
+ gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
+ GPIO_Init(GPIOA, &gpio_cnf);
+
+ // SPI
+ gpio_cnf.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
+ gpio_cnf.GPIO_Mode = GPIO_Mode_AF_PP;
+ gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
+ GPIO_Init(GPIOA, &gpio_cnf);
+ // SPI NSS out
+ gpio_cnf.GPIO_Pin = GPIO_Pin_4;
+ gpio_cnf.GPIO_Mode = GPIO_Mode_Out_PP;
+ gpio_cnf.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &gpio_cnf);
}
@@ -115,6 +131,26 @@ static void conf_usart(void)
data_iface = usart_iface_init(USART1, 460800, 256, 256);
}
+/**
+ * @brief Configure SPI
+ */
+static void conf_spi(void)
+{
+ RCC_APB2PeriphClockCmd(RCC_APB2ENR_SPI1EN, ENABLE);
+
+ SPI_InitTypeDef spi_cnf;
+ SPI_StructInit(&spi_cnf);
+
+ spi_cnf.SPI_Direction = SPI_Direction_1Line_Tx;
+ spi_cnf.SPI_Mode = SPI_Mode_Master;
+ spi_cnf.SPI_NSS = SPI_NSS_Soft;
+ spi_cnf.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
+
+ SPI_Init(SPI1, &spi_cnf);
+
+ SPI_Cmd(SPI1, ENABLE);
+}
+
/**
* @brief Configure 1 kHz SysTick w/ interrupt
diff --git a/project/main.c b/project/main.c
index d2a0395..7dd8b8d 100644
--- a/project/main.c
+++ b/project/main.c
@@ -13,7 +13,10 @@
#include
#include
-void poll_subsystems(void)
+#include "matrixdsp.h"
+
+
+static void poll_subsystems(void)
{
// poll serial buffers (runs callback)
com_poll(debug_iface);
@@ -36,29 +39,69 @@ void poll_subsystems(void)
-void blinky(void* arg)
-{
- (void)arg;
- GPIOC->ODR ^= 1<<13;
-}
-
-
-
-
int main(void)
{
hw_init();
- display_init();
+// display_init();
- banner("*** STM32F103K8T6 RGB LED demo ***");
+ banner("*** LED MATRIX DEMO ***");
banner_info("(c) Ondrej Hruska, 2016");
banner_info("Katedra mereni K338, CVUT FEL");
-
- add_periodic_task(blinky, NULL, 500, false);
+ ms_time_t last;
+
+ mdsp_send_command_all(CMD_DECODE_MODE, 0x00);
+ mdsp_send_command_all(CMD_SCAN_LIMIT, 0x07);
+ mdsp_send_command_all(CMD_SHUTDOWN, 0x01);
+ mdsp_send_command_all(CMD_DISPLAY_TEST, 0x00);
+ mdsp_send_command_all(CMD_INTENSITY, 0x05);
+
+ mdsp_clear();
+
+ // ---
+
+ const uint16_t inva0[] = {
+ 0b00100000100,
+ 0b00010001000,
+ 0b00111111100,
+ 0b01101110110,
+ 0b11111111111,
+ 0b10111111101,
+ 0b10100000101,
+ 0b00011011000,
+ };
+
+ const uint16_t inva1[] = {
+ 0b00100000100,
+ 0b10010001001,
+ 0b10111111101,
+ 0b11101110111,
+ 0b11111111111,
+ 0b01111111110,
+ 0b00100000100,
+ 0b01000000010,
+ };
while (1) {
+ if (ms_loop_elapsed(&last, 500)) {
+ GPIOC->ODR ^= 1 << 13;
+ }
+
poll_subsystems();
+
+ for (int i = 0; i < 8; i++) {
+ uint32_t x = __RBIT(inva0[7-i]);
+ mdsp_set(i, x >> 21);
+ mdsp_set(8+i, (x >> 29) & 0b111);
+ }
+ delay_ms(500);
+
+ for (int i = 0; i < 8; i++) {
+ uint32_t x = __RBIT(inva1[7-i]);
+ mdsp_set(i, x >> 21);
+ mdsp_set(8+i, (x >> 29) & 0b111);
+ }
+ delay_ms(500);
}
}
diff --git a/project/matrixdsp.c b/project/matrixdsp.c
new file mode 100644
index 0000000..705e5a3
--- /dev/null
+++ b/project/matrixdsp.c
@@ -0,0 +1,87 @@
+#include
+#include
+
+#include "com/debug.h"
+
+#include "utils/timebase.h"
+
+static void send_byte(uint8_t b)
+{
+ MDSP_SPIx->DR = b;
+ while (!(MDSP_SPIx->SR & SPI_SR_TXE));
+}
+
+static void set_nss(bool nss)
+{
+ if (nss) {
+ MDSP_NSS_GPIO->BSRR = MDSP_NSS_PIN;
+ } else {
+ MDSP_NSS_GPIO->BRR = MDSP_NSS_PIN;
+ }
+}
+
+static void send_word(MDSP_Command cmd, uint8_t data)
+{
+ send_byte(cmd);
+ send_byte(data);
+}
+
+/**
+ * @brief Send a command to n-th chained driver
+ * @param idx Driver index (0, 1, 2 ...)
+ * @param cmd command to send
+ * @param data command argument
+ */
+void mdsp_send_command(uint8_t idx, MDSP_Command cmd, uint8_t data)
+{
+ dbg("Set %d: cmd 0x%02x, data 0x%02x", idx, cmd, data);
+
+ set_nss(false);
+ while (MDSP_SPIx->SR & SPI_SR_BSY);
+
+ for (uint8_t i = 0; i < MDSP_CHAIN_COUNT - idx - 1; i++) {
+ send_word(CMD_NOOP, 0);
+ }
+
+ send_word(cmd, data);
+
+ for (uint8_t i = 0; i < idx; i++) {
+ send_word(CMD_NOOP, 0);
+ }
+
+ while (MDSP_SPIx->SR & SPI_SR_BSY);
+ set_nss(false);
+ set_nss(true);
+}
+
+
+void mdsp_send_command_all(MDSP_Command cmd, uint8_t data)
+{
+ dbg("Set cmd 0x%02x, data 0x%02x ALL", cmd, data);
+
+ set_nss(false);
+ while (MDSP_SPIx->SR & SPI_SR_BSY);
+
+ for (uint8_t i = 0; i < MDSP_CHAIN_COUNT; i++) {
+ send_word(cmd, data);
+ }
+
+ while (MDSP_SPIx->SR & SPI_SR_BSY);
+
+ set_nss(false);
+ set_nss(true);
+}
+
+void mdsp_set(uint8_t column, uint8_t bits)
+{
+ if (column >= MDSP_COLUMN_COUNT) return;
+
+ mdsp_send_command(column >> 3, CMD_DIGIT0 + (column & 0x7), bits);
+}
+
+void mdsp_clear(void)
+{
+ for (uint8_t i = 0; i < 8; i++) {
+ mdsp_send_command_all(CMD_DIGIT0+i, 0);
+ }
+}
diff --git a/project/matrixdsp.h b/project/matrixdsp.h
new file mode 100644
index 0000000..f9cd124
--- /dev/null
+++ b/project/matrixdsp.h
@@ -0,0 +1,47 @@
+#ifndef MATRIXDSP_H
+#define MATRIXDSP_H
+
+#include
+
+#define MDSP_SPIx SPI1
+#define MDSP_NSS_GPIO GPIOA
+#define MDSP_NSS_PIN GPIO_Pin_4;
+
+#define MDSP_CHAIN_COUNT 4
+#define MDSP_COLUMN_COUNT (MDSP_CHAIN_COUNT*8)
+
+typedef enum {
+ CMD_NOOP = 0x00,
+
+ CMD_DIGIT0 = 0x01,
+ CMD_DIGIT1 = 0x02,
+ CMD_DIGIT2 = 0x03,
+ CMD_DIGIT3 = 0x04,
+ CMD_DIGIT4 = 0x05,
+ CMD_DIGIT5 = 0x06,
+ CMD_DIGIT6 = 0x07,
+ CMD_DIGIT7 = 0x08,
+
+ CMD_DECODE_MODE = 0x09,
+ CMD_INTENSITY = 0x0A,
+ CMD_SCAN_LIMIT = 0x0B,
+ CMD_SHUTDOWN = 0x0C,
+ CMD_DISPLAY_TEST = 0x0F,
+} MDSP_Command;
+
+void mdsp_set(uint8_t column, uint8_t bits);
+
+void mdsp_clear(void);
+
+/**
+ * @brief Send a command to n-th chained driver
+ * @param idx Driver index (0, 1, 2 ...)
+ * @param cmd command to send
+ * @param data command argument
+ */
+void mdsp_send_command(uint8_t idx, MDSP_Command cmd, uint8_t data);
+
+
+void mdsp_send_command_all(MDSP_Command cmd, uint8_t data);
+
+#endif // MATRIXDSP_H