Commit 93554697 authored by Pedro Henrique Kopper's avatar Pedro Henrique Kopper

Add suport for OLED module and USB-CDC

parent 5a1bbcee
...@@ -122,6 +122,9 @@ LDSCRIPT= $(STARTUPLD)/STM32F303xC.ld ...@@ -122,6 +122,9 @@ LDSCRIPT= $(STARTUPLD)/STM32F303xC.ld
# setting. # setting.
CSRC = $(ALLCSRC) \ CSRC = $(ALLCSRC) \
$(TESTSRC) \ $(TESTSRC) \
$(CHIBIOS)/os/various/syscalls.c \
./lib/ssd1306.c \
usbcfg.c \
main.c main.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global # C++ sources that can be compiled in ARM or THUMB mode depending on the global
...@@ -135,7 +138,7 @@ ASMSRC = $(ALLASMSRC) ...@@ -135,7 +138,7 @@ ASMSRC = $(ALLASMSRC)
ASMXSRC = $(ALLXASMSRC) ASMXSRC = $(ALLXASMSRC)
# Inclusion directories. # Inclusion directories.
INCDIR = $(CONFDIR) $(ALLINC) $(TESTINC) INCDIR = $(CONFDIR) $(ALLINC) $(TESTINC) $(ROOT)/lib
# Define C warning options here. # Define C warning options here.
CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
* @brief Enables the I2C subsystem. * @brief Enables the I2C subsystem.
*/ */
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C FALSE #define HAL_USE_I2C TRUE
#endif #endif
/** /**
...@@ -149,7 +149,7 @@ ...@@ -149,7 +149,7 @@
* @brief Enables the SERIAL over USB subsystem. * @brief Enables the SERIAL over USB subsystem.
*/ */
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB FALSE #define HAL_USE_SERIAL_USB TRUE
#endif #endif
/** /**
...@@ -184,7 +184,7 @@ ...@@ -184,7 +184,7 @@
* @brief Enables the USB subsystem. * @brief Enables the USB subsystem.
*/ */
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) #if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB FALSE #define HAL_USE_USB TRUE
#endif #endif
/** /**
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
#define STM32_TIM1SW STM32_TIM1SW_PCLK2 #define STM32_TIM1SW STM32_TIM1SW_PCLK2
#define STM32_TIM8SW STM32_TIM8SW_PCLK2 #define STM32_TIM8SW STM32_TIM8SW_PCLK2
#define STM32_RTCSEL STM32_RTCSEL_LSI #define STM32_RTCSEL STM32_RTCSEL_LSI
#define STM32_USB_CLOCK_REQUIRED FALSE #define STM32_USB_CLOCK_REQUIRED TRUE
#define STM32_USBPRE STM32_USBPRE_DIV1P5 #define STM32_USBPRE STM32_USBPRE_DIV1P5
/* /*
...@@ -158,7 +158,7 @@ ...@@ -158,7 +158,7 @@
/* /*
* I2C driver system settings. * I2C driver system settings.
*/ */
#define STM32_I2C_USE_I2C1 FALSE #define STM32_I2C_USE_I2C1 TRUE
#define STM32_I2C_USE_I2C2 FALSE #define STM32_I2C_USE_I2C2 FALSE
#define STM32_I2C_BUSY_TIMEOUT 50 #define STM32_I2C_BUSY_TIMEOUT 50
#define STM32_I2C_I2C1_IRQ_PRIORITY 10 #define STM32_I2C_I2C1_IRQ_PRIORITY 10
...@@ -260,7 +260,7 @@ ...@@ -260,7 +260,7 @@
/* /*
* USB driver system settings. * USB driver system settings.
*/ */
#define STM32_USB_USE_USB1 FALSE #define STM32_USB_USE_USB1 TRUE
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE #define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
#define STM32_USB_USB1_HP_IRQ_PRIORITY 13 #define STM32_USB_USB1_HP_IRQ_PRIORITY 13
#define STM32_USB_USB1_LP_IRQ_PRIORITY 14 #define STM32_USB_USB1_LP_IRQ_PRIORITY 14
......
#include <string.h>
#include "hal.h"
#include "ssd1306.h"
#include "ssd1306_font.c"
/* Steal from https://stm32f4-discovery.net/2015/05/library-61-ssd1306-oled-i2c-lcd-for-stm32f4xx/ */
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static msg_t wrCmd(void *ip, uint8_t cmd) {
const SSD1306Driver *drvp = (const SSD1306Driver *)ip;
msg_t ret;
uint8_t txbuf[] = { 0x00, cmd };
i2cAcquireBus(drvp->config->i2cp);
i2cStart(drvp->config->i2cp, drvp->config->i2ccfg);
ret = i2cMasterTransmitTimeout(drvp->config->i2cp, drvp->config->sad,
txbuf, sizeof(txbuf), NULL, 0, TIME_INFINITE);
i2cReleaseBus(drvp->config->i2cp);
return ret;
}
static msg_t wrDat(void *ip, uint8_t *txbuf, uint16_t len) {
const SSD1306Driver *drvp = (const SSD1306Driver *)ip;
msg_t ret;
i2cAcquireBus(drvp->config->i2cp);
i2cStart(drvp->config->i2cp, drvp->config->i2ccfg);
ret = i2cMasterTransmitTimeout(drvp->config->i2cp, drvp->config->sad,
txbuf, len, NULL, 0, TIME_INFINITE);
i2cReleaseBus(drvp->config->i2cp);
return ret;
}
static void updateScreen(void *ip) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
uint8_t idx;
for (idx = 0; idx < 8; idx++) {
wrCmd(drvp, 0xB0 + idx);
wrCmd(drvp, 0x00);
wrCmd(drvp, 0x10);
// Write multi data
wrDat(drvp, &drvp->fb[SSD1306_WIDTH_FIXED * idx], SSD1306_WIDTH_FIXED);
}
}
static void toggleInvert(void *ip) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
uint16_t idx;
// Toggle invert
drvp->inv = !drvp->inv;
for (idx = 0; idx < sizeof(drvp->fb); idx++) {
if (idx % SSD1306_WIDTH_FIXED == 0) continue;
drvp->fb[idx] = ~drvp->fb[idx];
}
}
static void fillScreen(void *ip, ssd1306_color_t color) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
uint8_t idx;
for (idx = 0; idx < 8; idx++) {
drvp->fb[SSD1306_WIDTH_FIXED * idx] = 0x40;
memset(&drvp->fb[SSD1306_WIDTH_FIXED * idx + 1],
color == SSD1306_COLOR_BLACK ? 0x00 : 0xff, SSD1306_WIDTH);
}
}
static void drawPixel(void *ip, uint8_t x, uint8_t y, ssd1306_color_t color) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
if (x > SSD1306_WIDTH || y > SSD1306_HEIGHT) return;
// Check if pixels are inverted
if (drvp->inv) {
color = (ssd1306_color_t)!color;
}
// Set color
if (color == SSD1306_COLOR_WHITE) {
drvp->fb[x + (y / 8) * SSD1306_WIDTH_FIXED + 1] |= 1 << (y % 8);
} else {
drvp->fb[x + (y / 8) * SSD1306_WIDTH_FIXED + 1] &= ~(1 << (y % 8));
}
}
static void gotoXy(void *ip, uint8_t x, uint8_t y) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
drvp->x = x;
drvp->y = y;
}
static char PUTC(void *ip, char ch, const ssd1306_font_t *font, ssd1306_color_t color) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
uint32_t i, b, j;
// Check available space in OLED
if (drvp->x + font->fw >= SSD1306_WIDTH ||
drvp->y + font->fh >= SSD1306_HEIGHT) {
return 0;
}
// Go through font
for (i = 0; i < font->fh; i++) {
b = font->dt[(ch - 32) * font->fh + i];
for (j = 0; j < font->fw; j++) {
if ((b << j) & 0x8000) {
drawPixel(drvp, drvp->x + j, drvp->y + i, color);
} else {
drawPixel(drvp, drvp->x + j, drvp->y + i,(ssd1306_color_t)! color);
}
}
}
//dirty hack for 7x10 font
/* for (i = 0; i < font->fh; i++) {
b = font->dt[(ch - 32) * font->fh + i];
for (j = 1; j < (uint32_t)(font->fw + 1); j++) {
if ((b << j) & 0x8000) {
drawPixel(drvp, drvp->x + j, drvp->y + i + 1, color);
} else {
drawPixel(drvp, drvp->x + j, drvp->y + i + 1,(ssd1306_color_t)! color);
}
}
}
*/
// Increase pointer
drvp->x += font->fw;
// Return character written
return ch;
}
static char PUTS(void *ip, char *str, const ssd1306_font_t *font, ssd1306_color_t color) {
// Write characters
while (*str) {
// Write character by character
if (PUTC(ip, *str, font, color) != *str) {
// Return error
return *str;
}
// Increase string pointer
str++;
}
// Everything OK, zero should be returned
return *str;
}
static void setDisplay(void *ip, uint8_t on) {
wrCmd(ip, 0x8D);
wrCmd(ip, on ? 0x14 : 0x10);
wrCmd(ip, 0xAE);
}
static const struct SSD1306VMT vmt_ssd1306 = {
updateScreen, toggleInvert, fillScreen, drawPixel,
gotoXy, PUTC, PUTS, setDisplay
};
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
void ssd1306ObjectInit(SSD1306Driver *devp) {
devp->vmt = &vmt_ssd1306;
devp->config = NULL;
devp->state = SSD1306_STOP;
}
void ssd1306Start(SSD1306Driver *devp, const SSD1306Config *config) {
const uint8_t cmds[] = {
0xAE, // display off
0x20, // Set memory address
0x10, // 0x00: horizontal addressing mode, 0x01: vertical addressing mode
// 0x10: Page addressing mode(RESET), 0x11: invalid
0xB0, // Set page start address for page addressing mode: 0 ~ 7
0xC8, // Set COM output scan direction
0x00, // Set low column address
0x10, // Set height column address
0x40, // Set start line address
0x81, // Set contrast control register
0xFF,
0xA1, // Set segment re-map 0 to 127
0xA6, // Set normal display
0xA8, // Set multiplex ratio(1 to 64)
0x3F,
0xA4, // 0xa4: ouput follows RAM content, 0xa5: ouput ignores RAM content
0xD3, // Set display offset
0x00, // Not offset
0xD5, // Set display clock divide ratio/oscillator frequency
0xF0, // Set divide ration
0xD9, // Set pre-charge period
0x22,
0xDA, // Set COM pins hardware configuration
0x12,
0xDB, // Set VCOMH
0x20, // 0x20: 0.77*Vcc
0x8D, // Set DC-DC enable
0x14,
0xAF, // turn on SSD1306panel
};
uint8_t idx;
chDbgCheck((devp != NULL) && (config != NULL));
chDbgAssert((devp->state == SSD1306_STOP) || (devp->state == SSD1306_READY),
"ssd1306Start(), invalid state");
devp->config = config;
// A little delay
chThdSleepMilliseconds(100);
// OLED initialize
for (idx = 0; idx < sizeof(cmds) / sizeof(cmds[0]); idx++) {
wrCmd(devp, cmds[idx]);
}
// Clear screen
fillScreen(devp, SSD1306_COLOR_WHITE);
// Update screen
updateScreen(devp);
// Set default value
devp->x = 0;
devp->y = 0;
devp->state = SSD1306_READY;
}
void ssd1306Stop(SSD1306Driver *devp) {
chDbgAssert((devp->state == SSD1306_STOP) || (devp->state == SSD1306_READY),
"ssd1306Stop(), invalid state");
if (devp->state == SSD1306_READY) {
// Turn off display
setDisplay(devp, 0);
}
devp->state = SSD1306_STOP;
}
#ifndef __SSD1306_H__
#define __SSD1306_H__
#include "hal.h"
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !HAL_USE_I2C
#error "SSD1306 requires HAL_USE_I2C"
#endif
#define SSD1306_WIDTH 128
#define SSD1306_HEIGHT 64
#define SSD1306_WIDTH_FIXED (SSD1306_WIDTH + 1)
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
typedef enum {
SSD1306_COLOR_BLACK = 0x00,
SSD1306_COLOR_WHITE = 0x01
} ssd1306_color_t;
typedef struct {
uint8_t fw;
uint8_t fh;
const uint16_t *dt;
} ssd1306_font_t;
typedef enum {
SSD1306_SAD_0X78 = (0x78 >> 1),
SSD1306_SAD_0X7A = (0x7A >> 1)
} ssd1306_sad_t;
typedef enum {
SSD1306_UNINIT = 0,
SSD1306_STOP = 1,
SSD1306_READY = 2,
} ssd1306_state_t;
typedef struct {
I2CDriver *i2cp;
const I2CConfig *i2ccfg;
ssd1306_sad_t sad;
} SSD1306Config;
#define _ssd1306_methods \
void (*updateScreen)(void *ip); \
void (*toggleInvert)(void *ip); \
void (*fillScreen)(void *ip, ssd1306_color_t color); \
void (*drawPixel)(void *ip, uint8_t x, uint8_t y, ssd1306_color_t color); \
void (*gotoXy)(void *ip, uint8_t x, uint8_t y); \
char (*putc)(void *ip, char ch, const ssd1306_font_t *font, ssd1306_color_t color); \
char (*puts)(void *ip, char *str, const ssd1306_font_t *font, ssd1306_color_t color); \
void (*setDisplay)(void *ip, uint8_t on);
struct SSD1306VMT {
_ssd1306_methods
};
#define _ssd1306_data \
ssd1306_state_t state; \
const SSD1306Config *config; \
typedef struct SSD1306Driver {
const struct SSD1306VMT *vmt;
_ssd1306_data;
uint8_t x;
uint8_t y;
uint8_t inv;
uint8_t fb[SSD1306_WIDTH_FIXED * SSD1306_HEIGHT / 8];
} SSD1306Driver;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
#define ssd1306UpdateScreen(ip) \
(ip)->vmt->updateScreen(ip)
#define ssd1306ToggleInvert(ip) \
(ip)->vmt->toggleInvert(ip)
#define ssd1306FillScreen(ip, color) \
(ip)->vmt->fillScreen(ip, color)
#define ssd1306DrawPixel(ip, x, y, color) \
(ip)->vmt->drawPixel(ip, x, y, color)
#define ssd1306GotoXy(ip, x, y) \
(ip)->vmt->gotoXy(ip, x, y)
#define ssd1306Putc(ip, ch, font, color) \
(ip)->vmt->putc(ip, ch, font, color)
#define ssd1306Puts(ip, str, font, color) \
(ip)->vmt->puts(ip, str, font, color)
#define ssd1306SetDisplay(ip, on) \
(ip)->vmt->setDisplay(ip, on)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
extern const ssd1306_font_t ssd1306_font_11x18;
void ssd1306ObjectInit(SSD1306Driver *devp);
void ssd1306Start(SSD1306Driver *devp, const SSD1306Config *config);
void ssd1306Stop(SSD1306Driver *devp);
#ifdef __cplusplus
}
#endif
#endif /* __SSD1306_H__ */
This diff is collapsed.
/* Steal from https://stm32f4-discovery.net/2015/05/library-61-ssd1306-oled-i2c-lcd-for-stm32f4xx/ */
static const uint16_t FONT_7x10_DATA[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp
0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // !
0x2800, 0x2800, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // "
0x2400, 0x2400, 0x7C00, 0x2400, 0x4800, 0x7C00, 0x4800, 0x4800, 0x0000, 0x0000, // #
0x3800, 0x5400, 0x5000, 0x3800, 0x1400, 0x5400, 0x5400, 0x3800, 0x1000, 0x0000, // $
0x2000, 0x5400, 0x5800, 0x3000, 0x2800, 0x5400, 0x1400, 0x0800, 0x0000, 0x0000, // %
0x1000, 0x2800, 0x2800, 0x1000, 0x3400, 0x4800, 0x4800, 0x3400, 0x0000, 0x0000, // &
0x1000, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // '
0x0800, 0x1000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x1000, 0x0800, // (
0x2000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x1000, 0x2000, // )
0x1000, 0x3800, 0x1000, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // *
0x0000, 0x0000, 0x1000, 0x1000, 0x7C00, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, // +
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3800, 0x0000, 0x0000, 0x0000, 0x0000, // -
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // .
0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x0000, 0x0000, // /
0x3800, 0x4400, 0x4400, 0x5400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 0
0x1000, 0x3000, 0x5000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // 1
0x3800, 0x4400, 0x4400, 0x0400, 0x0800, 0x1000, 0x2000, 0x7C00, 0x0000, 0x0000, // 2
0x3800, 0x4400, 0x0400, 0x1800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 3
0x0800, 0x1800, 0x2800, 0x2800, 0x4800, 0x7C00, 0x0800, 0x0800, 0x0000, 0x0000, // 4
0x7C00, 0x4000, 0x4000, 0x7800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 5
0x3800, 0x4400, 0x4000, 0x7800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 6
0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, // 7
0x3800, 0x4400, 0x4400, 0x3800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 8
0x3800, 0x4400, 0x4400, 0x4400, 0x3C00, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 9
0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // :
0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ;
0x0000, 0x0000, 0x0C00, 0x3000, 0x4000, 0x3000, 0x0C00, 0x0000, 0x0000, 0x0000, // <
0x0000, 0x0000, 0x0000, 0x7C00, 0x0000, 0x7C00, 0x0000, 0x0000, 0x0000, 0x0000, // =
0x0000, 0x0000, 0x6000, 0x1800, 0x0400, 0x1800, 0x6000, 0x0000, 0x0000, 0x0000, // >
0x3800, 0x4400, 0x0400, 0x0800, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ?
0x3800, 0x4400, 0x4C00, 0x5400, 0x5C00, 0x4000, 0x4000, 0x3800, 0x0000, 0x0000, // @
0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000, // A
0x7800, 0x4400, 0x4400, 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x0000, 0x0000, // B
0x3800, 0x4400, 0x4000, 0x4000, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // C
0x7000, 0x4800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4800, 0x7000, 0x0000, 0x0000, // D
0x7C00, 0x4000, 0x4000, 0x7C00, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // E
0x7C00, 0x4000, 0x4000, 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // F
0x3800, 0x4400, 0x4000, 0x4000, 0x5C00, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // G
0x4400, 0x4400, 0x4400, 0x7C00, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // H
0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3800, 0x0000, 0x0000, // I
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // J
0x4400, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // K
0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // L
0x4400, 0x6C00, 0x6C00, 0x5400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // M
0x4400, 0x6400, 0x6400, 0x5400, 0x5400, 0x4C00, 0x4C00, 0x4400, 0x0000, 0x0000, // N
0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // O
0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // P
0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x5400, 0x3800, 0x0400, 0x0000, // Q
0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // R
0x3800, 0x4400, 0x4000, 0x3000, 0x0800, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // S
0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // T
0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // U
0x4400, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x1000, 0x0000, 0x0000, // V
0x4400, 0x4400, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // W
0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, // X
0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // Y
0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // Z
0x1800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1800, // [
0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0000, 0x0000, /* \ */
0x3000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3000, // ]
0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE00, // _
0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // `
0x0000, 0x0000, 0x3800, 0x4400, 0x3C00, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // a
0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x0000, 0x0000, // b
0x0000, 0x0000, 0x3800, 0x4400, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // c
0x0400, 0x0400, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // d
0x0000, 0x0000, 0x3800, 0x4400, 0x7C00, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // e
0x0C00, 0x1000, 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // f
0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x7800, // g
0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // h
0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // i
0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xE000, // j
0x4000, 0x4000, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4400, 0x0000, 0x0000, // k
0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // l
0x0000, 0x0000, 0x7800, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x0000, 0x0000, // m
0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // n
0x0000, 0x0000, 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // o
0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x4000, 0x4000, // p
0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x0400, // q
0x0000, 0x0000, 0x5800, 0x6400, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // r
0x0000, 0x0000, 0x3800, 0x4400, 0x3000, 0x0800, 0x4400, 0x3800, 0x0000, 0x0000, // s
0x2000, 0x2000, 0x7800, 0x2000, 0x2000, 0x2000, 0x2000, 0x1800, 0x0000, 0x0000, // t
0x0000, 0x0000, 0x4400, 0x4400, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // u
0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x0000, 0x0000, // v
0x0000, 0x0000, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // w
0x0000, 0x0000, 0x4400, 0x2800, 0x1000, 0x1000, 0x2800, 0x4400, 0x0000, 0x0000, // x
0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x6000, // y
0x0000, 0x0000, 0x7C00, 0x0800, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // z
0x1800, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1800, // {
0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, // |
0x3000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x3000, // }
0x0000, 0x0000, 0x0000, 0x7400, 0x4C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~
};
const ssd1306_font_t ssd1306_font_7x10 = {
7, 10, FONT_7x10_DATA
};
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"
#include "board.h"
#include "rt_test_root.h" #include "rt_test_root.h"
#include "oslib_test_root.h" #include "oslib_test_root.h"
#include <stdio.h>
#include "usbcfg.h"
#include "ssd1306.h"
#define usb_lld_connect_bus(usbp)
#define usb_lld_disconnect_bus(usbp)
static const I2CConfig i2ccfg = {
STM32_TIMINGR_PRESC(8U) | STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(3U) |
STM32_TIMINGR_SCLH(3U) | STM32_TIMINGR_SCLL(9U),
0,
0
};
static const SSD1306Config ssd1306cfg = {
&I2CD1,
&i2ccfg,
SSD1306_SAD_0X78,
};
static SSD1306Driver SSD1306D1;
static THD_WORKING_AREA(waOledDisplay, 1024);
static THD_FUNCTION(OledDisplay, arg) {
(void)arg;
chRegSetThreadName("OledDisplay");
ssd1306ObjectInit(&SSD1306D1);
ssd1306Start(&SSD1306D1, &ssd1306cfg);
ssd1306ToggleInvert(&SSD1306D1);
ssd1306FillScreen(&SSD1306D1, 0x00);
int i = 0;
while (TRUE) {
ssd1306FillScreen(&SSD1306D1, 0x01);
char buf[32] = {0};
ssd1306GotoXy(&SSD1306D1, 0, 1);
ssd1306Puts(&SSD1306D1, "TESTE", &ssd1306_font_11x18, SSD1306_COLOR_WHITE);
ssd1306GotoXy(&SSD1306D1, 0, 32);
ssd1306Puts(&SSD1306D1, "0123456789", &ssd1306_font_11x18, SSD1306_COLOR_WHITE);
ssd1306UpdateScreen(&SSD1306D1);
i++;
chThdSleepMilliseconds(1000);
}
ssd1306Stop(&SSD1306D1);
}
/* /*
* Green LED blinker thread, times are in milliseconds. * Green LED blinker thread, times are in milliseconds.
...@@ -13,9 +64,17 @@ static THD_FUNCTION(Thread1, arg) { ...@@ -13,9 +64,17 @@ static THD_FUNCTION(Thread1, arg) {
chRegSetThreadName("blinker"); chRegSetThreadName("blinker");
while (true) { while (true) {
palClearLine(LINE_LED0); palClearLine(LINE_LED0);
chThdSleepMilliseconds(500); chThdSleepMilliseconds(100);
palSetLine(LINE_LED0); palSetLine(LINE_LED0);
chThdSleepMilliseconds(500); chThdSleepMilliseconds(100);
palClearLine(LINE_LED1);
chThdSleepMilliseconds(100);
palSetLine(LINE_LED1);
chThdSleepMilliseconds(100);
palClearLine(LINE_LED2);
chThdSleepMilliseconds(100);
palSetLine(LINE_LED2);
chThdSleepMilliseconds(100);
} }
} }
...@@ -34,6 +93,18 @@ int main(void) { ...@@ -34,6 +93,18 @@ int main(void) {
halInit(); halInit();
chSysInit(); chSysInit();
palSetPadMode(GPIOA, 11, PAL_MODE_ALTERNATE(14));
palSetPadMode(GPIOA, 12, PAL_MODE_ALTERNATE(14));
sduObjectInit(&SDU1);
sduStart(&SDU1, &serusbcfg1);
sduObjectInit(&SDU2);
sduStart(&SDU2, &serusbcfg2);
usbStart(serusbcfg1.usbp, &usbcfg);
usbConnectBus(serusbcfg1.usbp);
/* /*
* Activates the serial driver 3 using the driver default configuration. * Activates the serial driver 3 using the driver default configuration.
*/ */
...@@ -42,19 +113,23 @@ int main(void) { ...@@ -42,19 +113,23 @@ int main(void) {
/* /*
* Creates the blinker thread. * Creates the blinker thread.
*/ */
palSetPadMode(GPIOB, GPIOB_PIN12, PAL_MODE_OUTPUT_PUSHPULL); palSetLineMode(LINE_LED0, PAL_MODE_OUTPUT_PUSHPULL);
palSetLineMode(LINE_LED1, PAL_MODE_OUTPUT_PUSHPULL);
palSetLineMode(LINE_LED2, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4));
palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4));
palSetPadMode(GPIOB, 10, PAL_MODE_ALTERNATE(7)); palSetPadMode(GPIOB, 10, PAL_MODE_ALTERNATE(7));
palSetPadMode(GPIOB, 11, PAL_MODE_ALTERNATE(7)); palSetPadMode(GPIOB, 11, PAL_MODE_ALTERNATE(7));
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
chThdCreateStatic(waThread1, sizeof(waOledDisplay), NORMALPRIO, OledDisplay, NULL);