[stm32f429-discovery] General sweep to fix style according to make stylecheck.

This commit is contained in:
Piotr Esden-Tempski
2015-02-04 20:39:32 -08:00
parent c06aba1603
commit 8c6eb9ca57
26 changed files with 1091 additions and 963 deletions

View File

@@ -33,18 +33,21 @@
static volatile uint32_t system_millis; static volatile uint32_t system_millis;
/* Called when systick fires */ /* Called when systick fires */
void sys_tick_handler(void) { void sys_tick_handler(void)
{
system_millis++; system_millis++;
} }
/* simple sleep for delay milliseconds */ /* simple sleep for delay milliseconds */
void msleep(uint32_t delay) { void msleep(uint32_t delay)
{
uint32_t wake = system_millis + delay; uint32_t wake = system_millis + delay;
while (wake > system_millis) ; while (wake > system_millis);
} }
/* Getter function for the current time */ /* Getter function for the current time */
uint32_t mtime(void) { uint32_t mtime(void)
{
return system_millis; return system_millis;
} }

View File

@@ -41,10 +41,10 @@
* read by the program. See the README file for a discussion of * read by the program. See the README file for a discussion of
* the failure semantics. * the failure semantics.
*/ */
#define RECV_BUF_SIZE 128 // Arbitrary buffer size #define RECV_BUF_SIZE 128 /* Arbitrary buffer size */
char recv_buf[RECV_BUF_SIZE]; char recv_buf[RECV_BUF_SIZE];
volatile int recv_ndx_nxt; // Next place to store volatile int recv_ndx_nxt; /* Next place to store */
volatile int recv_ndx_cur; // Next place to read volatile int recv_ndx_cur; /* Next place to read */
/* For interrupt handling we add a new function which is called /* For interrupt handling we add a new function which is called
* when recieve interrupts happen. The name (usart1_isr) is created * when recieve interrupts happen. The name (usart1_isr) is created
@@ -57,7 +57,8 @@ volatile int recv_ndx_cur; // Next place to read
* right or it won't work. And you'll wonder where your interrupts * right or it won't work. And you'll wonder where your interrupts
* are going. * are going.
*/ */
void usart1_isr(void) { void usart1_isr(void)
{
uint32_t reg; uint32_t reg;
int i; int i;
@@ -79,7 +80,8 @@ void usart1_isr(void) {
recv_ndx_nxt = i; recv_ndx_nxt = i;
} }
} }
} while ((reg & USART_SR_RXNE) != 0); // can read back-to-back interrupts } while ((reg & USART_SR_RXNE) != 0); /* can read back-to-back
interrupts */
} }
/* /*
@@ -88,7 +90,8 @@ void usart1_isr(void) {
* Send the character 'c' to the USART, wait for the USART * Send the character 'c' to the USART, wait for the USART
* transmit buffer to be empty first. * transmit buffer to be empty first.
*/ */
void console_putc(char c) { void console_putc(char c)
{
uint32_t reg; uint32_t reg;
do { do {
reg = USART_SR(CONSOLE_UART); reg = USART_SR(CONSOLE_UART);
@@ -106,10 +109,11 @@ void console_putc(char c) {
* The implementation is a bit different however, now it looks * The implementation is a bit different however, now it looks
* in the ring buffer to see if a character has arrived. * in the ring buffer to see if a character has arrived.
*/ */
char console_getc(int wait) { char console_getc(int wait)
{
char c = 0; char c = 0;
while ((wait != 0) && (recv_ndx_cur == recv_ndx_nxt)) ; while ((wait != 0) && (recv_ndx_cur == recv_ndx_nxt));
if (recv_ndx_cur != recv_ndx_nxt) { if (recv_ndx_cur != recv_ndx_nxt) {
c = recv_buf[recv_ndx_cur]; c = recv_buf[recv_ndx_cur];
recv_ndx_cur = (recv_ndx_cur + 1) % RECV_BUF_SIZE; recv_ndx_cur = (recv_ndx_cur + 1) % RECV_BUF_SIZE;
@@ -124,7 +128,8 @@ char console_getc(int wait) {
* after the last character, as indicated by a NUL character, is * after the last character, as indicated by a NUL character, is
* reached. * reached.
*/ */
void console_puts(char *s) { void console_puts(char *s)
{
while (*s != '\000') { while (*s != '\000') {
console_putc(*s); console_putc(*s);
/* Add in a carraige return, after sending line feed */ /* Add in a carraige return, after sending line feed */
@@ -142,7 +147,8 @@ void console_puts(char *s) {
* support for editing characters (back space and delete) * support for editing characters (back space and delete)
* end when a <CR> character is received. * end when a <CR> character is received.
*/ */
int console_gets(char *s, int len) { int console_gets(char *s, int len)
{
char *t = s; char *t = s;
char c; char c;
@@ -165,7 +171,7 @@ int console_gets(char *s, int len) {
/* update end of string with NUL */ /* update end of string with NUL */
*t = '\000'; *t = '\000';
} }
return (t - s); return t - s;
} }
/* /*
@@ -174,7 +180,8 @@ int console_gets(char *s, int len) {
* Set the pins and clocks to create a console that we can * Set the pins and clocks to create a console that we can
* use for serial messages and getting text from the user. * use for serial messages and getting text from the user.
*/ */
void console_setup(int baud) { void console_setup(int baud)
{
/* MUST enable the GPIO clock in ADDITION to the USART clock */ /* MUST enable the GPIO clock in ADDITION to the USART clock */
rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOA);

View File

@@ -27,7 +27,7 @@
* These define sort of the minimum "library" of functions which * These define sort of the minimum "library" of functions which
* we can use on a serial port. If you wish to use a different * we can use on a serial port. If you wish to use a different
* USART there are several things to change: * USART there are several things to change:
* - CONSOLE_UART change this * - CONSOLE_UART change this
* - Change the peripheral enable clock * - Change the peripheral enable clock
* - add usartx_isr for interrupts * - add usartx_isr for interrupts
* - nvic_enable_interrupt(your choice of USART/UART) * - nvic_enable_interrupt(your choice of USART/UART)

View File

@@ -34,141 +34,141 @@
#define FONT_CHAR_HEIGHT 12 #define FONT_CHAR_HEIGHT 12
static const unsigned char mcm_font[] = { static const unsigned char mcm_font[] = {
0x00, 0x00, 0x00, 0x00, 0x31, 0x4A, 0x44, 0x4A, 0x31, // 0 0x00, 0x00, 0x00, 0x00, 0x31, 0x4A, 0x44, 0x4A, 0x31, /* 0 */
0xBC, 0x22, 0x3B, 0x22, 0x22, 0x3b, 0x20, 0x20, 0x40, // 1 0xBC, 0x22, 0x3B, 0x22, 0x22, 0x3b, 0x20, 0x20, 0x40, /* 1 */
0x80, 0x61, 0x12, 0x14, 0x18, 0x10, 0x30, 0x30, 0x30, // 2 0x80, 0x61, 0x12, 0x14, 0x18, 0x10, 0x30, 0x30, 0x30, /* 2 */
0x30, 0x48, 0x40, 0x40, 0x20, 0x30, 0x48, 0x48, 0x30, // 3 0x30, 0x48, 0x40, 0x40, 0x20, 0x30, 0x48, 0x48, 0x30, /* 3 */
0x00, 0x00, 0x18, 0x20, 0x40, 0x78, 0x40, 0x20, 0x30, // 4 0x00, 0x00, 0x18, 0x20, 0x40, 0x78, 0x40, 0x20, 0x30, /* 4 */
0x16, 0x0e, 0x10, 0x20, 0x40, 0x40, 0x38, 0x04, 0x18, // 5 0x16, 0x0e, 0x10, 0x20, 0x40, 0x40, 0x38, 0x04, 0x18, /* 5 */
0x80, 0x2c, 0x52, 0x12, 0x12, 0x12, 0x02, 0x02, 0x02, // 6 0x80, 0x2c, 0x52, 0x12, 0x12, 0x12, 0x02, 0x02, 0x02, /* 6 */
0x18, 0x24, 0x42, 0x42, 0x3e, 0x42, 0x42, 0x24, 0x18, // 7 0x18, 0x24, 0x42, 0x42, 0x3e, 0x42, 0x42, 0x24, 0x18, /* 7 */
0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x48, 0x30, // 8 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x48, 0x30, /* 8 */
0x00, 0x00, 0x40, 0x48, 0x50, 0x60, 0x50, 0x4A, 0x44, // 9 0x00, 0x00, 0x40, 0x48, 0x50, 0x60, 0x50, 0x4A, 0x44, /* 9 */
0x40, 0x20, 0x10, 0x10, 0x10, 0x10, 0x18, 0x24, 0x42, // 10 0x40, 0x20, 0x10, 0x10, 0x10, 0x10, 0x18, 0x24, 0x42, /* 10 */
0x80, 0x48, 0x48, 0x48, 0x48, 0x74, 0x40, 0x40, 0x40, // 11 0x80, 0x48, 0x48, 0x48, 0x48, 0x74, 0x40, 0x40, 0x40, /* 11 */
0x00, 0x00, 0x00, 0x62, 0x22, 0x24, 0x28, 0x30, 0x20, // 12 0x00, 0x00, 0x00, 0x62, 0x22, 0x24, 0x28, 0x30, 0x20, /* 12 */
0x08, 0x1c, 0x20, 0x18, 0x20, 0x40, 0x3c, 0x02, 0x0c, // 13 0x08, 0x1c, 0x20, 0x18, 0x20, 0x40, 0x3c, 0x02, 0x0c, /* 13 */
0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x24, 0x18, // 14 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x24, 0x18, /* 14 */
0x00, 0x00, 0x00, 0x3f, 0x54, 0x24, 0x24, 0x24, 0x24, // 15 0x00, 0x00, 0x00, 0x3f, 0x54, 0x24, 0x24, 0x24, 0x24, /* 15 */
0x98, 0x24, 0x42, 0x42, 0x64, 0x58, 0x40, 0x40, 0x40, // 16 0x98, 0x24, 0x42, 0x42, 0x64, 0x58, 0x40, 0x40, 0x40, /* 16 */
0x00, 0x00, 0x00, 0x1f, 0x24, 0x42, 0x42, 0x24, 0x18, // 17 0x00, 0x00, 0x00, 0x1f, 0x24, 0x42, 0x42, 0x24, 0x18, /* 17 */
0x00, 0x00, 0x00, 0x3f, 0x48, 0x08, 0x08, 0x08, 0x08, // 18 0x00, 0x00, 0x00, 0x3f, 0x48, 0x08, 0x08, 0x08, 0x08, /* 18 */
0x00, 0x00, 0x00, 0x62, 0x24, 0x24, 0x24, 0x24, 0x18, // 19 0x00, 0x00, 0x00, 0x62, 0x24, 0x24, 0x24, 0x24, 0x18, /* 19 */
0x10, 0x10, 0x38, 0x54, 0x54, 0x54, 0x38, 0x10, 0x10, // 20 0x10, 0x10, 0x38, 0x54, 0x54, 0x54, 0x38, 0x10, 0x10, /* 20 */
0x00, 0x00, 0x00, 0x00, 0x62, 0x14, 0x08, 0x14, 0x23, // 21 0x00, 0x00, 0x00, 0x00, 0x62, 0x14, 0x08, 0x14, 0x23, /* 21 */
0x80, 0x49, 0x2a, 0x2a, 0x2a, 0x1c, 0x08, 0x08, 0x08, // 22 0x80, 0x49, 0x2a, 0x2a, 0x2a, 0x1c, 0x08, 0x08, 0x08, /* 22 */
0x00, 0x00, 0x00, 0x22, 0x41, 0x49, 0x49, 0x49, 0x36, // 23 0x00, 0x00, 0x00, 0x22, 0x41, 0x49, 0x49, 0x49, 0x36, /* 23 */
0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x22, 0x22, 0x63, // 24 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x22, 0x22, 0x63, /* 24 */
0x0f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x50, 0x30, 0x10, // 25 0x0f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x50, 0x30, 0x10, /* 25 */
0x00, 0x00, 0x04, 0x02, 0x7f, 0x02, 0x04, 0x00, 0x00, // 26 0x00, 0x00, 0x04, 0x02, 0x7f, 0x02, 0x04, 0x00, 0x00, /* 26 */
0x00, 0x00, 0x10, 0x20, 0x7f, 0x20, 0x10, 0x00, 0x00, // 27 0x00, 0x00, 0x10, 0x20, 0x7f, 0x20, 0x10, 0x00, 0x00, /* 27 */
0x08, 0x1c, 0x2a, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 28 0x08, 0x1c, 0x2a, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 28 */
0x00, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x08, 0x00, 0x00, // 29 0x00, 0x00, 0x08, 0x00, 0x7f, 0x00, 0x08, 0x00, 0x00, /* 29 */
0x7f, 0x20, 0x10, 0x08, 0x06, 0x08, 0x10, 0x20, 0x7f, // 30 0x7f, 0x20, 0x10, 0x08, 0x06, 0x08, 0x10, 0x20, 0x7f, /* 30 */
0x00, 0x30, 0x45, 0x06, 0x30, 0x45, 0x06, 0x00, 0x00, // 31 0x00, 0x30, 0x45, 0x06, 0x30, 0x45, 0x06, 0x00, 0x00, /* 31 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 32 */
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, // 33 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, /* 33 */
0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 34 0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 34 */
0x14, 0x14, 0x14, 0x7f, 0x14, 0x7f, 0x14, 0x14, 0x14, // 35 0x14, 0x14, 0x14, 0x7f, 0x14, 0x7f, 0x14, 0x14, 0x14, /* 35 */
0x08, 0x3f, 0x48, 0x48, 0x3e, 0x09, 0x09, 0x7e, 0x08, // 36 0x08, 0x3f, 0x48, 0x48, 0x3e, 0x09, 0x09, 0x7e, 0x08, /* 36 */
0x20, 0x51, 0x22, 0x04, 0x08, 0x10, 0x22, 0x45, 0x02, // 37 0x20, 0x51, 0x22, 0x04, 0x08, 0x10, 0x22, 0x45, 0x02, /* 37 */
0x38, 0x44, 0x44, 0x28, 0x10, 0x29, 0x46, 0x46, 0x39, // 38 0x38, 0x44, 0x44, 0x28, 0x10, 0x29, 0x46, 0x46, 0x39, /* 38 */
0x20, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 39 0x20, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 39 */
0x08, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x08, // 40 0x08, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x08, /* 40 */
0x08, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x08, // 41 0x08, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x08, /* 41 */
0x80, 0x49, 0x2a, 0x1c, 0x7f, 0x1c, 0x2a, 0x49, 0x80, // 42 0x80, 0x49, 0x2a, 0x1c, 0x7f, 0x1c, 0x2a, 0x49, 0x80, /* 42 */
0x00, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x00, // 43 0x00, 0x80, 0x80, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x00, /* 43 */
0x80, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x20, // 44 0x80, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x20, /* 44 */
0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, // 45 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, /* 45 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, // 46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 46 */
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, // 47 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, /* 47 */
0x3e, 0x41, 0x43, 0x45, 0x49, 0x51, 0x61, 0x41, 0x3e, // 48 0x3e, 0x41, 0x43, 0x45, 0x49, 0x51, 0x61, 0x41, 0x3e, /* 48 */
0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, // 49 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, /* 49 */
0x3e, 0x41, 0x01, 0x02, 0x0c, 0x10, 0x20, 0x40, 0x7f, // 50 0x3e, 0x41, 0x01, 0x02, 0x0c, 0x10, 0x20, 0x40, 0x7f, /* 50 */
0x3e, 0x41, 0x01, 0x01, 0x1e, 0x01, 0x01, 0x41, 0x3e, // 51 0x3e, 0x41, 0x01, 0x01, 0x1e, 0x01, 0x01, 0x41, 0x3e, /* 51 */
0x02, 0x06, 0x0a, 0x12, 0x22, 0x7f, 0x02, 0x02, 0x02, // 52 0x02, 0x06, 0x0a, 0x12, 0x22, 0x7f, 0x02, 0x02, 0x02, /* 52 */
0x7f, 0x40, 0x40, 0x40, 0x7e, 0x01, 0x01, 0x41, 0x3e, // 53 0x7f, 0x40, 0x40, 0x40, 0x7e, 0x01, 0x01, 0x41, 0x3e, /* 53 */
0x3e, 0x41, 0x40, 0x40, 0x7e, 0x41, 0x41, 0x41, 0x3e, // 54 0x3e, 0x41, 0x40, 0x40, 0x7e, 0x41, 0x41, 0x41, 0x3e, /* 54 */
0x7f, 0x41, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10, 0x10, // 55 0x7f, 0x41, 0x02, 0x04, 0x08, 0x10, 0x10, 0x10, 0x10, /* 55 */
0x3e, 0x41, 0x41, 0x41, 0x3e, 0x41, 0x41, 0x41, 0x3e, // 56 0x3e, 0x41, 0x41, 0x41, 0x3e, 0x41, 0x41, 0x41, 0x3e, /* 56 */
0x3f, 0x41, 0x41, 0x41, 0x3f, 0x01, 0x01, 0x41, 0x3e, // 57 0x3f, 0x41, 0x41, 0x41, 0x3f, 0x01, 0x01, 0x41, 0x3e, /* 57 */
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, // 58 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, /* 58 */
0xa0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x20, // 59 0xa0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x20, /* 59 */
0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04, // 60 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04, /* 60 */
0x00, 0x00, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x00, 0x00, // 61 0x00, 0x00, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x00, 0x00, /* 61 */
0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, // 62 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, /* 62 */
0x3e, 0x41, 0x41, 0x02, 0x04, 0x08, 0x08, 0x00, 0x08, // 63 0x3e, 0x41, 0x41, 0x02, 0x04, 0x08, 0x08, 0x00, 0x08, /* 63 */
0x3e, 0x41, 0x41, 0x1d, 0x55, 0x5e, 0x40, 0x40, 0x3e, // 64 0x3e, 0x41, 0x41, 0x1d, 0x55, 0x5e, 0x40, 0x40, 0x3e, /* 64 */
0x1c, 0x22, 0x41, 0x41, 0x7f, 0x41, 0x41, 0x41, 0x41, // 65 0x1c, 0x22, 0x41, 0x41, 0x7f, 0x41, 0x41, 0x41, 0x41, /* 65 */
0x7e, 0x21, 0x21, 0x21, 0x3e, 0x21, 0x21, 0x21, 0x7e, // 66 0x7e, 0x21, 0x21, 0x21, 0x3e, 0x21, 0x21, 0x21, 0x7e, /* 66 */
0x1e, 0x21, 0x40, 0x40, 0x40, 0x40, 0x40, 0x21, 0x1e, // 67 0x1e, 0x21, 0x40, 0x40, 0x40, 0x40, 0x40, 0x21, 0x1e, /* 67 */
0x7e, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x7e, // 68 0x7e, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x7e, /* 68 */
0x7f, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7f, // 69 0x7f, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7f, /* 69 */
0x7f, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, // 70 0x7f, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, /* 70 */
0x1e, 0x21, 0x40, 0x40, 0x40, 0x47, 0x41, 0x21, 0x1e, // 71 0x1e, 0x21, 0x40, 0x40, 0x40, 0x47, 0x41, 0x21, 0x1e, /* 71 */
0x41, 0x41, 0x41, 0x41, 0x7f, 0x41, 0x41, 0x41, 0x41, // 72 0x41, 0x41, 0x41, 0x41, 0x7f, 0x41, 0x41, 0x41, 0x41, /* 72 */
0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, // 73 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, /* 73 */
0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x38, // 74 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x38, /* 74 */
0x41, 0x42, 0x44, 0x48, 0x70, 0x48, 0x44, 0x42, 0x41, // 75 0x41, 0x42, 0x44, 0x48, 0x70, 0x48, 0x44, 0x42, 0x41, /* 75 */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7f, // 76 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7f, /* 76 */
0x41, 0x63, 0x55, 0x49, 0x49, 0x41, 0x41, 0x41, 0x41, // 77 0x41, 0x63, 0x55, 0x49, 0x49, 0x41, 0x41, 0x41, 0x41, /* 77 */
0x41, 0x61, 0x51, 0x49, 0x45, 0x43, 0x41, 0x41, 0x41, // 78 0x41, 0x61, 0x51, 0x49, 0x45, 0x43, 0x41, 0x41, 0x41, /* 78 */
0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, // 79 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, /* 79 */
0x7e, 0x41, 0x41, 0x41, 0x7e, 0x40, 0x40, 0x40, 0x40, // 80 0x7e, 0x41, 0x41, 0x41, 0x7e, 0x40, 0x40, 0x40, 0x40, /* 80 */
0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x45, 0x22, 0x1d, // 81 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x45, 0x22, 0x1d, /* 81 */
0x7e, 0x41, 0x41, 0x41, 0x7e, 0x48, 0x44, 0x42, 0x41, // 82 0x7e, 0x41, 0x41, 0x41, 0x7e, 0x48, 0x44, 0x42, 0x41, /* 82 */
0x3e, 0x41, 0x40, 0x40, 0x3e, 0x01, 0x01, 0x41, 0x3e, // 83 0x3e, 0x41, 0x40, 0x40, 0x3e, 0x01, 0x01, 0x41, 0x3e, /* 83 */
0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // 84 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 84 */
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x3e, // 85 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x3e, /* 85 */
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x14, 0x08, // 86 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x14, 0x08, /* 86 */
0x41, 0x41, 0x41, 0x49, 0x49, 0x49, 0x55, 0x63, 0x41, // 87 0x41, 0x41, 0x41, 0x49, 0x49, 0x49, 0x55, 0x63, 0x41, /* 87 */
0x41, 0x41, 0x22, 0x14, 0x08, 0x14, 0x22, 0x41, 0x41, // 88 0x41, 0x41, 0x22, 0x14, 0x08, 0x14, 0x22, 0x41, 0x41, /* 88 */
0x41, 0x41, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, // 89 0x41, 0x41, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, /* 89 */
0x7f, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7f, // 90 0x7f, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7f, /* 90 */
0x1e, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1e, // 91 0x1e, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1e, /* 91 */
0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // 92 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, /* 92 */
0x3c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x3c, // 93 0x3c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x3c, /* 93 */
0x3e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 94 0x3e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 94 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, // 95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, /* 95 */
0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 96
0x00, 0x00, 0x00, 0x1e, 0x22, 0x42, 0x41, 0x46, 0x3a, // 97
0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x62, 0x5c, // 98
0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x42, 0x3c, // 99
0x02, 0x02, 0x02, 0x3a, 0x46, 0x42, 0x42, 0x46, 0x3a, // 100
0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x3e, // 101
0x0c, 0x12, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, // 102
0xba, 0x46, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x42, 0x3c, // 103
0x40, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, // 104
0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, // 105
0x82, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x3c, // 106
0x40, 0x40, 0x40, 0x44, 0x48, 0x70, 0x48, 0x44, 0x42, // 107
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 108
0x00, 0x00, 0x00, 0x76, 0x49, 0x49, 0x49, 0x49, 0x49, // 109
0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, // 110
0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, // 111
0xdc, 0x62, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 0x40, // 112 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 96 */
0xba, 0x46, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 0x02, // 113 0x00, 0x00, 0x00, 0x1e, 0x22, 0x42, 0x41, 0x46, 0x3a, /* 97 */
0x00, 0x00, 0x00, 0x5c, 0x62, 0x40, 0x40, 0x40, 0x40, // 114 0x40, 0x40, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x62, 0x5c, /* 98 */
0x00, 0x00, 0x00, 0x3c, 0x42, 0x30, 0x0c, 0x42, 0x3c, // 115 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x42, 0x3c, /* 99 */
0x00, 0x10, 0x10, 0x7c, 0x10, 0x01, 0x10, 0x12, 0x0c, // 116 0x02, 0x02, 0x02, 0x3a, 0x46, 0x42, 0x42, 0x46, 0x3a, /* 100 */
0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, // 117 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x3e, /* 101 */
0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x28, 0x10, // 118 0x0c, 0x12, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, /* 102 */
0x00, 0x00, 0x00, 0x41, 0x49, 0x49, 0x49, 0x49, 0x36, // 119 0xba, 0x46, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x42, 0x3c, /* 103 */
0x00, 0x00, 0x00, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, // 120 0x40, 0x40, 0x40, 0x58, 0x64, 0x42, 0x42, 0x42, 0x42, /* 104 */
0xc2, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x42, 0x3c, // 121 0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, /* 105 */
0x00, 0x00, 0x00, 0x7e, 0x04, 0x08, 0x10, 0x20, 0x7e, // 122 0x82, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x3c, /* 106 */
0x0e, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x0e, // 123 0x40, 0x40, 0x40, 0x44, 0x48, 0x70, 0x48, 0x44, 0x42, /* 107 */
0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, // 124 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, /* 108 */
0x38, 0x04, 0x04, 0x04, 0x02, 0x04, 0x04, 0x04, 0x38, // 125 0x00, 0x00, 0x00, 0x76, 0x49, 0x49, 0x49, 0x49, 0x49, /* 109 */
0x30, 0x49, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 126 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, /* 110 */
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f // 127 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, /* 111 */
0xdc, 0x62, 0x42, 0x42, 0x62, 0x5c, 0x40, 0x40, 0x40, /* 112 */
0xba, 0x46, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x02, 0x02, /* 113 */
0x00, 0x00, 0x00, 0x5c, 0x62, 0x40, 0x40, 0x40, 0x40, /* 114 */
0x00, 0x00, 0x00, 0x3c, 0x42, 0x30, 0x0c, 0x42, 0x3c, /* 115 */
0x00, 0x10, 0x10, 0x7c, 0x10, 0x01, 0x10, 0x12, 0x0c, /* 116 */
0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, /* 117 */
0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x28, 0x10, /* 118 */
0x00, 0x00, 0x00, 0x41, 0x49, 0x49, 0x49, 0x49, 0x36, /* 119 */
0x00, 0x00, 0x00, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, /* 120 */
0xc2, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x42, 0x3c, /* 121 */
0x00, 0x00, 0x00, 0x7e, 0x04, 0x08, 0x10, 0x20, 0x7e, /* 122 */
0x0e, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x0e, /* 123 */
0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, /* 124 */
0x38, 0x04, 0x04, 0x04, 0x02, 0x04, 0x04, 0x04, 0x38, /* 125 */
0x30, 0x49, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 126 */
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f /* 127 */
}; };
#endif #endif

View File

@@ -1,41 +1,41 @@
/* /*
This is the core graphics library for all our displays, providing a common * This is the core graphics library for all our displays, providing a common
set of graphics primitives (points, lines, circles, etc.). It needs to be * set of graphics primitives (points, lines, circles, etc.). It needs to be
paired with a hardware-specific library for each display device we carry * paired with a hardware-specific library for each display device we carry
(to handle the lower-level functions). * (to handle the lower-level functions).
*
Adafruit invests time and resources providing this open source code, please * Adafruit invests time and resources providing this open source code, please
support Adafruit & open-source hardware by purchasing products from Adafruit! * support Adafruit & open-source hardware by purchasing products from Adafruit!
*
Copyright (c) 2013 Adafruit Industries. All rights reserved. * Copyright (c) 2013 Adafruit Industries. All rights reserved.
*
Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
*
- Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Modified the AdaFruit library to be a C library, changed the font and * Modified the AdaFruit library to be a C library, changed the font and
* generally munged it in a variety of ways, creating a reasonably quick * generally munged it in a variety of ways, creating a reasonably quick
* and dirty way to put something "interesting" on the LCD display. * and dirty way to put something "interesting" on the LCD display.
* --Chuck McManis (2013, 2014) * --Chuck McManis (2013, 2014)
* *
*/ */
#include <stdint.h> #include <stdint.h>
#include <math.h> #include <math.h>
@@ -48,454 +48,497 @@ POSSIBILITY OF SUCH DAMAGE.
struct gfx_state __gfx_state; struct gfx_state __gfx_state;
void void
gfx_drawPixel(int x, int y, uint16_t color) { gfx_drawPixel(int x, int y, uint16_t color)
if ((x < 0) || (x >= __gfx_state._width) || {
(y < 0) || (y >= __gfx_state._height)) { if ((x < 0) || (x >= __gfx_state._width) ||
return; // off screen so don't draw it (y < 0) || (y >= __gfx_state._height)) {
} return; /* off screen so don't draw it */
(__gfx_state.drawpixel)(x, y, color); }
(__gfx_state.drawpixel)(x, y, color);
} }
#define true 1 #define true 1
void void
gfx_init(void (*pixel_func)(int, int, uint16_t), int width, int height) gfx_init(void (*pixel_func)(int, int, uint16_t), int width, int height)
{ {
__gfx_state._width = width; __gfx_state._width = width;
__gfx_state._height = height; __gfx_state._height = height;
__gfx_state.rotation = 0; __gfx_state.rotation = 0;
__gfx_state.cursor_y = __gfx_state.cursor_x = 0; __gfx_state.cursor_y = __gfx_state.cursor_x = 0;
__gfx_state.textsize = 1; __gfx_state.textsize = 1;
__gfx_state.textcolor = 0; __gfx_state.textcolor = 0;
__gfx_state.textbgcolor = 0xFFFF; __gfx_state.textbgcolor = 0xFFFF;
__gfx_state.wrap = true; __gfx_state.wrap = true;
__gfx_state.drawpixel = pixel_func; __gfx_state.drawpixel = pixel_func;
} }
// Draw a circle outline /* Draw a circle outline */
void gfx_drawCircle(int16_t x0, int16_t y0, int16_t r, void gfx_drawCircle(int16_t x0, int16_t y0, int16_t r,
uint16_t color) { uint16_t color)
int16_t f = 1 - r; {
int16_t ddF_x = 1; int16_t f = 1 - r;
int16_t ddF_y = -2 * r; int16_t ddF_x = 1;
int16_t x = 0; int16_t ddF_y = -2 * r;
int16_t y = r; int16_t x = 0;
int16_t y = r;
gfx_drawPixel(x0 , y0+r, color); gfx_drawPixel(x0 , y0+r, color);
gfx_drawPixel(x0 , y0-r, color); gfx_drawPixel(x0 , y0-r, color);
gfx_drawPixel(x0+r, y0 , color); gfx_drawPixel(x0+r, y0 , color);
gfx_drawPixel(x0-r, y0 , color); gfx_drawPixel(x0-r, y0 , color);
while (x<y) { while (x < y) {
if (f >= 0) { if (f >= 0) {
y--; y--;
ddF_y += 2; ddF_y += 2;
f += ddF_y; f += ddF_y;
} }
x++; x++;
ddF_x += 2; ddF_x += 2;
f += ddF_x; f += ddF_x;
gfx_drawPixel(x0 + x, y0 + y, color); gfx_drawPixel(x0 + x, y0 + y, color);
gfx_drawPixel(x0 - x, y0 + y, color); gfx_drawPixel(x0 - x, y0 + y, color);
gfx_drawPixel(x0 + x, y0 - y, color); gfx_drawPixel(x0 + x, y0 - y, color);
gfx_drawPixel(x0 - x, y0 - y, color); gfx_drawPixel(x0 - x, y0 - y, color);
gfx_drawPixel(x0 + y, y0 + x, color); gfx_drawPixel(x0 + y, y0 + x, color);
gfx_drawPixel(x0 - y, y0 + x, color); gfx_drawPixel(x0 - y, y0 + x, color);
gfx_drawPixel(x0 + y, y0 - x, color); gfx_drawPixel(x0 + y, y0 - x, color);
gfx_drawPixel(x0 - y, y0 - x, color); gfx_drawPixel(x0 - y, y0 - x, color);
} }
} }
void gfx_drawCircleHelper( int16_t x0, int16_t y0, void gfx_drawCircleHelper(int16_t x0, int16_t y0,
int16_t r, uint8_t cornername, uint16_t color) { int16_t r, uint8_t cornername, uint16_t color)
int16_t f = 1 - r; {
int16_t ddF_x = 1; int16_t f = 1 - r;
int16_t ddF_y = -2 * r; int16_t ddF_x = 1;
int16_t x = 0; int16_t ddF_y = -2 * r;
int16_t y = r; int16_t x = 0;
int16_t y = r;
while (x<y) { while (x < y) {
if (f >= 0) { if (f >= 0) {
y--; y--;
ddF_y += 2; ddF_y += 2;
f += ddF_y; f += ddF_y;
} }
x++; x++;
ddF_x += 2; ddF_x += 2;
f += ddF_x; f += ddF_x;
if (cornername & 0x4) { if (cornername & 0x4) {
gfx_drawPixel(x0 + x, y0 + y, color); gfx_drawPixel(x0 + x, y0 + y, color);
gfx_drawPixel(x0 + y, y0 + x, color); gfx_drawPixel(x0 + y, y0 + x, color);
} }
if (cornername & 0x2) { if (cornername & 0x2) {
gfx_drawPixel(x0 + x, y0 - y, color); gfx_drawPixel(x0 + x, y0 - y, color);
gfx_drawPixel(x0 + y, y0 - x, color); gfx_drawPixel(x0 + y, y0 - x, color);
} }
if (cornername & 0x8) { if (cornername & 0x8) {
gfx_drawPixel(x0 - y, y0 + x, color); gfx_drawPixel(x0 - y, y0 + x, color);
gfx_drawPixel(x0 - x, y0 + y, color); gfx_drawPixel(x0 - x, y0 + y, color);
} }
if (cornername & 0x1) { if (cornername & 0x1) {
gfx_drawPixel(x0 - y, y0 - x, color); gfx_drawPixel(x0 - y, y0 - x, color);
gfx_drawPixel(x0 - x, y0 - y, color); gfx_drawPixel(x0 - x, y0 - y, color);
} }
} }
} }
void gfx_fillCircle(int16_t x0, int16_t y0, int16_t r, void gfx_fillCircle(int16_t x0, int16_t y0, int16_t r,
uint16_t color) { uint16_t color)
gfx_drawFastVLine(x0, y0-r, 2*r+1, color); {
gfx_fillCircleHelper(x0, y0, r, 3, 0, color); gfx_drawFastVLine(x0, y0 - r, 2*r+1, color);
gfx_fillCircleHelper(x0, y0, r, 3, 0, color);
} }
// Used to do circles and roundrects /* Used to do circles and roundrects */
void gfx_fillCircleHelper(int16_t x0, int16_t y0, int16_t r, void gfx_fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
uint8_t cornername, int16_t delta, uint16_t color) { uint8_t cornername, int16_t delta, uint16_t color)
{
int16_t f = 1 - r;
int16_t ddF_x = 1;
int16_t ddF_y = -2 * r;
int16_t x = 0;
int16_t y = r;
int16_t f = 1 - r; while (x < y) {
int16_t ddF_x = 1; if (f >= 0) {
int16_t ddF_y = -2 * r; y--;
int16_t x = 0; ddF_y += 2;
int16_t y = r; f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
while (x<y) { if (cornername & 0x1) {
if (f >= 0) { gfx_drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
y--; gfx_drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
ddF_y += 2; }
f += ddF_y; if (cornername & 0x2) {
} gfx_drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
x++; gfx_drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
ddF_x += 2; }
f += ddF_x; }
if (cornername & 0x1) {
gfx_drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
gfx_drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
}
if (cornername & 0x2) {
gfx_drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
gfx_drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
}
}
} }
// Bresenham's algorithm - thx wikpedia /* Bresenham's algorithm - thx wikpedia */
void gfx_drawLine(int16_t x0, int16_t y0, void gfx_drawLine(int16_t x0, int16_t y0,
int16_t x1, int16_t y1, int16_t x1, int16_t y1,
uint16_t color) { uint16_t color)
int16_t steep = abs(y1 - y0) > abs(x1 - x0); {
if (steep) { int16_t steep = abs(y1 - y0) > abs(x1 - x0);
swap(x0, y0); if (steep) {
swap(x1, y1); swap(x0, y0);
} swap(x1, y1);
}
if (x0 > x1) { if (x0 > x1) {
swap(x0, x1); swap(x0, x1);
swap(y0, y1); swap(y0, y1);
} }
int16_t dx, dy; int16_t dx, dy;
dx = x1 - x0; dx = x1 - x0;
dy = abs(y1 - y0); dy = abs(y1 - y0);
int16_t err = dx / 2; int16_t err = dx / 2;
int16_t ystep; int16_t ystep;
if (y0 < y1) { if (y0 < y1) {
ystep = 1; ystep = 1;
} else { } else {
ystep = -1; ystep = -1;
} }
for (; x0<=x1; x0++) { for (; x0 <= x1; x0++) {
if (steep) { if (steep) {
gfx_drawPixel(y0, x0, color); gfx_drawPixel(y0, x0, color);
} else { } else {
gfx_drawPixel(x0, y0, color); gfx_drawPixel(x0, y0, color);
} }
err -= dy; err -= dy;
if (err < 0) { if (err < 0) {
y0 += ystep; y0 += ystep;
err += dx; err += dx;
} }
} }
} }
// Draw a rectangle /* Draw a rectangle */
void gfx_drawRect(int16_t x, int16_t y, void gfx_drawRect(int16_t x, int16_t y,
int16_t w, int16_t h, int16_t w, int16_t h,
uint16_t color) { uint16_t color)
gfx_drawFastHLine(x, y, w, color); {
gfx_drawFastHLine(x, y+h-1, w, color); gfx_drawFastHLine(x, y, w, color);
gfx_drawFastVLine(x, y, h, color); gfx_drawFastHLine(x, y + h - 1, w, color);
gfx_drawFastVLine(x+w-1, y, h, color); gfx_drawFastVLine(x, y, h, color);
gfx_drawFastVLine(x + w - 1, y, h, color);
} }
void gfx_drawFastVLine(int16_t x, int16_t y, void gfx_drawFastVLine(int16_t x, int16_t y,
int16_t h, uint16_t color) { int16_t h, uint16_t color)
// Update in subclasses if desired! {
gfx_drawLine(x, y, x, y+h-1, color); /* Update in subclasses if desired! */
gfx_drawLine(x, y, x, y + h - 1, color);
} }
void gfx_drawFastHLine(int16_t x, int16_t y, void gfx_drawFastHLine(int16_t x, int16_t y,
int16_t w, uint16_t color) { int16_t w, uint16_t color)
// Update in subclasses if desired! {
gfx_drawLine(x, y, x+w-1, y, color); /* Update in subclasses if desired! */
gfx_drawLine(x, y, x + w - 1, y, color);
} }
void gfx_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, void gfx_fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
uint16_t color) { uint16_t color)
// Update in subclasses if desired! {
int16_t i; /* Update in subclasses if desired! */
for (i=x; i<x+w; i++) { int16_t i;
gfx_drawFastVLine(i, y, h, color); for (i = x; i < x + w; i++) {
} gfx_drawFastVLine(i, y, h, color);
}
} }
void gfx_fillScreen(uint16_t color) { void gfx_fillScreen(uint16_t color)
gfx_fillRect(0, 0, __gfx_state._width, __gfx_state._height, color); {
gfx_fillRect(0, 0, __gfx_state._width, __gfx_state._height, color);
} }
// Draw a rounded rectangle /* Draw a rounded rectangle */
void gfx_drawRoundRect(int16_t x, int16_t y, int16_t w, void gfx_drawRoundRect(int16_t x, int16_t y, int16_t w,
int16_t h, int16_t r, uint16_t color) { int16_t h, int16_t r, uint16_t color)
// smarter version {
gfx_drawFastHLine(x+r , y , w-2*r, color); // Top /* smarter version */
gfx_drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom gfx_drawFastHLine(x + r , y , w - 2 * r, color); /* Top */
gfx_drawFastVLine(x , y+r , h-2*r, color); // Left gfx_drawFastHLine(x + r , y + h - 1, w - 2 * r, color); /* Bottom */
gfx_drawFastVLine(x+w-1, y+r , h-2*r, color); // Right gfx_drawFastVLine(x , y + r , h - 2 * r, color); /* Left */
// draw four corners gfx_drawFastVLine(x + w - 1, y + r , h - 2 * r, color); /* Right */
gfx_drawCircleHelper(x+r , y+r , r, 1, color); /* draw four corners */
gfx_drawCircleHelper(x+w-r-1, y+r , r, 2, color); gfx_drawCircleHelper(x + r , y + r , r, 1, color);
gfx_drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); gfx_drawCircleHelper(x + w - r - 1, y + r , r, 2, color);
gfx_drawCircleHelper(x+r , y+h-r-1, r, 8, color); gfx_drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4, color);
gfx_drawCircleHelper(x + r , y + h - r - 1, r, 8, color);
} }
// Fill a rounded rectangle /* Fill a rounded rectangle */
void gfx_fillRoundRect(int16_t x, int16_t y, int16_t w, void gfx_fillRoundRect(int16_t x, int16_t y, int16_t w,
int16_t h, int16_t r, uint16_t color) { int16_t h, int16_t r, uint16_t color) {
// smarter version /* smarter version */
gfx_fillRect(x+r, y, w-2*r, h, color); gfx_fillRect(x + r, y, w - 2 * r, h, color);
// draw four corners /* draw four corners */
gfx_fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); gfx_fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color);
gfx_fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); gfx_fillCircleHelper(x + r , y + r, r, 2, h - 2 * r - 1, color);
} }
// Draw a triangle /* Draw a triangle */
void gfx_drawTriangle(int16_t x0, int16_t y0, void gfx_drawTriangle(int16_t x0, int16_t y0,
int16_t x1, int16_t y1, int16_t x1, int16_t y1,
int16_t x2, int16_t y2, uint16_t color) { int16_t x2, int16_t y2, uint16_t color)
gfx_drawLine(x0, y0, x1, y1, color); {
gfx_drawLine(x1, y1, x2, y2, color); gfx_drawLine(x0, y0, x1, y1, color);
gfx_drawLine(x2, y2, x0, y0, color); gfx_drawLine(x1, y1, x2, y2, color);
gfx_drawLine(x2, y2, x0, y0, color);
} }
// Fill a triangle /* Fill a triangle */
void gfx_fillTriangle ( int16_t x0, int16_t y0, void gfx_fillTriangle(int16_t x0, int16_t y0,
int16_t x1, int16_t y1, int16_t x1, int16_t y1,
int16_t x2, int16_t y2, uint16_t color) { int16_t x2, int16_t y2, uint16_t color)
{
int16_t a, b, y, last;
int16_t a, b, y, last; /* Sort coordinates by Y order (y2 >= y1 >= y0) */
if (y0 > y1) {
swap(y0, y1); swap(x0, x1);
}
if (y1 > y2) {
swap(y2, y1); swap(x2, x1);
}
if (y0 > y1) {
swap(y0, y1); swap(x0, x1);
}
// Sort coordinates by Y order (y2 >= y1 >= y0) /* Handle awkward all-on-same-line case as its own thing */
if (y0 > y1) { if (y0 == y2) {
swap(y0, y1); swap(x0, x1); a = b = x0;
} if (x1 < a) {
if (y1 > y2) { a = x1;
swap(y2, y1); swap(x2, x1); } else if (x1 > b) {
} b = x1;
if (y0 > y1) { }
swap(y0, y1); swap(x0, x1); if (x2 < a) {
} a = x2;
} else if (x2 > b) {
b = x2;
}
gfx_drawFastHLine(a, y0, b - a + 1, color);
return;
}
if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing int16_t
a = b = x0; dx01 = x1 - x0,
if(x1 < a) a = x1; dy01 = y1 - y0,
else if(x1 > b) b = x1; dx02 = x2 - x0,
if(x2 < a) a = x2; dy02 = y2 - y0,
else if(x2 > b) b = x2; dx12 = x2 - x1,
gfx_drawFastHLine(a, y0, b-a+1, color); dy12 = y2 - y1,
return; sa = 0,
} sb = 0;
int16_t /* For upper part of triangle, find scanline crossings for segments
dx01 = x1 - x0, * 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
dy01 = y1 - y0, * is included here (and second loop will be skipped, avoiding a /0
dx02 = x2 - x0, * error there), otherwise scanline y1 is skipped here and handled
dy02 = y2 - y0, * in the second loop...which also avoids a /0 error here if y0=y1
dx12 = x2 - x1, * (flat-topped triangle).
dy12 = y2 - y1, */
sa = 0, if (y1 == y2) {
sb = 0; last = y1; /* Include y1 scanline */
} else {
last = y1 - 1; /* Skip it */
}
// For upper part of triangle, find scanline crossings for segments for (y = y0; y <= last; y++) {
// 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 a = x0 + sa / dy01;
// is included here (and second loop will be skipped, avoiding a /0 b = x0 + sb / dy02;
// error there), otherwise scanline y1 is skipped here and handled sa += dx01;
// in the second loop...which also avoids a /0 error here if y0=y1 sb += dx02;
// (flat-topped triangle). /* longhand:
if(y1 == y2) last = y1; // Include y1 scanline a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
else last = y1-1; // Skip it b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
if (a > b) {
swap(a, b);
}
gfx_drawFastHLine(a, y, b - a + 1, color);
}
for(y=y0; y<=last; y++) { /* For lower part of triangle, find scanline crossings for segments
a = x0 + sa / dy01; * 0-2 and 1-2. This loop is skipped if y1=y2.
b = x0 + sb / dy02; */
sa += dx01; sa = dx12 * (y - y1);
sb += dx02; sb = dx02 * (y - y0);
/* longhand: for (; y <= y2; y++) {
a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); a = x1 + sa / dy12;
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); b = x0 + sb / dy02;
*/ sa += dx12;
if(a > b) swap(a,b); sb += dx02;
gfx_drawFastHLine(a, y, b-a+1, color); /* longhand:
} a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
// For lower part of triangle, find scanline crossings for segments */
// 0-2 and 1-2. This loop is skipped if y1=y2. if (a > b) {
sa = dx12 * (y - y1); swap(a, b);
sb = dx02 * (y - y0); }
for(; y<=y2; y++) { gfx_drawFastHLine(a, y, b - a + 1, color);
a = x1 + sa / dy12; }
b = x0 + sb / dy02;
sa += dx12;
sb += dx02;
/* longhand:
a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
if(a > b) swap(a,b);
gfx_drawFastHLine(a, y, b-a+1, color);
}
} }
void gfx_drawBitmap(int16_t x, int16_t y, void gfx_drawBitmap(int16_t x, int16_t y,
const uint8_t *bitmap, int16_t w, int16_t h, const uint8_t *bitmap, int16_t w, int16_t h,
uint16_t color) { uint16_t color)
{
int16_t i, j, byteWidth = (w + 7) / 8;
int16_t i, j, byteWidth = (w + 7) / 8; for (j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
for(j=0; j<h; j++) { if (pgm_read_byte(bitmap + j * byteWidth + i / 8) &
for(i=0; i<w; i++ ) { (128 >> (i & 7))) {
if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { gfx_drawPixel(x + i, y + j, color);
gfx_drawPixel(x+i, y+j, color); }
} }
} }
}
} }
void gfx_write(uint8_t c) { void gfx_write(uint8_t c)
if (c == '\n') { {
__gfx_state.cursor_y += __gfx_state.textsize*12; if (c == '\n') {
__gfx_state.cursor_x = 0; __gfx_state.cursor_y += __gfx_state.textsize * 12;
} else if (c == '\r') { __gfx_state.cursor_x = 0;
// skip em } else if (c == '\r') {
} else { /* skip em */
gfx_drawChar(__gfx_state.cursor_x, __gfx_state.cursor_y, } else {
c, __gfx_state.textcolor, __gfx_state.textbgcolor, gfx_drawChar(__gfx_state.cursor_x, __gfx_state.cursor_y,
__gfx_state.textsize); c, __gfx_state.textcolor, __gfx_state.textbgcolor,
__gfx_state.cursor_x += __gfx_state.textsize*8; __gfx_state.textsize);
if (__gfx_state.wrap && (__gfx_state.cursor_x > (__gfx_state._width - __gfx_state.textsize*8))) { __gfx_state.cursor_x += __gfx_state.textsize * 8;
__gfx_state.cursor_y += __gfx_state.textsize*12; if (__gfx_state.wrap &&
__gfx_state.cursor_x = 0; (__gfx_state.cursor_x > (__gfx_state._width -
} __gfx_state.textsize*8))) {
} __gfx_state.cursor_y += __gfx_state.textsize * 12;
__gfx_state.cursor_x = 0;
}
}
} }
void gfx_puts(char *s) { void gfx_puts(char *s)
while (*s) { {
gfx_write(*s); while (*s) {
s++; gfx_write(*s);
} s++;
}
} }
// Draw a character /* Draw a character */
void gfx_drawChar(int16_t x, int16_t y, unsigned char c, void gfx_drawChar(int16_t x, int16_t y, unsigned char c,
uint16_t color, uint16_t bg, uint8_t size) { uint16_t color, uint16_t bg, uint8_t size)
{
int8_t i, j, line;
int8_t descender;
unsigned const char *glyph;
int8_t i, j, line; glyph = &mcm_font[(c & 0x7f) * 9];
int8_t descender;
unsigned const char *glyph;
glyph = &mcm_font[(c & 0x7f) * 9]; descender = (*glyph & 0x80) != 0;
descender = (*glyph & 0x80) != 0; for (i = 0; i < 12; i++) {
line = 0x00;
for (i=0; i<12; i++ ) { if (descender) {
line = 0x00; if (i > 2) {
if ( descender ) { line = *(glyph + (i - 3));
if (i > 2) { }
line = *(glyph + (i - 3)); } else {
} if (i < 9) {
} else { line = *(glyph + i);
if (i < 9) { }
line = *(glyph + i); }
} line &= 0x7f;
} for (j = 0; j < 8; j++) {
line &= 0x7f; if (line & 0x80) {
for (j = 0; j<8; j++) { if (size == 1) /* default size */
if (line & 0x80) { gfx_drawPixel(x+j, y+i, color);
if (size == 1) // default size else { /* big size */
gfx_drawPixel(x+j, y+i, color); gfx_fillRect(x+(j*size), y+(i*size),
else { // big size size, size, color);
gfx_fillRect(x+(j*size), y+(i*size), size, size, color); }
} } else if (bg != color) {
} else if (bg != color) { if (size == 1) /* default size */
if (size == 1) // default size gfx_drawPixel(x+j, y+i, bg);
gfx_drawPixel(x+j, y+i, bg); else { /* big size */
else { // big size gfx_fillRect(x+j*size, y+i*size,
gfx_fillRect(x+j*size, y+i*size, size, size, bg); size, size, bg);
} }
} }
line <<= 1; line <<= 1;
} }
} }
} }
void gfx_setCursor(int16_t x, int16_t y) { void gfx_setCursor(int16_t x, int16_t y)
__gfx_state.cursor_x = x; {
__gfx_state.cursor_y = y; __gfx_state.cursor_x = x;
__gfx_state.cursor_y = y;
} }
void gfx_setTextSize(uint8_t s) { void gfx_setTextSize(uint8_t s)
__gfx_state.textsize = (s > 0) ? s : 1; {
__gfx_state.textsize = (s > 0) ? s : 1;
} }
void gfx_setTextColor(uint16_t c, uint16_t b) { void gfx_setTextColor(uint16_t c, uint16_t b)
__gfx_state.textcolor = c; {
__gfx_state.textbgcolor = b; __gfx_state.textcolor = c;
__gfx_state.textbgcolor = b;
} }
void gfx_setTextWrap(uint8_t w) { void gfx_setTextWrap(uint8_t w)
__gfx_state.wrap = w; {
__gfx_state.wrap = w;
} }
uint8_t gfx_getRotation(void) { uint8_t gfx_getRotation(void)
return __gfx_state.rotation; {
return __gfx_state.rotation;
} }
void gfx_setRotation(uint8_t x) { void gfx_setRotation(uint8_t x)
__gfx_state.rotation = (x & 3); {
switch(__gfx_state.rotation) { __gfx_state.rotation = (x & 3);
case 0: switch (__gfx_state.rotation) {
case 2: case 0:
__gfx_state._width = GFX_WIDTH; case 2:
__gfx_state._height = GFX_HEIGHT; __gfx_state._width = GFX_WIDTH;
break; __gfx_state._height = GFX_HEIGHT;
case 1: break;
case 3: case 1:
__gfx_state._width = GFX_HEIGHT; case 3:
__gfx_state._height = GFX_WIDTH; __gfx_state._width = GFX_HEIGHT;
break; __gfx_state._height = GFX_WIDTH;
} break;
}
} }
// Return the size of the display (per current rotation) /* Return the size of the display (per current rotation) */
uint16_t gfx_width(void) { uint16_t gfx_width(void)
return __gfx_state._width; {
} return __gfx_state._width;
}
uint16_t gfx_height(void) {
return __gfx_state._height; uint16_t gfx_height(void)
{
return __gfx_state._height;
} }

View File

@@ -1,4 +1,4 @@
/* /*
* A simple port of the AdaFruit minimal graphics code to my * A simple port of the AdaFruit minimal graphics code to my
* demo code. * demo code.
*/ */
@@ -9,7 +9,8 @@
#define swap(a, b) { int16_t t = a; a = b; b = t; } #define swap(a, b) { int16_t t = a; a = b; b = t; }
void gfx_drawPixel(int x, int y, uint16_t color); void gfx_drawPixel(int x, int y, uint16_t color);
void gfx_drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color); void gfx_drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
uint16_t color);
void gfx_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); void gfx_drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void gfx_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); void gfx_drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
void gfx_drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); void gfx_drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
@@ -17,25 +18,25 @@ void gfx_fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void gfx_fillScreen(uint16_t color); void gfx_fillScreen(uint16_t color);
void gfx_drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color); void gfx_drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
void gfx_drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, void gfx_drawCircleHelper(int16_t x0, int16_t y0, int16_t r,
uint16_t color); uint8_t cornername, uint16_t color);
void gfx_fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color); void gfx_fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
void gfx_init(void (*draw)(int, int, uint16_t), int, int); void gfx_init(void (*draw)(int, int, uint16_t), int, int);
void gfx_fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, void gfx_fillCircleHelper(int16_t x0, int16_t y0, int16_t r,
int16_t delta, uint16_t color); uint8_t cornername, int16_t delta, uint16_t color);
void gfx_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, void gfx_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
int16_t x2, int16_t y2, uint16_t color); int16_t x2, int16_t y2, uint16_t color);
void gfx_fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, void gfx_fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
int16_t x2, int16_t y2, uint16_t color); int16_t x2, int16_t y2, uint16_t color);
void gfx_drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, void gfx_drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,
int16_t radius, uint16_t color); int16_t radius, uint16_t color);
void gfx_fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, void gfx_fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,
int16_t radius, uint16_t color); int16_t radius, uint16_t color);
void gfx_drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, void gfx_drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap,
int16_t w, int16_t h, uint16_t color); int16_t w, int16_t h, uint16_t color);
void gfx_drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, void gfx_drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color,
uint16_t bg, uint8_t size); uint16_t bg, uint8_t size);
void gfx_setCursor(int16_t x, int16_t y); void gfx_setCursor(int16_t x, int16_t y);
void gfx_setTextColor(uint16_t c, uint16_t bg); void gfx_setTextColor(uint16_t c, uint16_t bg);
void gfx_setTextSize(uint8_t s); void gfx_setTextSize(uint8_t s);
@@ -53,11 +54,11 @@ uint8_t gfx_getRotation(void);
#define GFX_HEIGHT 240 #define GFX_HEIGHT 240
struct gfx_state { struct gfx_state {
int16_t _width, _height, cursor_x, cursor_y; int16_t _width, _height, cursor_x, cursor_y;
uint16_t textcolor, textbgcolor; uint16_t textcolor, textbgcolor;
uint8_t textsize, rotation; uint8_t textsize, rotation;
uint8_t wrap; uint8_t wrap;
void (*drawpixel)(int, int, uint16_t); void (*drawpixel)(int, int, uint16_t);
}; };
extern struct gfx_state __gfx_state; extern struct gfx_state __gfx_state;
@@ -73,4 +74,4 @@ extern struct gfx_state __gfx_state;
#define GFX_COLOR_CYAN 0x7FFF #define GFX_COLOR_CYAN 0x7FFF
#define GFX_COLOR_YELLOW 0xFFE0 #define GFX_COLOR_YELLOW 0xFFE0
#endif // _ADAFRUIT_GFX_H #endif /* _ADAFRUIT_GFX_H */

View File

@@ -32,7 +32,8 @@
* This is our example, the heavy lifing is actually in lcd-spi.c but * This is our example, the heavy lifing is actually in lcd-spi.c but
* this drives that code. * this drives that code.
*/ */
int main(void) { int main(void)
{
int p1, p2, p3; int p1, p2, p3;
clock_setup(); clock_setup();
@@ -42,7 +43,7 @@ int main(void) {
console_puts("LCD Initialized\n"); console_puts("LCD Initialized\n");
console_puts("Should have a checker pattern, press any key to proceed\n"); console_puts("Should have a checker pattern, press any key to proceed\n");
msleep(2000); msleep(2000);
// (void) console_getc(1); /* (void) console_getc(1); */
gfx_init(lcd_draw_pixel, 240, 320); gfx_init(lcd_draw_pixel, 240, 320);
gfx_fillScreen(LCD_GREY); gfx_fillScreen(LCD_GREY);
gfx_fillRoundRect(10, 10, 220, 220, 5, LCD_WHITE); gfx_fillRoundRect(10, 10, 220, 220, 5, LCD_WHITE);
@@ -62,7 +63,7 @@ int main(void) {
console_puts("Now it has a bit of structured graphics.\n"); console_puts("Now it has a bit of structured graphics.\n");
console_puts("Press a key for some simple animation.\n"); console_puts("Press a key for some simple animation.\n");
msleep(2000); msleep(2000);
// (void) console_getc(1); /* (void) console_getc(1); */
gfx_setTextColor(LCD_YELLOW, LCD_BLACK); gfx_setTextColor(LCD_YELLOW, LCD_BLACK);
gfx_setTextSize(3); gfx_setTextSize(3);
p1 = 0; p1 = 0;
@@ -72,17 +73,17 @@ int main(void) {
gfx_fillScreen(LCD_BLACK); gfx_fillScreen(LCD_BLACK);
gfx_setCursor(15, 36); gfx_setCursor(15, 36);
gfx_puts("PLANETS!"); gfx_puts("PLANETS!");
gfx_fillCircle( 120, 160, 40, LCD_YELLOW); gfx_fillCircle(120, 160, 40, LCD_YELLOW);
gfx_drawCircle( 120, 160, 55, LCD_GREY); gfx_drawCircle(120, 160, 55, LCD_GREY);
gfx_drawCircle( 120, 160, 75, LCD_GREY); gfx_drawCircle(120, 160, 75, LCD_GREY);
gfx_drawCircle( 120, 160, 100, LCD_GREY); gfx_drawCircle(120, 160, 100, LCD_GREY);
gfx_fillCircle( 120 + (sin(d2r(p1)) * 55), gfx_fillCircle(120 + (sin(d2r(p1)) * 55),
160 + (cos(d2r(p1)) * 55), 5, LCD_RED); 160 + (cos(d2r(p1)) * 55), 5, LCD_RED);
gfx_fillCircle( 120 + (sin(d2r(p2)) * 75), gfx_fillCircle(120 + (sin(d2r(p2)) * 75),
160 + (cos(d2r(p2)) * 75), 10, LCD_WHITE); 160 + (cos(d2r(p2)) * 75), 10, LCD_WHITE);
gfx_fillCircle( 120 + (sin(d2r(p3)) * 100), gfx_fillCircle(120 + (sin(d2r(p3)) * 100),
160 + (cos(d2r(p3)) * 100), 8, LCD_BLUE); 160 + (cos(d2r(p3)) * 100), 8, LCD_BLUE);
p1 = (p1 + 3) % 360; p1 = (p1 + 3) % 360;
p2 = (p2 + 2) % 360; p2 = (p2 + 2) % 360;
p3 = (p3 + 1) % 360; p3 = (p3 + 1) % 360;

View File

@@ -48,8 +48,9 @@ uint16_t *display_frame;
* of the word to store, and puts in the value we pass to it. * of the word to store, and puts in the value we pass to it.
*/ */
void void
lcd_draw_pixel(int x, int y, uint16_t color) { lcd_draw_pixel(int x, int y, uint16_t color)
*(cur_frame + x + y * LCD_WIDTH) = color; {
*(cur_frame + x + y * LCD_WIDTH) = color;
} }
/* /*
@@ -72,9 +73,9 @@ lcd_draw_pixel(int x, int y, uint16_t color) {
* initialization sequence for the display. * initialization sequence for the display.
*/ */
struct tft_command { struct tft_command {
uint16_t delay; // If you need a delay after uint16_t delay; /* If you need a delay after */
uint8_t cmd; // command to send uint8_t cmd; /* command to send */
uint8_t n_args; // How many arguments it has uint8_t n_args; /* How many arguments it has */
}; };
@@ -90,21 +91,22 @@ static void lcd_command(uint8_t cmd, int delay, int n_args,
* sends those along too. * sends those along too.
*/ */
static void static void
lcd_command(uint8_t cmd, int delay, int n_args, const uint8_t *args) { lcd_command(uint8_t cmd, int delay, int n_args, const uint8_t *args)
{
int i; int i;
gpio_clear(GPIOC, GPIO2); // Select the LCD gpio_clear(GPIOC, GPIO2); /* Select the LCD */
(void) spi_xfer(LCD_SPI, cmd); (void) spi_xfer(LCD_SPI, cmd);
if (n_args) { if (n_args) {
gpio_set(GPIOD, GPIO13); // Set the D/CX pin gpio_set(GPIOD, GPIO13); /* Set the D/CX pin */
for (i = 0; i < n_args; i++) { for (i = 0; i < n_args; i++) {
(void) spi_xfer(LCD_SPI, *(args+i)); (void) spi_xfer(LCD_SPI, *(args+i));
} }
} }
gpio_set(GPIOC, GPIO2); // Turn off chip select gpio_set(GPIOC, GPIO2); /* Turn off chip select */
gpio_clear(GPIOD, GPIO13); // always reset D/CX gpio_clear(GPIOD, GPIO13); /* always reset D/CX */
if (delay) { if (delay) {
msleep(delay); // wait, if called for msleep(delay); /* wait, if called for */
} }
} }
@@ -122,16 +124,16 @@ static const uint8_t cmd_args[] = {
0x10, 0x10,
0x45, 0x15, 0x45, 0x15,
0x90, 0x90,
// 0xc8, // original /* 0xc8,*/ /* original */
// 11001000 = MY, MX, BGR /* 11001000 = MY, MX, BGR */
0x08, 0x08,
0xc2, 0xc2,
0x55, 0x55,
0x0a, 0xa7, 0x27, 0x04, 0x0a, 0xa7, 0x27, 0x04,
0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0xef,
0x00, 0x00, 0x01, 0x3f, 0x00, 0x00, 0x01, 0x3f,
// 0x01, 0x00, 0x06, // original /* 0x01, 0x00, 0x06,*/ /* original */
0x01, 0x00, 0x00, // modified to remove RGB mode 0x01, 0x00, 0x00, /* modified to remove RGB mode */
0x01, 0x01,
0x0F, 0x29, 0x24, 0x0C, 0x0E, 0x0F, 0x29, 0x24, 0x0C, 0x0E,
0x09, 0x4E, 0x78, 0x3C, 0x09, 0x09, 0x4E, 0x78, 0x3C, 0x09,
@@ -152,30 +154,30 @@ static const uint8_t cmd_args[] = {
* code, the data sheet, and other sources on the web. * code, the data sheet, and other sources on the web.
*/ */
const struct tft_command initialization[] = { const struct tft_command initialization[] = {
{ 0, 0xb1, 2 }, // 0x00, 0x1B, { 0, 0xb1, 2 }, /* 0x00, 0x1B, */
{ 0, 0xb6, 2 }, // 0x0a, 0xa2, { 0, 0xb6, 2 }, /* 0x0a, 0xa2, */
{ 0, 0xc0, 1 }, // 0x10, { 0, 0xc0, 1 }, /* 0x10, */
{ 0, 0xc1, 1 }, // 0x10, { 0, 0xc1, 1 }, /* 0x10, */
{ 0, 0xc5, 2 }, // 0x45, 0x15, { 0, 0xc5, 2 }, /* 0x45, 0x15, */
{ 0, 0xc7, 1 }, // 0x90, { 0, 0xc7, 1 }, /* 0x90, */
{ 0, 0x36, 1 }, // 0xc8, { 0, 0x36, 1 }, /* 0xc8, */
{ 0, 0xb0, 1 }, // 0xc2, { 0, 0xb0, 1 }, /* 0xc2, */
{ 0, 0x3a, 1 }, // 0x55 **added, pixel format 16 bpp { 0, 0x3a, 1 }, /* 0x55 **added, pixel format 16 bpp */
{ 0, 0xb6, 4 }, // 0x0a, 0xa7, 0x27, 0x04, { 0, 0xb6, 4 }, /* 0x0a, 0xa7, 0x27, 0x04, */
{ 0, 0x2A, 4 }, // 0x00, 0x00, 0x00, 0xef, { 0, 0x2A, 4 }, /* 0x00, 0x00, 0x00, 0xef, */
{ 0, 0x2B, 4 }, // 0x00, 0x00, 0x01, 0x3f, { 0, 0x2B, 4 }, /* 0x00, 0x00, 0x01, 0x3f, */
{ 0, 0xf6, 3 }, // 0x01, 0x00, 0x06, { 0, 0xf6, 3 }, /* 0x01, 0x00, 0x06, */
{ 200, 0x2c, 0 }, { 200, 0x2c, 0 },
{ 0, 0x26, 1}, // 0x01, { 0, 0x26, 1}, /* 0x01, */
{ 0, 0xe0, 15 }, // 0x0F, 0x29, 0x24, 0x0C, 0x0E, { 0, 0xe0, 15 }, /* 0x0F, 0x29, 0x24, 0x0C, 0x0E, */
// 0x09, 0x4E, 0x78, 0x3C, 0x09, /* 0x09, 0x4E, 0x78, 0x3C, 0x09, */
// 0x13, 0x05, 0x17, 0x11, 0x00, /* 0x13, 0x05, 0x17, 0x11, 0x00, */
{ 0, 0xe1, 15 }, // 0x00, 0x16, 0x1B, 0x04, 0x11, { 0, 0xe1, 15 }, /* 0x00, 0x16, 0x1B, 0x04, 0x11, */
// 0x07, 0x31, 0x33, 0x42, 0x05, /* 0x07, 0x31, 0x33, 0x42, 0x05, */
// 0x0C, 0x0A, 0x28, 0x2F, 0x0F, /* 0x0C, 0x0A, 0x28, 0x2F, 0x0F, */
{ 200, 0x11, 0 }, { 200, 0x11, 0 },
{ 0, 0x29, 0 }, { 0, 0x29, 0 },
{ 0, 0, 0 } // cmd == 0 indicates last command { 0, 0, 0 } /* cmd == 0 indicates last command */
}; };
/* prototype for initialize_display */ /* prototype for initialize_display */
@@ -188,7 +190,8 @@ static void initialize_display(const struct tft_command cmds[]);
* the commands it is sending to the console. * the commands it is sending to the console.
*/ */
static void static void
initialize_display(const struct tft_command cmds[]) { initialize_display(const struct tft_command cmds[])
{
int i = 0; int i = 0;
int arg_offset = 0; int arg_offset = 0;
int j; int j;
@@ -235,18 +238,19 @@ static void test_image(void);
* white lines. No line on the right edge and bottom of screen. * white lines. No line on the right edge and bottom of screen.
*/ */
static void static void
test_image(void) { test_image(void)
{
int x, y; int x, y;
uint16_t pixel; uint16_t pixel;
for (x = 0; x < LCD_WIDTH; x++) { for (x = 0; x < LCD_WIDTH; x++) {
for (y = 0; y < LCD_HEIGHT; y++) { for (y = 0; y < LCD_HEIGHT; y++) {
pixel = 0; // all black pixel = 0; /* all black */
if ((x % 16) == 0) { if ((x % 16) == 0) {
pixel = 0xffff; // all white pixel = 0xffff; /* all white */
} }
if ((y % 16) == 0) { if ((y % 16) == 0) {
pixel = 0xffff; // all white pixel = 0xffff; /* all white */
} }
lcd_draw_pixel(x, y, pixel); lcd_draw_pixel(x, y, pixel);
} }
@@ -261,7 +265,8 @@ test_image(void) {
* the implementation of SPI and the modules interpretation of * the implementation of SPI and the modules interpretation of
* D/CX line. * D/CX line.
*/ */
void lcd_show_frame(void) { void lcd_show_frame(void)
{
uint16_t *t; uint16_t *t;
uint8_t size[4]; uint8_t size[4];
@@ -302,7 +307,8 @@ void lcd_show_frame(void) {
* LCD_HEIGHT 320 * LCD_HEIGHT 320
*/ */
void void
lcd_spi_init(void) { lcd_spi_init(void)
{
/* /*
* Set up the GPIO lines for the SPI port and * Set up the GPIO lines for the SPI port and
@@ -348,7 +354,8 @@ lcd_spi_init(void) {
* number on the console. * number on the console.
*/ */
int int
print_decimal(int num) { print_decimal(int num)
{
int ndx = 0; int ndx = 0;
char buf[10]; char buf[10];
int len = 0; int len = 0;
@@ -372,7 +379,7 @@ print_decimal(int num) {
console_putc(buf[ndx--]); console_putc(buf[ndx--]);
len++; len++;
} }
return len; // number of characters printed return len; /* number of characters printed */
} }
/* /*
@@ -380,7 +387,8 @@ print_decimal(int num) {
* *
* Very simple routine for printing out hex constants. * Very simple routine for printing out hex constants.
*/ */
static int print_hex(int v) { static int print_hex(int v)
{
int ndx = 0; int ndx = 0;
char buf[10]; char buf[10];
int len; int len;
@@ -388,7 +396,7 @@ static int print_hex(int v) {
buf[ndx++] = '\000'; buf[ndx++] = '\000';
do { do {
char c = v & 0xf; char c = v & 0xf;
buf[ndx++] = (c > 9) ? '7'+ c : '0' + c; buf[ndx++] = (c > 9) ? '7' + c : '0' + c;
v = (v >> 4) & 0x0fffffff; v = (v >> 4) & 0x0fffffff;
} while (v != 0); } while (v != 0);
ndx--; ndx--;
@@ -398,5 +406,5 @@ static int print_hex(int v) {
console_putc(buf[ndx--]); console_putc(buf[ndx--]);
len++; len++;
} }
return len; // number of characters printed return len; /* number of characters printed */
} }

View File

@@ -31,25 +31,25 @@ void lcd_spi_init(void);
void lcd_show_frame(void); void lcd_show_frame(void);
void lcd_draw_pixel(int x, int y, uint16_t color); void lcd_draw_pixel(int x, int y, uint16_t color);
// Color definitions /* Color definitions */
#define LCD_BLACK 0x0000 #define LCD_BLACK 0x0000
#define LCD_BLUE 0x1F00 #define LCD_BLUE 0x1F00
#define LCD_RED 0x00F8 #define LCD_RED 0x00F8
#define LCD_GREEN 0xE007 #define LCD_GREEN 0xE007
#define LCD_CYAN 0xFF07 #define LCD_CYAN 0xFF07
#define LCD_MAGENTA 0x1FF8 #define LCD_MAGENTA 0x1FF8
#define LCD_YELLOW 0xE0FF #define LCD_YELLOW 0xE0FF
#define LCD_WHITE 0xFFFF #define LCD_WHITE 0xFFFF
#define LCD_GREY 0xc339 #define LCD_GREY 0xc339
/* /*
* SPI Port and GPIO Defined - for STM32F4-Disco * SPI Port and GPIO Defined - for STM32F4-Disco
*/ */
// #define LCD_RESET PA3 not used /* #define LCD_RESET PA3 not used */
#define LCD_CS PC2 // CH 1 #define LCD_CS PC2 /* CH 1 */
#define LCD_SCK PF7 // CH 2 #define LCD_SCK PF7 /* CH 2 */
#define LCD_DC PD13 // CH 4 #define LCD_DC PD13 /* CH 4 */
#define LCD_MOSI PF9 // CH 3 #define LCD_MOSI PF9 /* CH 3 */
#define LCD_SPI SPI5 #define LCD_SPI SPI5

View File

@@ -43,7 +43,7 @@ static struct {
GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15 }, GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15 },
{GPIOF, GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 | GPIO11 | {GPIOF, GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 | GPIO11 |
GPIO12 | GPIO13 | GPIO14 | GPIO15 }, GPIO12 | GPIO13 | GPIO14 | GPIO15 },
{GPIOG, GPIO0 | GPIO1 | GPIO4 | GPIO5 |GPIO8 | GPIO15} {GPIOG, GPIO0 | GPIO1 | GPIO4 | GPIO5 | GPIO8 | GPIO15}
}; };
static struct sdram_timing timing = { static struct sdram_timing timing = {
@@ -62,7 +62,7 @@ static struct sdram_timing timing = {
void void
sdram_init(void) { sdram_init(void) {
int i; int i;
uint32_t cr_tmp, tr_tmp; // control, timing registers uint32_t cr_tmp, tr_tmp; /* control, timing registers */
/* /*
* First all the GPIO pins that end up as SDRAM pins * First all the GPIO pins that end up as SDRAM pins
@@ -75,10 +75,10 @@ sdram_init(void) {
rcc_periph_clock_enable(RCC_GPIOG); rcc_periph_clock_enable(RCC_GPIOG);
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
gpio_mode_setup(sdram_pins[i].gpio, GPIO_MODE_AF, GPIO_PUPD_NONE, gpio_mode_setup(sdram_pins[i].gpio, GPIO_MODE_AF,
sdram_pins[i].pins); GPIO_PUPD_NONE, sdram_pins[i].pins);
gpio_set_output_options(sdram_pins[i].gpio, GPIO_OTYPE_PP, gpio_set_output_options(sdram_pins[i].gpio, GPIO_OTYPE_PP,
GPIO_OSPEED_50MHZ, sdram_pins[i].pins); GPIO_OSPEED_50MHZ, sdram_pins[i].pins);
gpio_set_af(sdram_pins[i].gpio, GPIO_AF12, sdram_pins[i].pins); gpio_set_af(sdram_pins[i].gpio, GPIO_AF12, sdram_pins[i].pins);
} }
@@ -107,7 +107,7 @@ sdram_init(void) {
*/ */
FMC_SDCR1 |= (cr_tmp & FMC_SDCR_DNC_MASK); FMC_SDCR1 |= (cr_tmp & FMC_SDCR_DNC_MASK);
FMC_SDCR2 = cr_tmp; FMC_SDCR2 = cr_tmp;
tr_tmp = sdram_timing(&timing); tr_tmp = sdram_timing(&timing);
FMC_SDTR1 |= (tr_tmp & FMC_SDTR_DNC_MASK); FMC_SDTR1 |= (tr_tmp & FMC_SDTR_DNC_MASK);
FMC_SDTR2 = tr_tmp; FMC_SDTR2 = tr_tmp;
@@ -119,12 +119,12 @@ sdram_init(void) {
* - Load the Mode Register * - Load the Mode Register
*/ */
sdram_command(SDRAM_BANK2, SDRAM_CLK_CONF, 1, 0); sdram_command(SDRAM_BANK2, SDRAM_CLK_CONF, 1, 0);
msleep(1); // sleep at least 100uS msleep(1); /* sleep at least 100uS */
sdram_command(SDRAM_BANK2, SDRAM_PALL, 1, 0); sdram_command(SDRAM_BANK2, SDRAM_PALL, 1, 0);
sdram_command(SDRAM_BANK2, SDRAM_AUTO_REFRESH, 4, 0); sdram_command(SDRAM_BANK2, SDRAM_AUTO_REFRESH, 4, 0);
tr_tmp = SDRAM_MODE_BURST_LENGTH_2 | tr_tmp = SDRAM_MODE_BURST_LENGTH_2 |
SDRAM_MODE_BURST_TYPE_SEQUENTIAL | SDRAM_MODE_BURST_TYPE_SEQUENTIAL |
SDRAM_MODE_CAS_LATENCY_3 | SDRAM_MODE_CAS_LATENCY_3 |
SDRAM_MODE_OPERATING_MODE_STANDARD | SDRAM_MODE_OPERATING_MODE_STANDARD |
SDRAM_MODE_WRITEBURST_MODE_SINGLE; SDRAM_MODE_WRITEBURST_MODE_SINGLE;
sdram_command(SDRAM_BANK2, SDRAM_LOAD_MODE, 1, tr_tmp); sdram_command(SDRAM_BANK2, SDRAM_LOAD_MODE, 1, tr_tmp);

View File

@@ -26,14 +26,14 @@ static void gpio_setup(void)
{ {
/* Enable GPIOD clock. */ /* Enable GPIOD clock. */
/* Manually: */ /* Manually: */
// RCC_AHB1ENR |= RCC_AHB1ENR_IOPGEN; /* RCC_AHB1ENR |= RCC_AHB1ENR_IOPGEN; */
/* Using API functions: */ /* Using API functions: */
rcc_periph_clock_enable(RCC_GPIOG); rcc_periph_clock_enable(RCC_GPIOG);
/* Set GPIO13 (in GPIO port G) to 'output push-pull'. */ /* Set GPIO13 (in GPIO port G) to 'output push-pull'. */
/* Manually: */ /* Manually: */
// GPIOG_CRH = (GPIO_CNF_OUTPUT_PUSHPULL << 2); /* GPIOG_CRH = (GPIO_CNF_OUTPUT_PUSHPULL << 2); */
// GPIOG_CRH |= (GPIO_MODE_OUTPUT_2_MHZ << 2); /* GPIOG_CRH |= (GPIO_MODE_OUTPUT_2_MHZ << 2); */
/* Using API functions: */ /* Using API functions: */
gpio_mode_setup(GPIOG, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO13); gpio_mode_setup(GPIOG, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO13);
} }
@@ -47,20 +47,28 @@ int main(void)
/* Blink the LED (PG13) on the board. */ /* Blink the LED (PG13) on the board. */
while (1) { while (1) {
/* Manually: */ /* Manually: */
// GPIOG_BSRR = GPIO13; /* LED off */ #if 0
// for (i = 0; i < 1000000; i++) /* Wait a bit. */ GPIOG_BSRR = GPIO13; /* LED off */
// __asm__("nop"); for (i = 0; i < 1000000; i++) { /* Wait a bit. */
// GPIOG_BRR = GPIO13; /* LED on */ __asm__("nop");
// for (i = 0; i < 1000000; i++) /* Wait a bit. */ }
// __asm__("nop"); GPIOG_BRR = GPIO13; /* LED on */
for (i = 0; i < 1000000; i++) { /* Wait a bit. */
__asm__("nop");
}
#endif
/* Using API functions gpio_set()/gpio_clear(): */ /* Using API functions gpio_set()/gpio_clear(): */
// gpio_set(GPIOG, GPIO13); /* LED off */ #if 0
// for (i = 0; i < 1000000; i++) /* Wait a bit. */ gpio_set(GPIOG, GPIO13); /* LED off */
// __asm__("nop"); for (i = 0; i < 1000000; i++) { /* Wait a bit. */
// gpio_clear(GPIOG, GPIO13); /* LED on */ __asm__("nop");
// for (i = 0; i < 1000000; i++) /* Wait a bit. */ }
// __asm__("nop"); gpio_clear(GPIOG, GPIO13); /* LED on */
for (i = 0; i < 1000000; i++) { /* Wait a bit. */
__asm__("nop");
}
#endif
/* Using API function gpio_toggle(): */ /* Using API function gpio_toggle(): */
gpio_toggle(GPIOG, GPIO13); /* LED on/off */ gpio_toggle(GPIOG, GPIO13); /* LED on/off */

View File

@@ -33,18 +33,21 @@
static volatile uint32_t system_millis; static volatile uint32_t system_millis;
/* Called when systick fires */ /* Called when systick fires */
void sys_tick_handler(void) { void sys_tick_handler(void)
{
system_millis++; system_millis++;
} }
/* simple sleep for delay milliseconds */ /* simple sleep for delay milliseconds */
void msleep(uint32_t delay) { void msleep(uint32_t delay)
{
uint32_t wake = system_millis + delay; uint32_t wake = system_millis + delay;
while (wake > system_millis) ; while (wake > system_millis);
} }
/* Getter function for the current time */ /* Getter function for the current time */
uint32_t mtime(void) { uint32_t mtime(void)
{
return system_millis; return system_millis;
} }

View File

@@ -37,29 +37,26 @@
#include <libopencm3/cm3/cortex.h> #include <libopencm3/cm3/cortex.h>
#include "console.h" #include "console.h"
/* /*
* Some definitions of our console "functions" attached to the * Some definitions of our console "functions" attached to the
* USART. * USART.
* *
* These define sort of the minimum "library" of functions which * These define sort of the minimum "library" of functions which
* we can use on a serial port. * we can use on a serial port.
*/ */
#define CONSOLE_UART USART1 #define CONSOLE_UART USART1
/* This is a ring buffer to holding characters as they are typed /* This is a ring buffer to holding characters as they are typed
* it maintains both the place to put the next character received * it maintains both the place to put the next character received
* from the UART, and the place where the last character was * from the UART, and the place where the last character was
* read by the program. See the README file for a discussion of * read by the program. See the README file for a discussion of
* the failure semantics. * the failure semantics.
*/ */
#define RECV_BUF_SIZE 128 // Arbitrary buffer size #define RECV_BUF_SIZE 128 /* Arbitrary buffer size */
char recv_buf[RECV_BUF_SIZE]; char recv_buf[RECV_BUF_SIZE];
volatile int recv_ndx_nxt; // Next place to store volatile int recv_ndx_nxt; /* Next place to store */
volatile int recv_ndx_cur; // Next place to read volatile int recv_ndx_cur; /* Next place to read */
/* For interrupt handling we add a new function which is called /* For interrupt handling we add a new function which is called
* when recieve interrupts happen. The name (usart1_isr) is created * when recieve interrupts happen. The name (usart1_isr) is created
@@ -72,7 +69,8 @@ volatile int recv_ndx_cur; // Next place to read
* right or it won't work. And you'll wonder where your interrupts * right or it won't work. And you'll wonder where your interrupts
* are going. * are going.
*/ */
void usart1_isr(void) { void usart1_isr(void)
{
uint32_t reg; uint32_t reg;
int i; int i;
@@ -84,10 +82,13 @@ void usart1_isr(void) {
/* Check for "reset" */ /* Check for "reset" */
if (recv_buf[recv_ndx_nxt] == '\003') { if (recv_buf[recv_ndx_nxt] == '\003') {
/* reset the system */ /* reset the system */
volatile uint32_t *ret = (&reg) + 7; // Return address on stack /* Return address on stack */
volatile uint32_t *ret = (&reg) + 7;
*ret = (uint32_t) &reset_handler; // force system reset
return; // go to new address /* force system reset */
*ret = (uint32_t) &reset_handler;
/* go to new address */
return;
} }
#endif #endif
/* Check for "overrun" */ /* Check for "overrun" */
@@ -96,7 +97,8 @@ void usart1_isr(void) {
recv_ndx_nxt = i; recv_ndx_nxt = i;
} }
} }
} while ((reg & USART_SR_RXNE) != 0); // can read back-to-back interrupts /* can read back-to-back interrupts */
} while ((reg & USART_SR_RXNE) != 0);
} }
/* /*
@@ -105,7 +107,8 @@ void usart1_isr(void) {
* Send the character 'c' to the USART, wait for the USART * Send the character 'c' to the USART, wait for the USART
* transmit buffer to be empty first. * transmit buffer to be empty first.
*/ */
void console_putc(char c) { void console_putc(char c)
{
uint32_t reg; uint32_t reg;
do { do {
reg = USART_SR(CONSOLE_UART); reg = USART_SR(CONSOLE_UART);
@@ -123,10 +126,11 @@ void console_putc(char c) {
* The implementation is a bit different however, now it looks * The implementation is a bit different however, now it looks
* in the ring buffer to see if a character has arrived. * in the ring buffer to see if a character has arrived.
*/ */
char console_getc(int wait) { char console_getc(int wait)
{
char c = 0; char c = 0;
while ((wait != 0) && (recv_ndx_cur == recv_ndx_nxt)) ; while ((wait != 0) && (recv_ndx_cur == recv_ndx_nxt));
if (recv_ndx_cur != recv_ndx_nxt) { if (recv_ndx_cur != recv_ndx_nxt) {
c = recv_buf[recv_ndx_cur]; c = recv_buf[recv_ndx_cur];
recv_ndx_cur = (recv_ndx_cur + 1) % RECV_BUF_SIZE; recv_ndx_cur = (recv_ndx_cur + 1) % RECV_BUF_SIZE;
@@ -141,7 +145,8 @@ char console_getc(int wait) {
* after the last character, as indicated by a NUL character, is * after the last character, as indicated by a NUL character, is
* reached. * reached.
*/ */
void console_puts(char *s) { void console_puts(char *s)
{
while (*s != '\000') { while (*s != '\000') {
console_putc(*s); console_putc(*s);
/* Add in a carraige return, after sending line feed */ /* Add in a carraige return, after sending line feed */
@@ -159,7 +164,8 @@ void console_puts(char *s) {
* support for editing characters (back space and delete) * support for editing characters (back space and delete)
* end when a <CR> character is received. * end when a <CR> character is received.
*/ */
int console_gets(char *s, int len) { int console_gets(char *s, int len)
{
char *t = s; char *t = s;
char c; char c;
@@ -182,7 +188,7 @@ int console_gets(char *s, int len) {
/* update end of string with NUL */ /* update end of string with NUL */
*t = '\000'; *t = '\000';
} }
return (t - s); return t - s;
} }
/* /*
@@ -190,7 +196,8 @@ int console_gets(char *s, int len) {
* on some of the pins, in this case connected to a * on some of the pins, in this case connected to a
* USART. * USART.
*/ */
void console_setup(void) { void console_setup(void)
{
/* MUST enable the GPIO clock in ADDITION to the USART clock */ /* MUST enable the GPIO clock in ADDITION to the USART clock */
rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOA);

View File

@@ -49,7 +49,7 @@ static struct {
GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15 }, GPIO11 | GPIO12 | GPIO13 | GPIO14 | GPIO15 },
{GPIOF, GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 | GPIO11 | {GPIOF, GPIO0 | GPIO1 | GPIO2 | GPIO3 | GPIO4 | GPIO5 | GPIO11 |
GPIO12 | GPIO13 | GPIO14 | GPIO15 }, GPIO12 | GPIO13 | GPIO14 | GPIO15 },
{GPIOG, GPIO0 | GPIO1 | GPIO4 | GPIO5 |GPIO8 | GPIO15} {GPIOG, GPIO0 | GPIO1 | GPIO4 | GPIO5 | GPIO8 | GPIO15}
}; };
static struct sdram_timing timing = { static struct sdram_timing timing = {
@@ -66,9 +66,10 @@ static struct sdram_timing timing = {
* Initialize the SD RAM controller. * Initialize the SD RAM controller.
*/ */
void void
sdram_init(void) { sdram_init(void)
{
int i; int i;
uint32_t cr_tmp, tr_tmp; // control, timing registers uint32_t cr_tmp, tr_tmp; /* control, timing registers */
/* /*
* First all the GPIO pins that end up as SDRAM pins * First all the GPIO pins that end up as SDRAM pins
@@ -81,15 +82,15 @@ sdram_init(void) {
rcc_periph_clock_enable(RCC_GPIOG); rcc_periph_clock_enable(RCC_GPIOG);
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
gpio_mode_setup(sdram_pins[i].gpio, GPIO_MODE_AF, GPIO_PUPD_NONE, gpio_mode_setup(sdram_pins[i].gpio, GPIO_MODE_AF,
sdram_pins[i].pins); GPIO_PUPD_NONE, sdram_pins[i].pins);
gpio_set_output_options(sdram_pins[i].gpio, GPIO_OTYPE_PP, gpio_set_output_options(sdram_pins[i].gpio, GPIO_OTYPE_PP,
GPIO_OSPEED_50MHZ, sdram_pins[i].pins); GPIO_OSPEED_50MHZ, sdram_pins[i].pins);
gpio_set_af(sdram_pins[i].gpio, GPIO_AF12, sdram_pins[i].pins); gpio_set_af(sdram_pins[i].gpio, GPIO_AF12, sdram_pins[i].pins);
} }
/* Enable the SDRAM Controller */ /* Enable the SDRAM Controller */
rcc_periph_clock_enable(RCC_FSMC); rcc_periph_clock_enable(RCC_FSMC);
/* Note the STM32F429-DISCO board has the ram attached to bank 2 */ /* Note the STM32F429-DISCO board has the ram attached to bank 2 */
/* Timing parameters computed for a 168Mhz clock */ /* Timing parameters computed for a 168Mhz clock */
@@ -109,7 +110,7 @@ sdram_init(void) {
*/ */
FMC_SDCR1 |= (cr_tmp & FMC_SDCR_DNC_MASK); FMC_SDCR1 |= (cr_tmp & FMC_SDCR_DNC_MASK);
FMC_SDCR2 = cr_tmp; FMC_SDCR2 = cr_tmp;
tr_tmp = sdram_timing(&timing); tr_tmp = sdram_timing(&timing);
FMC_SDTR1 |= (tr_tmp & FMC_SDTR_DNC_MASK); FMC_SDTR1 |= (tr_tmp & FMC_SDTR_DNC_MASK);
FMC_SDTR2 = tr_tmp; FMC_SDTR2 = tr_tmp;
@@ -121,12 +122,12 @@ sdram_init(void) {
* - Load the Mode Register * - Load the Mode Register
*/ */
sdram_command(SDRAM_BANK2, SDRAM_CLK_CONF, 1, 0); sdram_command(SDRAM_BANK2, SDRAM_CLK_CONF, 1, 0);
msleep(1); // sleep at least 100uS msleep(1); /* sleep at least 100uS */
sdram_command(SDRAM_BANK2, SDRAM_PALL, 1, 0); sdram_command(SDRAM_BANK2, SDRAM_PALL, 1, 0);
sdram_command(SDRAM_BANK2, SDRAM_AUTO_REFRESH, 4, 0); sdram_command(SDRAM_BANK2, SDRAM_AUTO_REFRESH, 4, 0);
tr_tmp = SDRAM_MODE_BURST_LENGTH_2 | tr_tmp = SDRAM_MODE_BURST_LENGTH_2 |
SDRAM_MODE_BURST_TYPE_SEQUENTIAL | SDRAM_MODE_BURST_TYPE_SEQUENTIAL |
SDRAM_MODE_CAS_LATENCY_3 | SDRAM_MODE_CAS_LATENCY_3 |
SDRAM_MODE_OPERATING_MODE_STANDARD | SDRAM_MODE_OPERATING_MODE_STANDARD |
SDRAM_MODE_WRITEBURST_MODE_SINGLE; SDRAM_MODE_WRITEBURST_MODE_SINGLE;
sdram_command(SDRAM_BANK2, SDRAM_LOAD_MODE, 1, tr_tmp); sdram_command(SDRAM_BANK2, SDRAM_LOAD_MODE, 1, tr_tmp);
@@ -154,13 +155,15 @@ uint8_t *dump_page(uint8_t *, uint8_t *);
#define HEX_CHAR(x) ((((x) + '0') > '9') ? ((x) + '7') : ((x) + '0')) #define HEX_CHAR(x) ((((x) + '0') > '9') ? ((x) + '7') : ((x) + '0'))
/* send an 8 bit byte as two HEX characters to the console */ /* send an 8 bit byte as two HEX characters to the console */
void dump_byte(uint8_t b) { void dump_byte(uint8_t b)
{
console_putc(HEX_CHAR((b >> 4) & 0xf)); console_putc(HEX_CHAR((b >> 4) & 0xf));
console_putc(HEX_CHAR(b & 0xf)); console_putc(HEX_CHAR(b & 0xf));
} }
/* send a 32 bit value as 8 hex characters to the console */ /* send a 32 bit value as 8 hex characters to the console */
void dump_long(uint32_t l) { void dump_long(uint32_t l)
{
int i = 0; int i = 0;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
console_putc(HEX_CHAR((l >> (28 - i * 4)) & 0xf)); console_putc(HEX_CHAR((l >> (28 - i * 4)) & 0xf));
@@ -177,7 +180,8 @@ void dump_long(uint32_t l) {
* next 16 bytes out. * next 16 bytes out.
*/ */
uint8_t * uint8_t *
dump_line(uint8_t *addr, uint8_t *base) { dump_line(uint8_t *addr, uint8_t *base)
{
uint8_t *line_addr; uint8_t *line_addr;
uint8_t b; uint8_t b;
uint32_t tmp; uint32_t tmp;
@@ -211,7 +215,8 @@ dump_line(uint8_t *addr, uint8_t *base) {
* on the screen with some other information. * on the screen with some other information.
*/ */
uint8_t * uint8_t *
dump_page(uint8_t *addr, uint8_t *base) { dump_page(uint8_t *addr, uint8_t *base)
{
int i; int i;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
addr = dump_line(addr, base); addr = dump_line(addr, base);
@@ -227,7 +232,8 @@ dump_page(uint8_t *addr, uint8_t *base) {
* (PL) previous line, and (?) for help. * (PL) previous line, and (?) for help.
*/ */
int int
main(void) { main(void)
{
int i; int i;
uint8_t *addr; uint8_t *addr;
char c; char c;
@@ -246,93 +252,93 @@ main(void) {
} }
console_puts("Modified data (with Fill Increment)\n"); console_puts("Modified data (with Fill Increment)\n");
addr = SDRAM_BASE_ADDRESS; addr = SDRAM_BASE_ADDRESS;
addr = dump_page( addr, NULL); addr = dump_page(addr, NULL);
while (1) { while (1) {
console_puts("CMD> "); console_puts("CMD> ");
switch (c = console_getc(1)) { switch (c = console_getc(1)) {
case 'f':
case 'F':
console_puts("Fill ");
switch (c = console_getc(1)) {
case 'i':
case 'I':
console_puts("Increment\n");
for (i = 0; i < 256; i++) {
*(addr+i) = i;
}
dump_page(addr, NULL);
break;
case '0':
console_puts("Zero\n");
for (i = 0; i < 256; i++) {
*(addr+i) = 0;
}
dump_page(addr, NULL);
break;
case 'f': case 'f':
case 'F': case 'F':
console_puts("Fill "); console_puts("Ones (0xff)\n");
switch (c = console_getc(1)) { for (i = 0; i < 256; i++) {
case 'i': *(addr+i) = 0xff;
case 'I':
console_puts("Increment\n");
for (i = 0; i < 256; i++) {
*(addr+i) = i;
}
dump_page(addr, NULL);
break;
case '0':
console_puts("Zero\n");
for (i = 0; i < 256; i++) {
*(addr+i) = 0;
}
dump_page(addr, NULL);
break;
case 'f':
case 'F':
console_puts("Ones (0xff)\n");
for (i = 0; i < 256; i++) {
*(addr+i) = 0xff;
}
dump_page(addr, NULL);
break;
default:
console_puts("Unrecognized Command, press ? for help\n");
}
break;
case 'n':
case 'N':
console_puts("Next ");
switch (c = console_getc(1)) {
case 'p':
case 'P':
console_puts("Page\n");
addr += 256;
dump_page(addr, NULL);
break;
case 'l':
case 'L':
console_puts("Line\n");
addr += 16;
dump_line(addr, NULL);
break;
default:
console_puts("Unrecognized Command, press ? for help\n");
} }
dump_page(addr, NULL);
break; break;
default:
console_puts("Unrecognized Command, press ? for help\n");
}
break;
case 'n':
case 'N':
console_puts("Next ");
switch (c = console_getc(1)) {
case 'p': case 'p':
case 'P': case 'P':
console_puts("Previous "); console_puts("Page\n");
switch (c = console_getc(1)) { addr += 256;
case 'p': dump_page(addr, NULL);
case 'P': break;
console_puts("Page\n"); case 'l':
addr -= 256; case 'L':
dump_page(addr, NULL); console_puts("Line\n");
break; addr += 16;
case 'l': dump_line(addr, NULL);
case 'L':
console_puts("Line\n");
addr -= 16;
dump_line(addr, NULL);
break;
default:
console_puts("Unrecognized Command, press ? for help\n");
}
break; break;
case '?':
default: default:
console_puts("Help\n"); console_puts("Unrecognized Command, press ? for help\n");
console_puts(" n p - dump next page\n"); }
console_puts(" n l - dump next line\n"); break;
console_puts(" p p - dump previous page\n"); case 'p':
console_puts(" p l - dump previous line\n"); case 'P':
console_puts(" f 0 - fill current page with 0\n"); console_puts("Previous ");
console_puts(" f i - fill current page with 0 to 255\n"); switch (c = console_getc(1)) {
console_puts(" f f - fill current page with 0xff\n"); case 'p':
console_puts(" ? - this message\n"); case 'P':
console_puts("Page\n");
addr -= 256;
dump_page(addr, NULL);
break; break;
case 'l':
case 'L':
console_puts("Line\n");
addr -= 16;
dump_line(addr, NULL);
break;
default:
console_puts("Unrecognized Command, press ? for help\n");
}
break;
case '?':
default:
console_puts("Help\n");
console_puts(" n p - dump next page\n");
console_puts(" n l - dump next line\n");
console_puts(" p p - dump previous page\n");
console_puts(" p l - dump previous line\n");
console_puts(" f 0 - fill current page with 0\n");
console_puts(" f i - fill current page with 0 to 255\n");
console_puts(" f f - fill current page with 0xff\n");
console_puts(" ? - this message\n");
break;
} }
} }
} }

View File

@@ -33,18 +33,21 @@
static volatile uint32_t system_millis; static volatile uint32_t system_millis;
/* Called when systick fires */ /* Called when systick fires */
void sys_tick_handler(void) { void sys_tick_handler(void)
{
system_millis++; system_millis++;
} }
/* simple sleep for delay milliseconds */ /* simple sleep for delay milliseconds */
void msleep(uint32_t delay) { void msleep(uint32_t delay)
{
uint32_t wake = system_millis + delay; uint32_t wake = system_millis + delay;
while (wake > system_millis) ; while (wake > system_millis);
} }
/* Getter function for the current time */ /* Getter function for the current time */
uint32_t mtime(void) { uint32_t mtime(void)
{
return system_millis; return system_millis;
} }

View File

@@ -41,10 +41,10 @@
* read by the program. See the README file for a discussion of * read by the program. See the README file for a discussion of
* the failure semantics. * the failure semantics.
*/ */
#define RECV_BUF_SIZE 128 // Arbitrary buffer size #define RECV_BUF_SIZE 128 /* Arbitrary buffer size */
char recv_buf[RECV_BUF_SIZE]; char recv_buf[RECV_BUF_SIZE];
volatile int recv_ndx_nxt; // Next place to store volatile int recv_ndx_nxt; /* Next place to store */
volatile int recv_ndx_cur; // Next place to read volatile int recv_ndx_cur; /* Next place to read */
/* For interrupt handling we add a new function which is called /* For interrupt handling we add a new function which is called
* when recieve interrupts happen. The name (usart1_isr) is created * when recieve interrupts happen. The name (usart1_isr) is created
@@ -57,9 +57,10 @@ volatile int recv_ndx_cur; // Next place to read
* right or it won't work. And you'll wonder where your interrupts * right or it won't work. And you'll wonder where your interrupts
* are going. * are going.
*/ */
void usart1_isr(void) { void usart1_isr(void)
uint32_t reg; {
int i; uint32_t reg;
int i;
do { do {
reg = USART_SR(CONSOLE_UART); reg = USART_SR(CONSOLE_UART);
@@ -68,21 +69,22 @@ void usart1_isr(void) {
#ifdef RESET_ON_CTRLC #ifdef RESET_ON_CTRLC
/* Check for "reset" */ /* Check for "reset" */
if (recv_buf[recv_ndx_nxt] == '\003') { if (recv_buf[recv_ndx_nxt] == '\003') {
/* reset the system /* reset the system volatile definition of
* volatile definition of return address on the stack * return address on the stack to insure it
* to insure it gets stored, changed to point to * gets stored, changed to point to the
* the trampoline function (do_the_nasty) which is * trampoline function (do_the_nasty) which is
* required because we need to return of an interrupt * required because we need to return of an
* to get the internal value of the LR register reset * interrupt to get the internal value of the
* and put the processor back into "Thread" mode from * LR register reset and put the processor back
* "Handler" mode. * into "Thread" mode from "Handler" mode.
* *
* See the PM0214 Programming Manual for Cortex M, * See the PM0214 Programming Manual for Cortex
* pg 42, to see the format of the Cortex M4 stack after * M, pg 42, to see the format of the Cortex M4
* an interrupt or exception has occurred. * stack after an interrupt or exception has
* occurred.
*/ */
volatile uint32_t *ret = (&reg) + 7; volatile uint32_t *ret = (&reg) + 7;
*ret = (uint32_t) &reset_handler; *ret = (uint32_t) &reset_handler;
return; return;
} }
@@ -93,7 +95,8 @@ void usart1_isr(void) {
recv_ndx_nxt = i; recv_ndx_nxt = i;
} }
} }
} while ((reg & USART_SR_RXNE) != 0); // can read back-to-back interrupts } while ((reg & USART_SR_RXNE) != 0); /* can read back-to-back
interrupts */
} }
/* /*
@@ -102,7 +105,8 @@ void usart1_isr(void) {
* Send the character 'c' to the USART, wait for the USART * Send the character 'c' to the USART, wait for the USART
* transmit buffer to be empty first. * transmit buffer to be empty first.
*/ */
void console_putc(char c) { void console_putc(char c)
{
uint32_t reg; uint32_t reg;
do { do {
reg = USART_SR(CONSOLE_UART); reg = USART_SR(CONSOLE_UART);
@@ -120,10 +124,11 @@ void console_putc(char c) {
* The implementation is a bit different however, now it looks * The implementation is a bit different however, now it looks
* in the ring buffer to see if a character has arrived. * in the ring buffer to see if a character has arrived.
*/ */
char console_getc(int wait) { char console_getc(int wait)
{
char c = 0; char c = 0;
while ((wait != 0) && (recv_ndx_cur == recv_ndx_nxt)) ; while ((wait != 0) && (recv_ndx_cur == recv_ndx_nxt));
if (recv_ndx_cur != recv_ndx_nxt) { if (recv_ndx_cur != recv_ndx_nxt) {
c = recv_buf[recv_ndx_cur]; c = recv_buf[recv_ndx_cur];
recv_ndx_cur = (recv_ndx_cur + 1) % RECV_BUF_SIZE; recv_ndx_cur = (recv_ndx_cur + 1) % RECV_BUF_SIZE;
@@ -138,7 +143,8 @@ char console_getc(int wait) {
* after the last character, as indicated by a NUL character, is * after the last character, as indicated by a NUL character, is
* reached. * reached.
*/ */
void console_puts(char *s) { void console_puts(char *s)
{
while (*s != '\000') { while (*s != '\000') {
console_putc(*s); console_putc(*s);
/* Add in a carraige return, after sending line feed */ /* Add in a carraige return, after sending line feed */
@@ -156,7 +162,8 @@ void console_puts(char *s) {
* support for editing characters (back space and delete) * support for editing characters (back space and delete)
* end when a <CR> character is received. * end when a <CR> character is received.
*/ */
int console_gets(char *s, int len) { int console_gets(char *s, int len)
{
char *t = s; char *t = s;
char c; char c;
@@ -179,7 +186,7 @@ int console_gets(char *s, int len) {
/* update end of string with NUL */ /* update end of string with NUL */
*t = '\000'; *t = '\000';
} }
return (t - s); return t - s;
} }
/* /*
@@ -188,8 +195,8 @@ int console_gets(char *s, int len) {
* Set the pins and clocks to create a console that we can * Set the pins and clocks to create a console that we can
* use for serial messages and getting text from the user. * use for serial messages and getting text from the user.
*/ */
void console_setup(int baud) { void console_setup(int baud)
{
/* MUST enable the GPIO clock in ADDITION to the USART clock */ /* MUST enable the GPIO clock in ADDITION to the USART clock */
rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOA);

View File

@@ -27,7 +27,7 @@
* These define sort of the minimum "library" of functions which * These define sort of the minimum "library" of functions which
* we can use on a serial port. If you wish to use a different * we can use on a serial port. If you wish to use a different
* USART there are several things to change: * USART there are several things to change:
* - CONSOLE_UART change this * - CONSOLE_UART change this
* - Change the peripheral enable clock * - Change the peripheral enable clock
* - add usartx_isr for interrupts * - add usartx_isr for interrupts
* - nvic_enable_interrupt(your choice of USART/UART) * - nvic_enable_interrupt(your choice of USART/UART)

View File

@@ -36,21 +36,20 @@ void write_reg(uint8_t reg, uint8_t value);
uint8_t read_xyz(int16_t vecs[3]); uint8_t read_xyz(int16_t vecs[3]);
void spi_init(void); void spi_init(void);
/* /*
* Chart of the various SPI ports (1 - 6) and where their pins can be: * Chart of the various SPI ports (1 - 6) and where their pins can be:
*
NSS SCK MISO MOSI * NSS SCK MISO MOSI
-------------- ------------------- ------------- --------------- * -------------- ------------------- ------------- ---------------
SPI1 PA4, PA15 PA5, PB3 PA6, PB4 PA7, PB5 * SPI1 PA4, PA15 PA5, PB3 PA6, PB4 PA7, PB5
SPI2 PB9, PB12, PI0 PB10, PB13, PD3, PI1 PB14, PC2, PI2 PB15, PC3, PI3 * SPI2 PB9, PB12, PI0 PB10, PB13, PD3, PI1 PB14, PC2, PI2 PB15, PC3, PI3
SPI3 PA15*, PA4* PB3*, PC10* PB4*, PC11* PB5*, PD6, PC12* * SPI3 PA15*, PA4* PB3*, PC10* PB4*, PC11* PB5*, PD6, PC12*
SPI4 PE4,PE11 PE2, PE12 PE5, PE13 PE6, PE14 * SPI4 PE4,PE11 PE2, PE12 PE5, PE13 PE6, PE14
SPI5 PF6, PH5 PF7, PH6 PF8 PF9, PF11, PH7 * SPI5 PF6, PH5 PF7, PH6 PF8 PF9, PF11, PH7
SPI6 PG8 PG13 PG12 PG14 * SPI6 PG8 PG13 PG12 PG14
*
Pin name with * is alternate function 6 otherwise use alternate function 5. * Pin name with * is alternate function 6 otherwise use alternate function 5.
*
* MEMS uses SPI5 - SCK (PF7), MISO (PF8), MOSI (PF9), * MEMS uses SPI5 - SCK (PF7), MISO (PF8), MOSI (PF9),
* MEMS CS* (PC1) -- GPIO * MEMS CS* (PC1) -- GPIO
* MEMS INT1 = PA1, MEMS INT2 = PA2 * MEMS INT1 = PA1, MEMS INT2 = PA2
@@ -60,13 +59,14 @@ void put_status(char *m);
/* /*
* put_status(char *) * put_status(char *)
* *
* This is a helper function I wrote to watch the status register * This is a helper function I wrote to watch the status register
* it decodes the bits and prints them on the console. Sometimes * it decodes the bits and prints them on the console. Sometimes
* the SPI port comes up with the MODF flag set, you have to re-read * the SPI port comes up with the MODF flag set, you have to re-read
* the status port and re-write the control register to clear that. * the status port and re-write the control register to clear that.
*/ */
void put_status(char *m) { void put_status(char *m)
{
uint16_t stmp; uint16_t stmp;
console_puts(m); console_puts(m);
@@ -95,7 +95,7 @@ void put_status(char *m) {
} }
console_puts("\n"); console_puts("\n");
} }
/* /*
* read_reg(int reg) * read_reg(int reg)
* *
@@ -106,10 +106,11 @@ void put_status(char *m) {
* be a more stable solution. * be a more stable solution.
*/ */
uint16_t uint16_t
read_reg(int reg) { read_reg(int reg)
{
uint16_t d1, d2; uint16_t d1, d2;
d1 = 0x80 | (reg & 0x3f); // Read operation d1 = 0x80 | (reg & 0x3f); /* Read operation */
/* Nominallly a register read is a 16 bit operation */ /* Nominallly a register read is a 16 bit operation */
gpio_clear(GPIOC, GPIO1); gpio_clear(GPIOC, GPIO1);
spi_send(SPI5, d1); spi_send(SPI5, d1);
@@ -136,22 +137,23 @@ read_reg(int reg) {
* Then the status register is read and returned. * Then the status register is read and returned.
*/ */
uint8_t uint8_t
read_xyz(int16_t vecs[3]) { read_xyz(int16_t vecs[3])
{
uint8_t buf[7]; uint8_t buf[7];
int i; int i;
gpio_clear(GPIOC, GPIO1); // CS* select gpio_clear(GPIOC, GPIO1); /* CS* select */
spi_send(SPI5, 0xc0 | 0x28); spi_send(SPI5, 0xc0 | 0x28);
(void) spi_read(SPI5); (void) spi_read(SPI5);
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
spi_send(SPI5, 0); spi_send(SPI5, 0);
buf[i] = spi_read(SPI5); buf[i] = spi_read(SPI5);
} }
gpio_set(GPIOC, GPIO1); // CS* deselect gpio_set(GPIOC, GPIO1); /* CS* deselect */
vecs[0] = (buf[1] << 8 | buf[0]); vecs[0] = (buf[1] << 8 | buf[0]);
vecs[1] = (buf[3] << 8 | buf[2]); vecs[1] = (buf[3] << 8 | buf[2]);
vecs[3] = (buf[5] << 8 | buf[4]); vecs[3] = (buf[5] << 8 | buf[4]);
return read_reg(0x27); // Status register return read_reg(0x27); /* Status register */
} }
/* /*
@@ -161,13 +163,14 @@ read_xyz(int16_t vecs[3]) {
* selecting it and then writing to it. * selecting it and then writing to it.
*/ */
void void
write_reg(uint8_t reg, uint8_t value) { write_reg(uint8_t reg, uint8_t value)
gpio_clear(GPIOC, GPIO1); // CS* select {
gpio_clear(GPIOC, GPIO1); /* CS* select */
spi_send(SPI5, reg); spi_send(SPI5, reg);
(void) spi_read(SPI5); (void) spi_read(SPI5);
spi_send(SPI5, value); spi_send(SPI5, value);
(void) spi_read(SPI5); (void) spi_read(SPI5);
gpio_set(GPIOC, GPIO1); // CS* deselect gpio_set(GPIOC, GPIO1); /* CS* deselect */
return; return;
} }
@@ -180,7 +183,8 @@ int print_decimal(int);
* number on the console. * number on the console.
*/ */
int int
print_decimal(int num) { print_decimal(int num)
{
int ndx = 0; int ndx = 0;
char buf[10]; char buf[10];
int len = 0; int len = 0;
@@ -204,7 +208,7 @@ print_decimal(int num) {
console_putc(buf[ndx--]); console_putc(buf[ndx--]);
len++; len++;
} }
return len; // number of characters printed return len; /* number of characters printed */
} }
char *axes[] = { "X: ", "Y: ", "Z: " }; char *axes[] = { "X: ", "Y: ", "Z: " };
@@ -214,7 +218,8 @@ char *axes[] = { "X: ", "Y: ", "Z: " };
* SPI port, and then shows a continuous display of values on * SPI port, and then shows a continuous display of values on
* the console once you start it. Typing ^C will reset it. * the console once you start it. Typing ^C will reset it.
*/ */
int main(void) { int main(void)
{
int16_t vecs[3]; int16_t vecs[3];
int16_t baseline[3]; int16_t baseline[3];
int tmp, i; int tmp, i;
@@ -225,13 +230,13 @@ int main(void) {
console_setup(115200); console_setup(115200);
/* Enable the GPIO ports whose pins we are using */ /* Enable the GPIO ports whose pins we are using */
rcc_periph_clock_enable(RCC_GPIOF | RCC_GPIOC); rcc_periph_clock_enable(RCC_GPIOF | RCC_GPIOC);
gpio_mode_setup(GPIOF, GPIO_MODE_AF, GPIO_PUPD_PULLDOWN, gpio_mode_setup(GPIOF, GPIO_MODE_AF, GPIO_PUPD_PULLDOWN,
GPIO7 | GPIO8 | GPIO9); GPIO7 | GPIO8 | GPIO9);
gpio_set_af(GPIOF, GPIO_AF5, GPIO7 | GPIO8 | GPIO9); gpio_set_af(GPIOF, GPIO_AF5, GPIO7 | GPIO8 | GPIO9);
gpio_set_output_options(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, gpio_set_output_options(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ,
GPIO7 | GPIO9); GPIO7 | GPIO9);
/* Chip select line */ /* Chip select line */
gpio_set(GPIOC, GPIO1); gpio_set(GPIOC, GPIO1);
@@ -239,11 +244,11 @@ int main(void) {
rcc_periph_clock_enable(RCC_SPI5); rcc_periph_clock_enable(RCC_SPI5);
cr_tmp = SPI_CR1_BAUDRATE_FPCLK_DIV_8 |\ cr_tmp = SPI_CR1_BAUDRATE_FPCLK_DIV_8 |
SPI_CR1_MSTR |\ SPI_CR1_MSTR |
SPI_CR1_SPE |\ SPI_CR1_SPE |
SPI_CR1_CPHA |\ SPI_CR1_CPHA |
SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE ; SPI_CR1_CPOL_CLK_TO_1_WHEN_IDLE;
put_status("\nBefore init: "); put_status("\nBefore init: ");
SPI_CR2(SPI5) |= SPI_CR2_SSOE; SPI_CR2(SPI5) |= SPI_CR2_SSOE;
@@ -269,25 +274,25 @@ int main(void) {
* temperature reading is correct and the ID code returned is * temperature reading is correct and the ID code returned is
* as expected so the SPI code at least is working. * as expected so the SPI code at least is working.
*/ */
write_reg(0x20, 0xcf); // Normal mode write_reg(0x20, 0xcf); /* Normal mode */
write_reg(0x21, 0x07); // standard filters write_reg(0x21, 0x07); /* standard filters */
write_reg(0x23, 0xb0); // 250 dps write_reg(0x23, 0xb0); /* 250 dps */
tmp = (int) read_reg(0x26); tmp = (int) read_reg(0x26);
console_puts( "Temperature: "); console_puts("Temperature: ");
print_decimal(tmp); print_decimal(tmp);
console_puts( " C\n"); console_puts(" C\n");
count = 0; count = 0;
while (1) { while (1) {
tmp = read_xyz(vecs); tmp = read_xyz(vecs);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
int pad; int pad;
console_puts( axes[i]); console_puts(axes[i]);
tmp = vecs[i] - baseline[i]; tmp = vecs[i] - baseline[i];
pad = print_decimal(tmp); pad = print_decimal(tmp);
pad = 15 - pad; pad = 15 - pad;
while (pad--) { while (pad--) {
console_puts( " "); console_puts(" ");
} }
} }
console_putc('\r'); console_putc('\r');

View File

@@ -34,18 +34,21 @@
static volatile uint32_t system_millis; static volatile uint32_t system_millis;
/* Called when systick fires */ /* Called when systick fires */
void sys_tick_handler(void) { void sys_tick_handler(void)
{
system_millis++; system_millis++;
} }
/* simple sleep for delay milliseconds */ /* simple sleep for delay milliseconds */
void msleep(uint32_t delay) { void msleep(uint32_t delay)
{
uint32_t wake = system_millis + delay; uint32_t wake = system_millis + delay;
while (wake > system_millis) ; while (wake > system_millis);
} }
/* Getter function for the current time */ /* Getter function for the current time */
uint32_t mtime(void) { uint32_t mtime(void)
{
return system_millis; return system_millis;
} }

View File

@@ -32,7 +32,7 @@
* USART. * USART.
* *
* These define sort of the minimum "library" of functions which * These define sort of the minimum "library" of functions which
* we can use on a serial port. * we can use on a serial port.
*/ */
#define CONSOLE_UART USART1 #define CONSOLE_UART USART1
@@ -48,7 +48,8 @@ int console_gets(char *s, int len);
* Send the character 'c' to the USART, wait for the USART * Send the character 'c' to the USART, wait for the USART
* transmit buffer to be empty first. * transmit buffer to be empty first.
*/ */
void console_putc(char c) { void console_putc(char c)
{
uint32_t reg; uint32_t reg;
do { do {
reg = USART_SR(CONSOLE_UART); reg = USART_SR(CONSOLE_UART);
@@ -63,7 +64,8 @@ void console_putc(char c) {
* non-zero. Continue checking until a character is received * non-zero. Continue checking until a character is received
* otherwise return 0 if called and no character was available. * otherwise return 0 if called and no character was available.
*/ */
char console_getc(int wait) { char console_getc(int wait)
{
uint32_t reg; uint32_t reg;
do { do {
reg = USART_SR(CONSOLE_UART); reg = USART_SR(CONSOLE_UART);
@@ -78,7 +80,8 @@ char console_getc(int wait) {
* after the last character, as indicated by a NUL character, is * after the last character, as indicated by a NUL character, is
* reached. * reached.
*/ */
void console_puts(char *s) { void console_puts(char *s)
{
while (*s != '\000') { while (*s != '\000') {
console_putc(*s); console_putc(*s);
/* Add in a carraige return, after sending line feed */ /* Add in a carraige return, after sending line feed */
@@ -96,7 +99,8 @@ void console_puts(char *s) {
* support for editing characters (back space and delete) * support for editing characters (back space and delete)
* end when a <CR> character is received. * end when a <CR> character is received.
*/ */
int console_gets(char *s, int len) { int console_gets(char *s, int len)
{
char *t = s; char *t = s;
char c; char c;
@@ -119,7 +123,7 @@ int console_gets(char *s, int len) {
/* update end of string with NUL */ /* update end of string with NUL */
*t = '\000'; *t = '\000';
} }
return (t - s); return t - s;
} }
/* /*
@@ -127,11 +131,12 @@ int console_gets(char *s, int len) {
* on some of the pins, in this case connected to a * on some of the pins, in this case connected to a
* USART. * USART.
*/ */
int main(void) { int main(void)
{
char buf[128]; char buf[128];
int len; int len;
clock_setup(); // initialize our clock clock_setup(); /* initialize our clock */
/* MUST enable the GPIO clock in ADDITION to the USART clock */ /* MUST enable the GPIO clock in ADDITION to the USART clock */
rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOA);

View File

@@ -33,18 +33,21 @@
static volatile uint32_t system_millis; static volatile uint32_t system_millis;
/* Called when systick fires */ /* Called when systick fires */
void sys_tick_handler(void) { void sys_tick_handler(void)
{
system_millis++; system_millis++;
} }
/* simple sleep for delay milliseconds */ /* simple sleep for delay milliseconds */
void msleep(uint32_t delay) { void msleep(uint32_t delay)
{
uint32_t wake = system_millis + delay; uint32_t wake = system_millis + delay;
while (wake > system_millis) ; while (wake > system_millis);
} }
/* Getter function for the current time */ /* Getter function for the current time */
uint32_t mtime(void) { uint32_t mtime(void)
{
return system_millis; return system_millis;
} }

View File

@@ -45,7 +45,7 @@
* These define sort of the minimum "library" of functions which * These define sort of the minimum "library" of functions which
* we can use on a serial port. If you wish to use a different * we can use on a serial port. If you wish to use a different
* USART there are several things to change: * USART there are several things to change:
* - CONSOLE_UART change this * - CONSOLE_UART change this
* - Change the peripheral enable clock * - Change the peripheral enable clock
* - add usartx_isr for interrupts * - add usartx_isr for interrupts
* - nvic_enable_interrupt(your choice of USART/UART) * - nvic_enable_interrupt(your choice of USART/UART)
@@ -79,9 +79,10 @@ static void do_the_nasty(void);
* the return address of the interrupt to here, and then this function * the return address of the interrupt to here, and then this function
* does a longjump to the last place we did a setjmp. * does a longjump to the last place we did a setjmp.
*/ */
static void do_the_nasty(void) { static void do_the_nasty(void)
{
longjmp(jump_buf, 1); longjmp(jump_buf, 1);
while(1) ; while (1);
} }
#endif #endif
@@ -91,10 +92,10 @@ static void do_the_nasty(void) {
* read by the program. See the README file for a discussion of * read by the program. See the README file for a discussion of
* the failure semantics. * the failure semantics.
*/ */
#define RECV_BUF_SIZE 128 // Arbitrary buffer size #define RECV_BUF_SIZE 128 /* Arbitrary buffer size */
char recv_buf[RECV_BUF_SIZE]; char recv_buf[RECV_BUF_SIZE];
volatile int recv_ndx_nxt; // Next place to store volatile int recv_ndx_nxt; /* Next place to store */
volatile int recv_ndx_cur; // Next place to read volatile int recv_ndx_cur; /* Next place to read */
/* For interrupt handling we add a new function which is called /* For interrupt handling we add a new function which is called
* when recieve interrupts happen. The name (usart1_isr) is created * when recieve interrupts happen. The name (usart1_isr) is created
@@ -107,7 +108,8 @@ volatile int recv_ndx_cur; // Next place to read
* right or it won't work. And you'll wonder where your interrupts * right or it won't work. And you'll wonder where your interrupts
* are going. * are going.
*/ */
void usart1_isr(void) { void usart1_isr(void)
{
uint32_t reg; uint32_t reg;
int i; int i;
@@ -118,21 +120,22 @@ void usart1_isr(void) {
#ifdef RESET_ON_CTRLC #ifdef RESET_ON_CTRLC
/* Check for "reset" */ /* Check for "reset" */
if (recv_buf[recv_ndx_nxt] == '\003') { if (recv_buf[recv_ndx_nxt] == '\003') {
/* reset the system /* reset the system volatile definition of
* volatile definition of return address on the stack * return address on the stack to insure it
* to insure it gets stored, changed to point to * gets stored, changed to point to the
* the trampoline function (do_the_nasty) which is * trampoline function (do_the_nasty) which is
* required because we need to return of an interrupt * required because we need to return of an
* to get the internal value of the LR register reset * interrupt to get the internal value of the
* and put the processor back into "Thread" mode from * LR register reset and put the processor back
* "Handler" mode. * into "Thread" mode from "Handler" mode.
* *
* See the PM0214 Programming Manual for Cortex M, * See the PM0214 Programming Manual for Cortex
* pg 42, to see the format of the Cortex M4 stack after * M, pg 42, to see the format of the Cortex M4
* an interrupt or exception has occurred. * stack after an interrupt or exception has
* occurred.
*/ */
volatile uint32_t *ret = (&reg) + 7; volatile uint32_t *ret = (&reg) + 7;
*ret = (uint32_t) &do_the_nasty; *ret = (uint32_t) &do_the_nasty;
return; return;
} }
@@ -143,7 +146,8 @@ void usart1_isr(void) {
recv_ndx_nxt = i; recv_ndx_nxt = i;
} }
} }
} while ((reg & USART_SR_RXNE) != 0); // can read back-to-back interrupts } while ((reg & USART_SR_RXNE) != 0); /* can read back-to-back
interrupts */
} }
/* /*
@@ -152,7 +156,8 @@ void usart1_isr(void) {
* Send the character 'c' to the USART, wait for the USART * Send the character 'c' to the USART, wait for the USART
* transmit buffer to be empty first. * transmit buffer to be empty first.
*/ */
void console_putc(char c) { void console_putc(char c)
{
uint32_t reg; uint32_t reg;
do { do {
reg = USART_SR(CONSOLE_UART); reg = USART_SR(CONSOLE_UART);
@@ -170,10 +175,11 @@ void console_putc(char c) {
* The implementation is a bit different however, now it looks * The implementation is a bit different however, now it looks
* in the ring buffer to see if a character has arrived. * in the ring buffer to see if a character has arrived.
*/ */
char console_getc(int wait) { char console_getc(int wait)
{
char c = 0; char c = 0;
while ((wait != 0) && (recv_ndx_cur == recv_ndx_nxt)) ; while ((wait != 0) && (recv_ndx_cur == recv_ndx_nxt));
if (recv_ndx_cur != recv_ndx_nxt) { if (recv_ndx_cur != recv_ndx_nxt) {
c = recv_buf[recv_ndx_cur]; c = recv_buf[recv_ndx_cur];
recv_ndx_cur = (recv_ndx_cur + 1) % RECV_BUF_SIZE; recv_ndx_cur = (recv_ndx_cur + 1) % RECV_BUF_SIZE;
@@ -188,7 +194,8 @@ char console_getc(int wait) {
* after the last character, as indicated by a NUL character, is * after the last character, as indicated by a NUL character, is
* reached. * reached.
*/ */
void console_puts(char *s) { void console_puts(char *s)
{
while (*s != '\000') { while (*s != '\000') {
console_putc(*s); console_putc(*s);
/* Add in a carraige return, after sending line feed */ /* Add in a carraige return, after sending line feed */
@@ -206,7 +213,8 @@ void console_puts(char *s) {
* support for editing characters (back space and delete) * support for editing characters (back space and delete)
* end when a <CR> character is received. * end when a <CR> character is received.
*/ */
int console_gets(char *s, int len) { int console_gets(char *s, int len)
{
char *t = s; char *t = s;
char c; char c;
@@ -229,7 +237,7 @@ int console_gets(char *s, int len) {
/* update end of string with NUL */ /* update end of string with NUL */
*t = '\000'; *t = '\000';
} }
return (t - s); return t - s;
} }
void countdown(void); void countdown(void);
@@ -244,16 +252,17 @@ void countdown(void);
* however with the interrupt driven receieve queue you can type * however with the interrupt driven receieve queue you can type
* ^C while it is counting down and it will be interrupted. * ^C while it is counting down and it will be interrupted.
*/ */
void countdown(void) { void countdown(void)
{
int i = 200; int i = 200;
while (i-- > 0) { while (i-- > 0) {
console_puts("Countdown: "); console_puts("Countdown: ");
console_putc( (i / 600) + '0'); console_putc((i / 600) + '0');
console_putc(':'); console_putc(':');
console_putc( ((i % 600) / 100) + '0'); console_putc(((i % 600) / 100) + '0');
console_putc( (((i % 600) / 10) % 10) + '0'); console_putc((((i % 600) / 10) % 10) + '0');
console_putc('.'); console_putc('.');
console_putc( ((i % 600) % 10) + '0'); console_putc(((i % 600) % 10) + '0');
console_putc('\r'); console_putc('\r');
msleep(100); msleep(100);
} }
@@ -264,12 +273,13 @@ void countdown(void) {
* on some of the pins, in this case connected to a * on some of the pins, in this case connected to a
* USART. * USART.
*/ */
int main(void) { int main(void)
{
char buf[128]; char buf[128];
int len; int len;
bool pmask; bool pmask;
clock_setup(); // initialize our clock clock_setup(); /* initialize our clock */
/* MUST enable the GPIO clock in ADDITION to the USART clock */ /* MUST enable the GPIO clock in ADDITION to the USART clock */
rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOA);
@@ -328,7 +338,8 @@ int main(void) {
if (len) { if (len) {
if (buf[0] == 'c') { if (buf[0] == 'c') {
console_puts("\n"); console_puts("\n");
countdown(); // long running thing (20 seconds) countdown(); /* long running thing (20
seconds) */
} }
console_puts("\nYou entered : '"); console_puts("\nYou entered : '");
console_puts(buf); console_puts(buf);

View File

@@ -159,7 +159,7 @@ static const struct usb_config_descriptor config = {
.interface = ifaces, .interface = ifaces,
}; };
static const char * usb_strings[] = { static const char *usb_strings[] = {
"Black Sphere Technologies", "Black Sphere Technologies",
"CDC-ACM Demo", "CDC-ACM Demo",
"DEMO", "DEMO",

View File

@@ -117,7 +117,7 @@ static const struct {
} __attribute__((packed)) audio_control_functional_descriptors = { } __attribute__((packed)) audio_control_functional_descriptors = {
.header_head = { .header_head = {
.bLength = sizeof(struct usb_audio_header_descriptor_head) + .bLength = sizeof(struct usb_audio_header_descriptor_head) +
1 * sizeof(struct usb_audio_header_descriptor_body), 1 * sizeof(struct usb_audio_header_descriptor_body),
.bDescriptorType = USB_AUDIO_DT_CS_INTERFACE, .bDescriptorType = USB_AUDIO_DT_CS_INTERFACE,
.bDescriptorSubtype = USB_AUDIO_TYPE_HEADER, .bDescriptorSubtype = USB_AUDIO_TYPE_HEADER,
.bcdADC = 0x0100, .bcdADC = 0x0100,
@@ -268,7 +268,7 @@ static const struct usb_config_descriptor config = {
.interface = ifaces, .interface = ifaces,
}; };
static const char * usb_strings[] = { static const char *usb_strings[] = {
"libopencm3.org", "libopencm3.org",
"MIDI demo", "MIDI demo",
}; };

View File

@@ -59,7 +59,7 @@ static const struct usb_endpoint_descriptor msc_endp[] = {{
.bmAttributes = USB_ENDPOINT_ATTR_BULK, .bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = 64, .wMaxPacketSize = 64,
.bInterval = 0, .bInterval = 0,
}}; } };
static const struct usb_interface_descriptor msc_iface[] = {{ static const struct usb_interface_descriptor msc_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE, .bLength = USB_DT_INTERFACE_SIZE,
@@ -74,12 +74,12 @@ static const struct usb_interface_descriptor msc_iface[] = {{
.endpoint = msc_endp, .endpoint = msc_endp,
.extra = NULL, .extra = NULL,
.extralen = 0 .extralen = 0
}}; } };
static const struct usb_interface ifaces[] = {{ static const struct usb_interface ifaces[] = {{
.num_altsetting = 1, .num_altsetting = 1,
.altsetting = msc_iface, .altsetting = msc_iface,
}}; } };
static const struct usb_config_descriptor config_descr = { static const struct usb_config_descriptor config_descr = {
.bLength = USB_DT_CONFIGURATION_SIZE, .bLength = USB_DT_CONFIGURATION_SIZE,

View File

@@ -22,10 +22,10 @@
#include "ramdisk.h" #include "ramdisk.h"
#define WBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF) #define WBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF)
#define QBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF),\ #define QBVAL(x) ((x) & 0xFF), (((x) >> 8) & 0xFF), \
(((x) >> 16) & 0xFF), (((x) >> 24) & 0xFF) (((x) >> 16) & 0xFF), (((x) >> 24) & 0xFF)
// filesystem size is 512kB (1024 * SECTOR_SIZE) /* filesystem size is 512kB (1024 * SECTOR_SIZE) */
#define SECTOR_COUNT 1024 #define SECTOR_COUNT 1024
#define SECTOR_SIZE 512 #define SECTOR_SIZE 512
#define BYTES_PER_SECTOR 512 #define BYTES_PER_SECTOR 512
@@ -40,30 +40,30 @@
#define FILEDATA_START_SECTOR (DATA_REGION_SECTOR + \ #define FILEDATA_START_SECTOR (DATA_REGION_SECTOR + \
(FILEDATA_START_CLUSTER - 2) * SECTORS_PER_CLUSTER) (FILEDATA_START_CLUSTER - 2) * SECTORS_PER_CLUSTER)
// filesize is 64kB (128 * SECTOR_SIZE) /* filesize is 64kB (128 * SECTOR_SIZE) */
#define FILEDATA_SECTOR_COUNT 128 #define FILEDATA_SECTOR_COUNT 128
uint8_t BootSector[] = { uint8_t BootSector[] = {
0xEB, 0x3C, 0x90, // code to jump to the bootstrap code 0xEB, 0x3C, 0x90, /* code to jump to the bootstrap code */
'm', 'k', 'd', 'o', 's', 'f', 's', 0x00, // OEM ID 'm', 'k', 'd', 'o', 's', 'f', 's', 0x00, /* OEM ID */
WBVAL(BYTES_PER_SECTOR), // bytes per sector WBVAL(BYTES_PER_SECTOR), /* bytes per sector */
SECTORS_PER_CLUSTER, // sectors per cluster SECTORS_PER_CLUSTER, /* sectors per cluster */
WBVAL(RESERVED_SECTORS), // # of reserved sectors (1 boot sector) WBVAL(RESERVED_SECTORS), /* # of reserved sectors (1 boot sector) */
FAT_COPIES, // FAT copies (2) FAT_COPIES, /* FAT copies (2) */
WBVAL(ROOT_ENTRIES), // root entries (512) WBVAL(ROOT_ENTRIES), /* root entries (512) */
WBVAL(SECTOR_COUNT), // total number of sectors WBVAL(SECTOR_COUNT), /* total number of sectors */
0xF8, // media descriptor (0xF8 = Fixed disk) 0xF8, /* media descriptor (0xF8 = Fixed disk) */
0x01, 0x00, // sectors per FAT (1) 0x01, 0x00, /* sectors per FAT (1) */
0x20, 0x00, // sectors per track (32) 0x20, 0x00, /* sectors per track (32) */
0x40, 0x00, // number of heads (64) 0x40, 0x00, /* number of heads (64) */
0x00, 0x00, 0x00, 0x00, // hidden sectors (0) 0x00, 0x00, 0x00, 0x00, /* hidden sectors (0) */
0x00, 0x00, 0x00, 0x00, // large number of sectors (0) 0x00, 0x00, 0x00, 0x00, /* large number of sectors (0) */
0x00, // drive number (0) 0x00, /* drive number (0) */
0x00, // reserved 0x00, /* reserved */
0x29, // extended boot signature 0x29, /* extended boot signature */
0x69, 0x17, 0xAD, 0x53, // volume serial number 0x69, 0x17, 0xAD, 0x53, /* volume serial number */
'R', 'A', 'M', 'D', 'I', 'S', 'K', ' ', ' ', ' ', ' ', // volume label 'R', 'A', 'M', 'D', 'I', 'S', 'K', ' ', ' ', ' ', ' ', /* volume label */
'F', 'A', 'T', '1', '2', ' ', ' ', ' ' // filesystem type 'F', 'A', 'T', '1', '2', ' ', ' ', ' ' /* filesystem type */
}; };
uint8_t FatSector[] = { uint8_t FatSector[] = {
@@ -92,29 +92,29 @@ uint8_t FatSector[] = {
}; };
uint8_t DirSector[] = { uint8_t DirSector[] = {
// long filename entry /* long filename entry */
0x41, // sequence number 0x41, /* sequence number */
WBVAL('r'), WBVAL('a'), WBVAL('m'), WBVAL('d'), WBVAL('i'), // five name characters in UTF-16 WBVAL('r'), WBVAL('a'), WBVAL('m'), WBVAL('d'), WBVAL('i'), /* five name characters in UTF-16 */
0x0F, // attributes 0x0F, /* attributes */
0x00, // type 0x00, /* type */
0x00, // checksum of DOS filename (computed in ramdisk_init) 0x00, /* checksum of DOS filename (computed in ramdisk_init) */
WBVAL('s'), WBVAL('k'), WBVAL('.'), WBVAL('d'), WBVAL('a'), WBVAL('t'), // six name characters in UTF-16 WBVAL('s'), WBVAL('k'), WBVAL('.'), WBVAL('d'), WBVAL('a'), WBVAL('t'), /* six name characters in UTF-16 */
0x00, 0x00, // first cluster 0x00, 0x00, /* first cluster */
WBVAL(0), WBVAL(0), // two name characters in UTF-16 WBVAL(0), WBVAL(0), /* two name characters in UTF-16 */
// actual entry /* actual entry */
'R', 'A', 'M', 'D', 'I', 'S', 'K', ' ', // filename 'R', 'A', 'M', 'D', 'I', 'S', 'K', ' ', /* filename */
'D', 'A', 'T', // extension 'D', 'A', 'T', /* extension */
0x20, // attribute byte 0x20, /* attribute byte */
0x00, // reserved for Windows NT 0x00, /* reserved for Windows NT */
0x00, // creation millisecond 0x00, /* creation millisecond */
0xCE, 0x01, // creation time 0xCE, 0x01, /* creation time */
0x86, 0x41, // creation date 0x86, 0x41, /* creation date */
0x86, 0x41, // last access date 0x86, 0x41, /* last access date */
0x00, 0x00, // reserved for FAT32 0x00, 0x00, /* reserved for FAT32 */
0xCE, 0x01, // last write time 0xCE, 0x01, /* last write time */
0x86, 0x41, // last write date 0x86, 0x41, /* last write date */
WBVAL(FILEDATA_START_CLUSTER), // start cluster WBVAL(FILEDATA_START_CLUSTER), /* start cluster */
QBVAL(FILEDATA_SECTOR_COUNT * SECTOR_SIZE) // file size in bytes QBVAL(FILEDATA_SECTOR_COUNT * SECTOR_SIZE) /* file size in bytes */
}; };
static uint8_t ramdata[FILEDATA_SECTOR_COUNT * SECTOR_SIZE]; static uint8_t ramdata[FILEDATA_SECTOR_COUNT * SECTOR_SIZE];
@@ -123,18 +123,18 @@ int ramdisk_init(void)
{ {
uint32_t i = 0; uint32_t i = 0;
// compute checksum in the directory entry /* compute checksum in the directory entry */
uint8_t chk = 0; uint8_t chk = 0;
for (i = 32; i < 43; i++) { for (i = 32; i < 43; i++) {
chk = (((chk & 1) << 7) | ((chk & 0xFE) >> 1)) + DirSector[i]; chk = (((chk & 1) << 7) | ((chk & 0xFE) >> 1)) + DirSector[i];
} }
DirSector[13] = chk; DirSector[13] = chk;
// fill ramdata /* fill ramdata */
const uint8_t text[] = "USB Mass Storage Class example. "; const uint8_t text[] = "USB Mass Storage Class example. ";
i = 0; i = 0;
while (i < sizeof(ramdata)) { while (i < sizeof(ramdata)) {
ramdata[i] = text[i % (sizeof(text) -1)]; ramdata[i] = text[i % (sizeof(text) - 1)];
i++; i++;
} }
return 0; return 0;
@@ -144,24 +144,28 @@ int ramdisk_read(uint32_t lba, uint8_t *copy_to)
{ {
memset(copy_to, 0, SECTOR_SIZE); memset(copy_to, 0, SECTOR_SIZE);
switch (lba) { switch (lba) {
case 0: // sector 0 is the boot sector case 0: /* sector 0 is the boot sector */
memcpy(copy_to, BootSector, sizeof(BootSector)); memcpy(copy_to, BootSector, sizeof(BootSector));
copy_to[SECTOR_SIZE - 2] = 0x55; copy_to[SECTOR_SIZE - 2] = 0x55;
copy_to[SECTOR_SIZE - 1] = 0xAA; copy_to[SECTOR_SIZE - 1] = 0xAA;
break; break;
case 1: // sector 1 is FAT 1st copy case 1: /* sector 1 is FAT 1st copy */
case 2: // sector 2 is FAT 2nd copy case 2: /* sector 2 is FAT 2nd copy */
memcpy(copy_to, FatSector, sizeof(FatSector)); memcpy(copy_to, FatSector, sizeof(FatSector));
break; break;
case 3: // sector 3 is the directory entry case 3: /* sector 3 is the directory entry */
memcpy(copy_to, DirSector, sizeof(DirSector)); memcpy(copy_to, DirSector, sizeof(DirSector));
break; break;
default: default:
// ignore reads outside of the data section /* ignore reads outside of the data section */
if (lba >= FILEDATA_START_SECTOR && lba < FILEDATA_START_SECTOR + FILEDATA_SECTOR_COUNT) { if (lba >= FILEDATA_START_SECTOR &&
memcpy(copy_to, ramdata + (lba - FILEDATA_START_SECTOR) * SECTOR_SIZE, SECTOR_SIZE); lba < FILEDATA_START_SECTOR + FILEDATA_SECTOR_COUNT) {
} memcpy(copy_to, ramdata +
break; (lba - FILEDATA_START_SECTOR) *
SECTOR_SIZE,
SECTOR_SIZE);
}
break;
} }
return 0; return 0;
} }
@@ -170,7 +174,7 @@ int ramdisk_write(uint32_t lba, const uint8_t *copy_from)
{ {
(void)lba; (void)lba;
(void)copy_from; (void)copy_from;
// ignore writes /* ignore writes */
return 0; return 0;
} }