Initial code for screen access

/!\ Dirty, hacky version
This commit is contained in:
Emmanuel BENOîT 2012-11-04 16:24:46 +01:00
parent af7a78dd5e
commit 0ef7bcc1c8
11 changed files with 1988 additions and 0 deletions

221
07-BitBangDisplay/Makefile Normal file
View file

@ -0,0 +1,221 @@
PROJECT = BitBangDisplay
PRJ_C_SRC = main.c \
ssd1963.c
##############################################################################
# Build global options
# NOTE: Can be overridden externally.
#
# Compiler options here.
ifeq ($(USE_OPT),)
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
endif
# C specific options here (added to USE_OPT).
ifeq ($(USE_COPT),)
USE_COPT =
endif
# C++ specific options here (added to USE_OPT).
ifeq ($(USE_CPPOPT),)
USE_CPPOPT = -fno-rtti
endif
# Enable this if you want the linker to remove unused code and data
ifeq ($(USE_LINK_GC),)
USE_LINK_GC = yes
endif
# If enabled, this option allows to compile the application in THUMB mode.
ifeq ($(USE_THUMB),)
USE_THUMB = yes
endif
# Enable this if you want to see the full log while compiling.
ifeq ($(USE_VERBOSE_COMPILE),)
USE_VERBOSE_COMPILE = no
endif
#
# Build global options
##############################################################################
##############################################################################
# Architecture or project specific options
#
# Enables the use of FPU on Cortex-M4.
# Enable this if you really want to use the STM FWLib.
ifeq ($(USE_FPU),)
USE_FPU = no
endif
# Enable this if you really want to use the STM FWLib.
ifeq ($(USE_FWLIB),)
USE_FWLIB = no
endif
#
# Architecture or project specific options
##############################################################################
##############################################################################
# Project, sources and paths
#
# Imported source files and paths
CHIBIOS = ../ChibiOS
include $(CHIBIOS)/boards/ST_STM32F4_DISCOVERY/board.mk
include $(CHIBIOS)/os/hal/platforms/STM32F4xx/platform.mk
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F4xx/port.mk
include $(CHIBIOS)/os/kernel/kernel.mk
# Define linker script file here
LDSCRIPT= $(PORTLD)/STM32F407xG.ld
#LDSCRIPT= $(PORTLD)/STM32F407xG_CCM.ld
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CSRC = $(PORTSRC) \
$(KERNSRC) \
$(HALSRC) \
$(PLATFORMSRC) \
$(BOARDSRC) \
$(PRJ_C_SRC)
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CPPSRC =
# C sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACSRC =
# C++ sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACPPSRC =
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCSRC =
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCPPSRC =
# List ASM source files here
ASMSRC = $(PORTASM)
INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
$(HALINC) $(PLATFORMINC) $(BOARDINC) \
$(CHIBIOS)/os/various/devices_lib/accel \
$(CHIBIOS)/os/various
#
# Project, sources and paths
##############################################################################
##############################################################################
# Compiler settings
#
MCU = cortex-m4
#TRGT = arm-elf-
TRGT = arm-none-eabi-
CC = $(TRGT)gcc
CPPC = $(TRGT)g++
# Enable loading with g++ only if you need C++ runtime support.
# NOTE: You can use C++ even without C++ support if you are careful. C++
# runtime support makes code size explode.
LD = $(TRGT)gcc
#LD = $(TRGT)g++
CP = $(TRGT)objcopy
AS = $(TRGT)gcc -x assembler-with-cpp
OD = $(TRGT)objdump
HEX = $(CP) -O ihex
BIN = $(CP) -O binary
# ARM-specific options here
AOPT =
# THUMB-specific options here
TOPT = -mthumb -DTHUMB
# Define C warning options here
CWARN = -Wall -Wextra -Wstrict-prototypes
# Define C++ warning options here
CPPWARN = -Wall -Wextra
#
# Compiler settings
##############################################################################
##############################################################################
# Start of default section
#
# List all default C defines here, like -D_DEBUG=1
DDEFS =
# List all default ASM defines here, like -D_DEBUG=1
DADEFS =
# List all default directories to look for include files here
DINCDIR =
# List the default directory to look for the libraries here
DLIBDIR =
# List all default libraries here
DLIBS =
#
# End of default section
##############################################################################
##############################################################################
# Start of user section
#
# List all user C define here, like -D_DEBUG=1
UDEFS =
# Define ASM defines here
UADEFS =
# List all user directories here
UINCDIR =
# List the user directory to look for the libraries here
ULIBDIR =
# List all user libraries here
ULIBS =
#
# End of user defines
##############################################################################
ifeq ($(USE_FPU),yes)
USE_OPT += -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant
DDEFS += -DCORTEX_USE_FPU=TRUE
else
DDEFS += -DCORTEX_USE_FPU=FALSE
endif
ifeq ($(USE_FWLIB),yes)
include $(CHIBIOS)/ext/stm32lib/stm32lib.mk
CSRC += $(STM32SRC)
INCDIR += $(STM32INC)
USE_OPT += -DUSE_STDPERIPH_DRIVER
endif
include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk

535
07-BitBangDisplay/chconf.h Normal file
View file

@ -0,0 +1,535 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file templates/chconf.h
* @brief Configuration file template.
* @details A copy of this file must be placed in each project directory, it
* contains the application specific kernel settings.
*
* @addtogroup config
* @details Kernel related settings and hooks.
* @{
*/
#ifndef _CHCONF_H_
#define _CHCONF_H_
/*===========================================================================*/
/**
* @name Kernel parameters and options
* @{
*/
/*===========================================================================*/
/**
* @brief System tick frequency.
* @details Frequency of the system timer that drives the system ticks. This
* setting also defines the system tick time unit.
*/
#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
#define CH_FREQUENCY 1000
#endif
/**
* @brief Round robin interval.
* @details This constant is the number of system ticks allowed for the
* threads before preemption occurs. Setting this value to zero
* disables the preemption for threads with equal priority and the
* round robin becomes cooperative. Note that higher priority
* threads can still preempt, the kernel is always preemptive.
*
* @note Disabling the round robin preemption makes the kernel more compact
* and generally faster.
*/
#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
#define CH_TIME_QUANTUM 20
#endif
/**
* @brief Managed RAM size.
* @details Size of the RAM area to be managed by the OS. If set to zero
* then the whole available RAM is used. The core memory is made
* available to the heap allocator and/or can be used directly through
* the simplified core memory allocator.
*
* @note In order to let the OS manage the whole RAM the linker script must
* provide the @p __heap_base__ and @p __heap_end__ symbols.
* @note Requires @p CH_USE_MEMCORE.
*/
#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
#define CH_MEMCORE_SIZE 0
#endif
/**
* @brief Idle thread automatic spawn suppression.
* @details When this option is activated the function @p chSysInit()
* does not spawn the idle thread automatically. The application has
* then the responsibility to do one of the following:
* - Spawn a custom idle thread at priority @p IDLEPRIO.
* - Change the main() thread priority to @p IDLEPRIO then enter
* an endless loop. In this scenario the @p main() thread acts as
* the idle thread.
* .
* @note Unless an idle thread is spawned the @p main() thread must not
* enter a sleep state.
*/
#if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__)
#define CH_NO_IDLE_THREAD FALSE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Performance options
* @{
*/
/*===========================================================================*/
/**
* @brief OS optimization.
* @details If enabled then time efficient rather than space efficient code
* is used when two possible implementations exist.
*
* @note This is not related to the compiler optimization options.
* @note The default is @p TRUE.
*/
#if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__)
#define CH_OPTIMIZE_SPEED TRUE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Subsystem options
* @{
*/
/*===========================================================================*/
/**
* @brief Threads registry APIs.
* @details If enabled then the registry APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__)
#define CH_USE_REGISTRY TRUE
#endif
/**
* @brief Threads synchronization APIs.
* @details If enabled then the @p chThdWait() function is included in
* the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
#define CH_USE_WAITEXIT TRUE
#endif
/**
* @brief Semaphores APIs.
* @details If enabled then the Semaphores APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
#define CH_USE_SEMAPHORES TRUE
#endif
/**
* @brief Semaphores queuing mode.
* @details If enabled then the threads are enqueued on semaphores by
* priority rather than in FIFO order.
*
* @note The default is @p FALSE. Enable this if you have special requirements.
* @note Requires @p CH_USE_SEMAPHORES.
*/
#if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__)
#define CH_USE_SEMAPHORES_PRIORITY FALSE
#endif
/**
* @brief Atomic semaphore API.
* @details If enabled then the semaphores the @p chSemSignalWait() API
* is included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_SEMAPHORES.
*/
#if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__)
#define CH_USE_SEMSW TRUE
#endif
/**
* @brief Mutexes APIs.
* @details If enabled then the mutexes APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
#define CH_USE_MUTEXES TRUE
#endif
/**
* @brief Conditional Variables APIs.
* @details If enabled then the conditional variables APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_MUTEXES.
*/
#if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__)
#define CH_USE_CONDVARS TRUE
#endif
/**
* @brief Conditional Variables APIs with timeout.
* @details If enabled then the conditional variables APIs with timeout
* specification are included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_CONDVARS.
*/
#if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__)
#define CH_USE_CONDVARS_TIMEOUT TRUE
#endif
/**
* @brief Events Flags APIs.
* @details If enabled then the event flags APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
#define CH_USE_EVENTS TRUE
#endif
/**
* @brief Events Flags APIs with timeout.
* @details If enabled then the events APIs with timeout specification
* are included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_EVENTS.
*/
#if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__)
#define CH_USE_EVENTS_TIMEOUT TRUE
#endif
/**
* @brief Synchronous Messages APIs.
* @details If enabled then the synchronous messages APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
#define CH_USE_MESSAGES TRUE
#endif
/**
* @brief Synchronous Messages queuing mode.
* @details If enabled then messages are served by priority rather than in
* FIFO order.
*
* @note The default is @p FALSE. Enable this if you have special requirements.
* @note Requires @p CH_USE_MESSAGES.
*/
#if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__)
#define CH_USE_MESSAGES_PRIORITY FALSE
#endif
/**
* @brief Mailboxes APIs.
* @details If enabled then the asynchronous messages (mailboxes) APIs are
* included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_SEMAPHORES.
*/
#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
#define CH_USE_MAILBOXES TRUE
#endif
/**
* @brief I/O Queues APIs.
* @details If enabled then the I/O queues APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__)
#define CH_USE_QUEUES TRUE
#endif
/**
* @brief Core Memory Manager APIs.
* @details If enabled then the core memory manager APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__)
#define CH_USE_MEMCORE TRUE
#endif
/**
* @brief Heap Allocator APIs.
* @details If enabled then the memory heap allocator APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or
* @p CH_USE_SEMAPHORES.
* @note Mutexes are recommended.
*/
#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
#define CH_USE_HEAP TRUE
#endif
/**
* @brief C-runtime allocator.
* @details If enabled the the heap allocator APIs just wrap the C-runtime
* @p malloc() and @p free() functions.
*
* @note The default is @p FALSE.
* @note Requires @p CH_USE_HEAP.
* @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
* appropriate documentation.
*/
#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
#define CH_USE_MALLOC_HEAP FALSE
#endif
/**
* @brief Memory Pools Allocator APIs.
* @details If enabled then the memory pools allocator APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
#define CH_USE_MEMPOOLS TRUE
#endif
/**
* @brief Dynamic Threads APIs.
* @details If enabled then the dynamic threads creation APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_USE_WAITEXIT.
* @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS.
*/
#if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__)
#define CH_USE_DYNAMIC TRUE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Debug options
* @{
*/
/*===========================================================================*/
/**
* @brief Debug option, system state check.
* @details If enabled the correct call protocol for system APIs is checked
* at runtime.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
#endif
/**
* @brief Debug option, parameters checks.
* @details If enabled then the checks on the API functions input
* parameters are activated.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* @brief Debug option, consistency checks.
* @details If enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel,
* runtime anomalies and port-defined checks.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_ASSERTS FALSE
#endif
/**
* @brief Debug option, trace buffer.
* @details If enabled then the context switch circular trace buffer is
* activated.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_TRACE FALSE
#endif
/**
* @brief Debug option, stack checks.
* @details If enabled then a runtime stack check is performed.
*
* @note The default is @p FALSE.
* @note The stack check is performed in a architecture/port dependent way.
* It may not be implemented or some ports.
* @note The default failure mode is to halt the system with the global
* @p panic_msg variable set to @p NULL.
*/
#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
#define CH_DBG_ENABLE_STACK_CHECK FALSE
#endif
/**
* @brief Debug option, stacks initialization.
* @details If enabled then the threads working area is filled with a byte
* value when a thread is created. This can be useful for the
* runtime measurement of the used stack.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
#define CH_DBG_FILL_THREADS FALSE
#endif
/**
* @brief Debug option, threads profiling.
* @details If enabled then a field is added to the @p Thread structure that
* counts the system ticks occurred while executing the thread.
*
* @note The default is @p TRUE.
* @note This debug option is defaulted to TRUE because it is required by
* some test cases into the test suite.
*/
#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
#define CH_DBG_THREADS_PROFILING TRUE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Kernel hooks
* @{
*/
/*===========================================================================*/
/**
* @brief Threads descriptor structure extension.
* @details User fields added to the end of the @p Thread structure.
*/
#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
#define THREAD_EXT_FIELDS \
/* Add threads custom fields here.*/
#endif
/**
* @brief Threads initialization hook.
* @details User initialization code added to the @p chThdInit() API.
*
* @note It is invoked from within @p chThdInit() and implicitly from all
* the threads creation APIs.
*/
#if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__)
#define THREAD_EXT_INIT_HOOK(tp) { \
/* Add threads initialization code here.*/ \
}
#endif
/**
* @brief Threads finalization hook.
* @details User finalization code added to the @p chThdExit() API.
*
* @note It is inserted into lock zone.
* @note It is also invoked when the threads simply return in order to
* terminate.
*/
#if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__)
#define THREAD_EXT_EXIT_HOOK(tp) { \
/* Add threads finalization code here.*/ \
}
#endif
/**
* @brief Context switch hook.
* @details This hook is invoked just before switching between threads.
*/
#if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__)
#define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \
/* System halt code here.*/ \
}
#endif
/**
* @brief Idle Loop hook.
* @details This hook is continuously invoked by the idle thread loop.
*/
#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
#define IDLE_LOOP_HOOK() { \
/* Idle loop code here.*/ \
}
#endif
/**
* @brief System tick event hook.
* @details This hook is invoked in the system tick handler immediately
* after processing the virtual timers queue.
*/
#if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__)
#define SYSTEM_TICK_EVENT_HOOK() { \
/* System tick event code here.*/ \
}
#endif
/**
* @brief System halt hook.
* @details This hook is invoked in case to a system halting error before
* the system is halted.
*/
#if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
#define SYSTEM_HALT_HOOK() { \
/* System halt code here.*/ \
}
#endif
/** @} */
/*===========================================================================*/
/* Port-specific settings (override port settings defaulted in chcore.h). */
/*===========================================================================*/
#endif /* _CHCONF_H_ */
/** @} */

View file

@ -0,0 +1,152 @@
#!/usr/bin/perl
use strict;
# Read input and generate pin definitions
open( INPUT , "pins.csv" ) or die;
my @pinDefs = ( );
my %byPort = ( );
my %fullMap = ( );
while ( <INPUT> ) {
chop;
my ($chip,$gpio) = split /\s+/;
my ($port,$pad);
$port = $pad = $gpio;
$port =~ s/^P(.).+/GPIO$1/;
$pad =~ s/^[^\d]+//;
$fullMap{$chip} = [ $port , $pad ];
$byPort{$port} = { } unless exists $byPort{$port};
$byPort{$port}->{$chip} = $pad;
push @pinDefs, "#define SSD1963_$chip\_PORT\t$port";
push @pinDefs, "#define SSD1963_$chip\_PAD\t$pad";
}
close INPUT;
open( OUTPUT , '>ssd1963_pins.h' ) or die;
print OUTPUT <<'EOF';
#ifndef _H_PINS_SSD1963_STM32F4
#define _H_PINS_SSD1963_STM32F4
// Pin definitions
EOF
print OUTPUT join("\n" , @pinDefs) . "\n";
# Generate initialisation code
print OUTPUT <<'EOF';
// Initialise all GPIO ports used by the SSD1963
#define _ssd1963_init_gpio(spd) \
do { \
EOF
foreach my $port ( keys %byPort ) {
my $mask = 0;
foreach my $chip ( keys %{ $byPort{$port} } ) {
$mask |= ( 1 << $fullMap{$chip}->[1] );
}
$mask = sprintf "0x%0.4x" , $mask;
print OUTPUT "\t\tpalSetGroupMode( $port , $mask , 0 , \\\n"
. "\t\t\tPAL_MODE_OUTPUT_PUSHPULL | spd ); \\\n";
}
print OUTPUT "\t} while ( 0 )\n";
# Generate macros for the various state pins
my @states = ( 'RESET' , 'CS' , 'RD' , 'WR' , 'RS' );
foreach my $state ( @states ) {
print OUTPUT "\n";
print OUTPUT "#define _ssd1963_set_" . lc( $state )
. " \\\n\tpalSetPad( " . $fullMap{$state}->[0] . " , "
. $fullMap{$state}->[1] . " )\n";
print OUTPUT "#define _ssd1963_clear_" . lc( $state )
. " \\\n\tpalClearPad( " . $fullMap{$state}->[0] . " , "
. $fullMap{$state}->[1] . " )\n";
}
# Generate the macro that sets all data pins
# For each GPIO port
# Find all Dx pins on that port
print OUTPUT <<'EOF';
// Write to the SSD1963's data ports
#define _ssd1963_write(in) \
do { \
EOF
foreach my $port ( keys %byPort ) {
my %dataPads = ( );
for ( my $d = 0 ; $d < 16 ; $d ++ ) {
$dataPads{$d} = $byPort{$port}->{"D$d"}
if exists $byPort{$port}->{"D$d"};
}
next unless %dataPads;
my $pStart = -1;
my ( $bEnd , $bStart ,$bit );
my @sequences = ( );
for ( $bit = 0 ; $bit < 16 ; $bit ++ ) {
if ( exists $dataPads{$bit} ) {
if ( $pStart == -1 ) {
$pStart = $dataPads{$bit};
$bEnd = $bit;
$bStart = $bit;
next;
} elsif ( $dataPads{$bit} == $dataPads{$bEnd} + 1 ) {
$bEnd = $bit;
next;
}
}
if ( $pStart != -1 ) {
push @sequences , {
startPad => $pStart ,
startBit => $bStart ,
nBits => $bEnd - $bStart + 1
};
$pStart = -1;
$bit --;
}
}
if ( $pStart != -1 ) {
push @sequences , {
startPad => $pStart ,
startBit => $bStart ,
nBits => $bEnd - $bStart + 1
};
}
my $outputMask = 0;
my @parts = ( );
foreach my $seq ( @sequences ) {
my $mask = 0;
for ( my $i = 0 ; $i < $seq->{nBits} ; $i ++ ) {
$mask <<= 1;
$mask |= 1;
}
my $padMask = $mask << $seq->{startPad};
$outputMask |= $mask << $seq->{startPad};
my $inputGet = "(in)";
if ( $seq->{startBit} > 0 ) {
$inputGet = "( $inputGet >> " . $seq->{startBit} . " )";
}
$inputGet = "( $inputGet & " . sprintf( '0x%0.4x' , $mask )
. " )";
if ( $seq->{startPad} > 0 ) {
$inputGet = "( $inputGet << " . $seq->{startPad} . " )";
}
push @parts , $inputGet;
}
print OUTPUT "\t\tpalWritePort( $port , ( palReadLatch( $port ) & ~( "
. sprintf( '0x%0.4x' , $outputMask ) . " ) ) \\\n\t\t\t| "
. join(" \\\n\t\t\t| " , @parts ) . " ); \\\n";
}
print OUTPUT <<'EOF';
} while ( 0 )
#endif //_H_PINS_SSD1963_STM32F4
EOF

349
07-BitBangDisplay/halconf.h Normal file
View file

@ -0,0 +1,349 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file templates/halconf.h
* @brief HAL configuration header.
* @details HAL configuration file, this file allows to enable or disable the
* various device drivers from your application. You may also use
* this file in order to override the device drivers default settings.
*
* @addtogroup HAL_CONF
* @{
*/
#ifndef _HALCONF_H_
#define _HALCONF_H_
#include "mcuconf.h"
/**
* @brief Enables the TM subsystem.
*/
#if !defined(HAL_USE_TM) || defined(__DOXYGEN__)
#define HAL_USE_TM FALSE
#endif
/**
* @brief Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL TRUE
#endif
/**
* @brief Enables the ADC subsystem.
*/
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC FALSE
#endif
/**
* @brief Enables the CAN subsystem.
*/
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN FALSE
#endif
/**
* @brief Enables the EXT subsystem.
*/
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
#define HAL_USE_EXT TRUE
#endif
/**
* @brief Enables the GPT subsystem.
*/
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
#define HAL_USE_GPT FALSE
#endif
/**
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C FALSE
#endif
/**
* @brief Enables the ICU subsystem.
*/
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
#define HAL_USE_ICU FALSE
#endif
/**
* @brief Enables the MAC subsystem.
*/
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
#define HAL_USE_MAC FALSE
#endif
/**
* @brief Enables the MMC_SPI subsystem.
*/
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
#define HAL_USE_MMC_SPI FALSE
#endif
/**
* @brief Enables the PWM subsystem.
*/
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM FALSE
#endif
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC FALSE
#endif
/**
* @brief Enables the SDC subsystem.
*/
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
#define HAL_USE_SDC FALSE
#endif
/**
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL FALSE
#endif
/**
* @brief Enables the SERIAL over USB subsystem.
*/
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB FALSE
#endif
/**
* @brief Enables the SPI subsystem.
*/
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
#define HAL_USE_SPI TRUE
#endif
/**
* @brief Enables the UART subsystem.
*/
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
#define HAL_USE_UART FALSE
#endif
/**
* @brief Enables the USB subsystem.
*/
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB FALSE
#endif
/*===========================================================================*/
/* ADC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
#define ADC_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* CAN driver related settings. */
/*===========================================================================*/
/**
* @brief Sleep mode related APIs inclusion switch.
*/
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE TRUE
#endif
/*===========================================================================*/
/* I2C driver related settings. */
/*===========================================================================*/
/**
* @brief Enables the mutual exclusion APIs on the I2C bus.
*/
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* MAC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
#define MAC_USE_EVENTS TRUE
#endif
/*===========================================================================*/
/* MMC_SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Block size for MMC transfers.
*/
#if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__)
#define MMC_SECTOR_SIZE 512
#endif
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
* This option is recommended also if the SPI driver does not
* use a DMA channel and heavily loads the CPU.
*/
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
#define MMC_NICE_WAITING TRUE
#endif
/**
* @brief Number of positive insertion queries before generating the
* insertion event.
*/
#if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__)
#define MMC_POLLING_INTERVAL 10
#endif
/**
* @brief Interval, in milliseconds, between insertion queries.
*/
#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
#define MMC_POLLING_DELAY 10
#endif
/**
* @brief Uses the SPI polled API for small data transfers.
* @details Polled transfers usually improve performance because it
* saves two context switches and interrupt servicing. Note
* that this option has no effect on large transfers which
* are always performed using DMAs/IRQs.
*/
#if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__)
#define MMC_USE_SPI_POLLING TRUE
#endif
/*===========================================================================*/
/* SDC driver related settings. */
/*===========================================================================*/
/**
* @brief Number of initialization attempts before rejecting the card.
* @note Attempts are performed at 10mS intervals.
*/
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY 100
#endif
/**
* @brief Include support for MMC cards.
* @note MMC support is not yet implemented so this option must be kept
* at @p FALSE.
*/
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
#define SDC_MMC_SUPPORT FALSE
#endif
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
*/
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SERIAL driver related settings. */
/*===========================================================================*/
/**
* @brief Default bit rate.
* @details Configuration parameter, this is the baud rate selected for the
* default configuration.
*/
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
#define SERIAL_DEFAULT_BITRATE 38400
#endif
/**
* @brief Serial buffers size.
* @details Configuration parameter, you can change the depth of the queue
* buffers depending on the requirements of your application.
* @note The default is 64 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16
#endif
/*===========================================================================*/
/* SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
#define SPI_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION FALSE
#endif
#endif /* _HALCONF_H_ */
/** @} */

40
07-BitBangDisplay/main.c Normal file
View file

@ -0,0 +1,40 @@
#include "ch.h"
#include "hal.h"
#include "ssd1963.h"
// This is called when the board boots up with the user button pressed. The
// idea is to enter this mode if the wrong SPI device has been used and flashing
// is no longer possible.
__attribute__ ((noreturn))
static void lockdown( void )
{
palSetPad( GPIOD , GPIOD_LED3 );
while (TRUE) {
// EMPTY
}
}
void display_off( void );
void display_test_pattern( u16 start_mask );
int main( void )
{
halInit();
chSysInit();
if ( palReadPad( GPIOA , GPIOA_BUTTON ) ) {
lockdown( );
}
ssd1963Init( );
int i = 0;
while (TRUE) {
display_test_pattern( 1 << i );
i = ( i + 1 ) % 16;
if ( palReadPad( GPIOA , GPIOA_BUTTON ) ) {
display_off( );
}
}
}

257
07-BitBangDisplay/mcuconf.h Normal file
View file

@ -0,0 +1,257 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* STM32F4xx drivers configuration.
* The following settings override the default settings present in
* the various device driver implementation headers.
* Note that the settings for each driver only have effect if the whole
* driver is enabled in halconf.h.
*
* IRQ priorities:
* 15...0 Lowest...Highest.
*
* DMA priorities:
* 0...3 Lowest...Highest.
*/
#define STM32F4xx_MCUCONF
/*
* HAL driver system settings.
*/
#define STM32_NO_INIT FALSE
#define STM32_HSI_ENABLED TRUE
#define STM32_LSI_ENABLED TRUE
#define STM32_HSE_ENABLED TRUE
#define STM32_LSE_ENABLED FALSE
#define STM32_CLOCK48_REQUIRED TRUE
#define STM32_SW STM32_SW_PLL
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_PLLM_VALUE 8
#define STM32_PLLN_VALUE 336
#define STM32_PLLP_VALUE 2
#define STM32_PLLQ_VALUE 7
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE1 STM32_PPRE1_DIV4
#define STM32_PPRE2 STM32_PPRE2_DIV2
#define STM32_RTCSEL STM32_RTCSEL_LSI
#define STM32_RTCPRE_VALUE 8
#define STM32_MCO1SEL STM32_MCO1SEL_HSI
#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
#define STM32_I2SSRC STM32_I2SSRC_CKIN
#define STM32_PLLI2SN_VALUE 192
#define STM32_PLLI2SR_VALUE 5
#define STM32_VOS STM32_VOS_HIGH
#define STM32_PVD_ENABLE FALSE
#define STM32_PLS STM32_PLS_LEV0
/*
* ADC driver system settings.
*/
#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV4
#define STM32_ADC_USE_ADC1 FALSE
#define STM32_ADC_USE_ADC2 FALSE
#define STM32_ADC_USE_ADC3 FALSE
#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
#define STM32_ADC_ADC1_DMA_PRIORITY 2
#define STM32_ADC_ADC2_DMA_PRIORITY 2
#define STM32_ADC_ADC3_DMA_PRIORITY 2
#define STM32_ADC_IRQ_PRIORITY 6
#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6
#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 6
#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 6
/*
* CAN driver system settings.
*/
#define STM32_CAN_USE_CAN1 FALSE
#define STM32_CAN_USE_CAN2 FALSE
#define STM32_CAN_CAN1_IRQ_PRIORITY 11
#define STM32_CAN_CAN2_IRQ_PRIORITY 11
/*
* EXT driver system settings.
*/
#define STM32_EXT_EXTI0_IRQ_PRIORITY 6
#define STM32_EXT_EXTI1_IRQ_PRIORITY 6
#define STM32_EXT_EXTI2_IRQ_PRIORITY 6
#define STM32_EXT_EXTI3_IRQ_PRIORITY 6
#define STM32_EXT_EXTI4_IRQ_PRIORITY 6
#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6
#define STM32_EXT_EXTI16_IRQ_PRIORITY 6
#define STM32_EXT_EXTI17_IRQ_PRIORITY 15
#define STM32_EXT_EXTI18_IRQ_PRIORITY 6
#define STM32_EXT_EXTI19_IRQ_PRIORITY 6
#define STM32_EXT_EXTI20_IRQ_PRIORITY 6
#define STM32_EXT_EXTI21_IRQ_PRIORITY 15
#define STM32_EXT_EXTI22_IRQ_PRIORITY 15
/*
* GPT driver system settings.
*/
#define STM32_GPT_USE_TIM1 FALSE
#define STM32_GPT_USE_TIM2 FALSE
#define STM32_GPT_USE_TIM3 FALSE
#define STM32_GPT_USE_TIM4 FALSE
#define STM32_GPT_USE_TIM5 FALSE
#define STM32_GPT_USE_TIM8 FALSE
#define STM32_GPT_TIM1_IRQ_PRIORITY 7
#define STM32_GPT_TIM2_IRQ_PRIORITY 7
#define STM32_GPT_TIM3_IRQ_PRIORITY 7
#define STM32_GPT_TIM4_IRQ_PRIORITY 7
#define STM32_GPT_TIM5_IRQ_PRIORITY 7
#define STM32_GPT_TIM8_IRQ_PRIORITY 7
/*
* I2C driver system settings.
*/
#define STM32_I2C_USE_I2C1 FALSE
#define STM32_I2C_USE_I2C2 FALSE
#define STM32_I2C_USE_I2C3 FALSE
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
#define STM32_I2C_I2C1_IRQ_PRIORITY 5
#define STM32_I2C_I2C2_IRQ_PRIORITY 5
#define STM32_I2C_I2C3_IRQ_PRIORITY 5
#define STM32_I2C_I2C1_DMA_PRIORITY 3
#define STM32_I2C_I2C2_DMA_PRIORITY 3
#define STM32_I2C_I2C3_DMA_PRIORITY 3
#define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt()
#define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt()
#define STM32_I2C_I2C3_DMA_ERROR_HOOK() chSysHalt()
/*
* ICU driver system settings.
*/
#define STM32_ICU_USE_TIM1 FALSE
#define STM32_ICU_USE_TIM2 FALSE
#define STM32_ICU_USE_TIM3 FALSE
#define STM32_ICU_USE_TIM4 FALSE
#define STM32_ICU_USE_TIM5 FALSE
#define STM32_ICU_USE_TIM8 FALSE
#define STM32_ICU_TIM1_IRQ_PRIORITY 7
#define STM32_ICU_TIM2_IRQ_PRIORITY 7
#define STM32_ICU_TIM3_IRQ_PRIORITY 7
#define STM32_ICU_TIM4_IRQ_PRIORITY 7
#define STM32_ICU_TIM5_IRQ_PRIORITY 7
#define STM32_ICU_TIM8_IRQ_PRIORITY 7
/*
* PWM driver system settings.
*/
#define STM32_PWM_USE_ADVANCED FALSE
#define STM32_PWM_USE_TIM1 FALSE
#define STM32_PWM_USE_TIM2 FALSE
#define STM32_PWM_USE_TIM3 FALSE
#define STM32_PWM_USE_TIM4 FALSE
#define STM32_PWM_USE_TIM5 FALSE
#define STM32_PWM_USE_TIM8 FALSE
#define STM32_PWM_TIM1_IRQ_PRIORITY 7
#define STM32_PWM_TIM2_IRQ_PRIORITY 7
#define STM32_PWM_TIM3_IRQ_PRIORITY 7
#define STM32_PWM_TIM4_IRQ_PRIORITY 7
#define STM32_PWM_TIM5_IRQ_PRIORITY 7
#define STM32_PWM_TIM8_IRQ_PRIORITY 7
/*
* SERIAL driver system settings.
*/
#define STM32_SERIAL_USE_USART1 FALSE
#define STM32_SERIAL_USE_USART2 FALSE
#define STM32_SERIAL_USE_USART3 FALSE
#define STM32_SERIAL_USE_UART4 FALSE
#define STM32_SERIAL_USE_UART5 FALSE
#define STM32_SERIAL_USE_USART6 FALSE
#define STM32_SERIAL_USART1_PRIORITY 12
#define STM32_SERIAL_USART2_PRIORITY 12
#define STM32_SERIAL_USART3_PRIORITY 12
#define STM32_SERIAL_UART4_PRIORITY 12
#define STM32_SERIAL_UART5_PRIORITY 12
#define STM32_SERIAL_USART6_PRIORITY 12
/*
* SPI driver system settings.
*/
#define STM32_SPI_USE_SPI1 TRUE
#define STM32_SPI_USE_SPI2 FALSE
#define STM32_SPI_USE_SPI3 FALSE
#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0)
#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
#define STM32_SPI_SPI1_DMA_PRIORITY 1
#define STM32_SPI_SPI2_DMA_PRIORITY 1
#define STM32_SPI_SPI3_DMA_PRIORITY 1
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
/*
* UART driver system settings.
*/
#define STM32_UART_USE_USART1 FALSE
#define STM32_UART_USE_USART2 FALSE
#define STM32_UART_USE_USART3 FALSE
#define STM32_UART_USE_USART6 FALSE
#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
#define STM32_UART_USART6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
#define STM32_UART_USART6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
#define STM32_UART_USART1_IRQ_PRIORITY 12
#define STM32_UART_USART2_IRQ_PRIORITY 12
#define STM32_UART_USART3_IRQ_PRIORITY 12
#define STM32_UART_USART6_IRQ_PRIORITY 12
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
#define STM32_UART_USART6_DMA_PRIORITY 0
#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
/*
* USB driver system settings.
*/
#define STM32_USB_USE_OTG1 FALSE
#define STM32_USB_USE_OTG2 FALSE
#define STM32_USB_OTG1_IRQ_PRIORITY 14
#define STM32_USB_OTG2_IRQ_PRIORITY 14
#define STM32_USB_OTG1_RX_FIFO_SIZE 512
#define STM32_USB_OTG2_RX_FIFO_SIZE 1024
#define STM32_USB_OTG_THREAD_PRIO LOWPRIO
#define STM32_USB_OTG_THREAD_STACK_SIZE 128
#define STM32_USB_OTGFIFO_FILL_BASEPRI 0

View file

@ -0,0 +1,21 @@
D0 PC6
D1 PC7
D2 PD0
D3 PD1
D4 PE7
D5 PE8
D6 PE9
D7 PE10
D8 PE11
D9 PE12
D10 PE13
D11 PE14
D12 PE15
D13 PD8
D14 PD9
D15 PD10
CS PD7
RS PD11
RD PD4
WR PD5
RESET PC5
1 D0 PC6
2 D1 PC7
3 D2 PD0
4 D3 PD1
5 D4 PE7
6 D5 PE8
7 D6 PE9
8 D7 PE10
9 D8 PE11
10 D9 PE12
11 D10 PE13
12 D11 PE14
13 D12 PE15
14 D13 PD8
15 D14 PD9
16 D15 PD10
17 CS PD7
18 RS PD11
19 RD PD4
20 WR PD5
21 RESET PC5

266
07-BitBangDisplay/ssd1963.c Normal file
View file

@ -0,0 +1,266 @@
#include "ch.h"
#include "hal.h"
#include "ssd1963.h"
#define _command 0x40
#define _delay 0x80
#define _ndata(x) ( (u8)( (x) & 0x3f) )
static const u8 _ssd1963_reset_sequence[ ] = {
/*
* PLL configuration
* -----------------
*
* PLL = input * ( P1 + 1 ) / ( P2 + 1 )
* (P1 : 8 bits ; P2 : 4 bits; P3 : junk)
*
* 1/ The ITDB02-4.3 board has a 12MHz crystal (which contradicts the
* SSD1963 datasheet - wtf?).
* 2/ The SSD1963 must be clocked at *at most* 110MHz.
* 3/ Also, 250MHz < input * ( P1 + 1 ) < 800MHz
* 4/ The STM32F4 can communicate at 50MHz.
* 5/ The SSD1963 accepts PLL/2 accesses per second.
*
* 100MHz = 12MHz * ( P1 + 1 ) / ( P2 + 1 )
* => P1 = 49, P2 = 5
* 100MHz = 10MHz * ( P1 + 1 ) / ( P2 + 1 )
* => P1 = 19, P2 = 1
*/
_command | _ndata(3) ,
SSD1963_CMD_SET_PLL_MN ,
0x31 , 0x05 , 0x04 ,
// 0x1e , 0x02 , 0x04 ,
// Enable PLL and wait until it's stable
_command | _delay | _ndata(1) ,
SSD1963_CMD_SET_PLL , 1 ,
1 ,
// Fully enable PLL
_command | _ndata(1) ,
SSD1963_CMD_SET_PLL , 3 ,
};
static const u8 _ssd1963_init_sequence[ ] = {
// Software reset
_command | _delay ,
SSD1963_CMD_SOFT_RESET ,
5 ,
/* Pixel clock: screw finesse, crank that up to the max */
_command | _ndata( 3 ) | _delay ,
SSD1963_CMD_SET_LSHIFT_FREQ ,
0x07 , 0xff , 0xff ,
15 ,
// Use 565 RGB format
_command | _delay | _ndata(1) ,
SSD1963_CMD_SET_PIXEL_FORMAT ,
0x03 ,
5 ,
// Setup LCD panel
_command | _ndata( 7 ) ,
SSD1963_CMD_SET_LCD_MODE ,
0x20 , // Data width 24-bit, FRC and dithering disabled
// Data latch on falling edge
// HSync polarity: active low
// VSync polarity: active low
0x00 , // TFT mode
// Width
( ( ( SSD1963_SCR_WIDTH - 1 ) >> 8 ) & 0xff ) ,
( ( SSD1963_SCR_WIDTH - 1 ) & 0xff ) ,
// Height
( ( ( SSD1963_SCR_HEIGHT - 1 ) >> 8 ) & 0xff ) ,
( ( SSD1963_SCR_HEIGHT - 1 ) & 0xff ) ,
0x00 , // Ignored (serial interface)
_command | _ndata( 8 ) ,
SSD1963_CMD_SET_HORI_PERIOD ,
0x02 , 0x13 , // Total period (PCLK)
0x00 , 0x08 , // Non-display period
0x2b , // Sync pulse width (PCLK)
0x00 , 0x02 , // Start location (PCLK)
0x00 , // Ignored (serial interfaces)
_command | _ndata( 7 ) ,
SSD1963_CMD_SET_VERT_PERIOD ,
0x01 , 0x20 , // Vertical total period
0x00 , 0x04 , // Non-display period
0x0c , // Sync pulse width
0x00 , 0x02 , // Start location
_command | _ndata(1) ,
0x36 ,
0x00 ,
_command ,
SSD1963_CMD_SET_DISPLAY_ON ,
_command | _ndata(6) ,
SSD1963_CMD_SET_PWM_CONF ,
0x06 , 0xf0 , 0x01 , 0xf0 , 0 , 0 ,
_command | _ndata(1) ,
0xd0 ,
0x0d ,
_command | _ndata(1) , SSD1963_CMD_SET_GAMMA_CURVE, 1 ,
//_command | SSD1963_CMD_ENTER_NORMAL_MODE ,
//_command | SSD1963_CMD_EXIT_INVERT_MODE ,
_command , SSD1963_CMD_EXIT_IDLE_MODE ,
/*
SSD1963_CMD_SET_TEAR_OFF ,
*/
};
#define _ssd1963_wcmd(command) \
do { \
_ssd1963_clear_rs; \
_ssd1963_write( command ); \
_ssd1963_clear_wr; \
_ssd1963_set_wr; \
} while ( FALSE )
#define _ssd1963_wdata(data) \
do { \
_ssd1963_set_rs; \
_ssd1963_write( data ); \
_ssd1963_clear_wr; \
_ssd1963_set_wr; \
} while ( FALSE )
void _ssd1963_run_sequence( const u8 * sequence , u32 size )
{
_ssd1963_clear_cs;
u32 addr = 0;
u8 has_command = 0 , has_data = 0 , has_delay = 0;
while ( addr < size ) {
if ( has_command ) {
u16 command = sequence[ addr ++ ];
_ssd1963_wcmd( command );
has_command = 0;
} else if ( has_data ) {
u16 data = sequence[ addr ++ ];
_ssd1963_wdata( data );
has_data --;
} else if ( has_delay ) {
u8 delay = sequence[ addr ++ ];
chThdSleep( delay );
has_delay = 0;
} else {
u8 value = sequence[ addr ++ ];
has_command = ( ( value & _command ) == _command );
has_delay = ( ( value & _delay ) == _delay );
has_data = value & ~( _command | _delay );
}
}
_ssd1963_set_cs;
}
void _ssd1963_reset_chip( void )
{
// Select and reset the chip
_ssd1963_set_reset;
_ssd1963_set_cs;
_ssd1963_set_rd;
_ssd1963_set_wr;
_ssd1963_clear_reset;
chThdSleep( 100 );
_ssd1963_set_reset;
chThdSleep( 100 );
// Run the PLL init sequence
_ssd1963_run_sequence( _ssd1963_reset_sequence ,
sizeof( _ssd1963_reset_sequence ) );
}
void _ssd1963_set_pos( u32 x , u32 y )
{
_ssd1963_wcmd( 0x2a );
_ssd1963_wdata( x >> 8 );
_ssd1963_wdata( x & 0xff );
_ssd1963_wdata( ( ( SSD1963_SCR_WIDTH - 1 ) >> 8 ) & 0xff );
_ssd1963_wdata( ( SSD1963_SCR_WIDTH - 1 ) & 0xff );
_ssd1963_wcmd( 0x2b );
_ssd1963_wdata( y >> 8 );
_ssd1963_wdata( y & 0xff );
_ssd1963_wdata( ( ( SSD1963_SCR_HEIGHT - 1 ) >> 8 ) & 0xff );
_ssd1963_wdata( ( SSD1963_SCR_HEIGHT - 1 ) & 0xff );
_ssd1963_wcmd( 0x2c );
}
void ssd1963Init( void )
{
_ssd1963_init_gpio( PAL_STM32_OSPEED_LOWEST );
chThdSleep( 10 );
_ssd1963_reset_chip( );
chThdSleep( 10 );
_ssd1963_init_gpio( PAL_STM32_OSPEED_HIGHEST );
_ssd1963_run_sequence( _ssd1963_init_sequence ,
sizeof( _ssd1963_init_sequence ) );
_ssd1963_clear_cs;
_ssd1963_set_pos( 0 , 0 );
int i;
for ( i = 0 ; i < SSD1963_SCR_HEIGHT ; i ++ ) {
u16 j , c = 0x8000;
for ( j = 0 ; j < SSD1963_SCR_WIDTH ; j ++ ) {
if ( ( j & 7 ) == 7 ) {
c >>= 1;
if ( !c ) {
c = 0x8000;
}
}
_ssd1963_wdata( c );
}
}
_ssd1963_set_cs;
}
void display_test_pattern( u16 start_mask )
{
_ssd1963_clear_cs;
_ssd1963_set_pos( 0 , 0 );
int i;
for ( i = 0 ; i < SSD1963_SCR_HEIGHT ; i ++ ) {
u16 j , c = start_mask;
for ( j = 0 ; j < SSD1963_SCR_WIDTH ; j ++ ) {
if ( ( j & 7 ) == 7 ) {
c >>= 1;
if ( !c ) {
c = 0x8000;
}
}
_ssd1963_wdata( c );
}
}
_ssd1963_set_cs;
}
void display_off( void )
{
static int display = 1;
display = !display;
_ssd1963_clear_cs;
if ( display ) {
_ssd1963_wcmd( SSD1963_CMD_SET_DISPLAY_ON );
} else {
_ssd1963_wcmd( SSD1963_CMD_SET_DISPLAY_OFF );
}
_ssd1963_set_cs;
}

View file

@ -0,0 +1,48 @@
#ifndef _H_SSD1963_STM32F4
#define _H_SSD1963_STM32F4
#include "ssd1963_pins.h"
// Screen width (pixels)
#define SSD1963_SCR_WIDTH 480
// Screen height (pixels)
#define SSD1963_SCR_HEIGHT 272
// Commands
#define SSD1963_CMD_ 0x00
#define SSD1963_CMD_NOP 0x00
#define SSD1963_CMD_SOFT_RESET 0x01
#define SSD1963_CMD_ENTER_SLEEP_MODE 0x10
#define SSD1963_CMD_ENTER_NORMAL_MODE 0x13
#define SSD1963_CMD_EXIT_INVERT_MODE 0x20
#define SSD1963_CMD_SET_GAMMA_CURVE 0x26
#define SSD1963_CMD_SET_DISPLAY_OFF 0x28
#define SSD1963_CMD_SET_DISPLAY_ON 0x29
#define SSD1963_CMD_SET_TEAR_OFF 0x34
#define SSD1963_CMD_EXIT_IDLE_MODE 0x38
#define SSD1963_CMD_SET_LCD_MODE 0xb0
#define SSD1963_CMD_SET_HORI_PERIOD 0xb4
#define SSD1963_CMD_SET_VERT_PERIOD 0xb6
#define SSD1963_CMD_SET_GPIO_VALUE 0xba
#define SSD1963_CMD_SET_POST_PROC 0xbc
#define SSD1963_CMD_SET_PWM_CONF 0xbe
#define SSD1963_CMD_SET_PLL 0xe0
#define SSD1963_CMD_SET_PLL_MN 0xe2
#define SSD1963_CMD_SET_LSHIFT_FREQ 0xe6
#define SSD1963_CMD_SET_PIXEL_FORMAT 0xf0
// Control and data ports
#define ssd1963Ctrl (*((__IO u16 *) 0x60000000))
#define ssd1963Data (*((__IO u16 *) 0x60020000))
// Initialise the display controller
void ssd1963Init( void );
#endif // _H_SSD1963_STM32F4

View file

@ -0,0 +1,97 @@
#ifndef _H_PINS_SSD1963_STM32F4
#define _H_PINS_SSD1963_STM32F4
// Pin definitions
#define SSD1963_D0_PORT GPIOC
#define SSD1963_D0_PAD 6
#define SSD1963_D1_PORT GPIOC
#define SSD1963_D1_PAD 7
#define SSD1963_D2_PORT GPIOD
#define SSD1963_D2_PAD 0
#define SSD1963_D3_PORT GPIOD
#define SSD1963_D3_PAD 1
#define SSD1963_D4_PORT GPIOE
#define SSD1963_D4_PAD 7
#define SSD1963_D5_PORT GPIOE
#define SSD1963_D5_PAD 8
#define SSD1963_D6_PORT GPIOE
#define SSD1963_D6_PAD 9
#define SSD1963_D7_PORT GPIOE
#define SSD1963_D7_PAD 10
#define SSD1963_D8_PORT GPIOE
#define SSD1963_D8_PAD 11
#define SSD1963_D9_PORT GPIOE
#define SSD1963_D9_PAD 12
#define SSD1963_D10_PORT GPIOE
#define SSD1963_D10_PAD 13
#define SSD1963_D11_PORT GPIOE
#define SSD1963_D11_PAD 14
#define SSD1963_D12_PORT GPIOE
#define SSD1963_D12_PAD 15
#define SSD1963_D13_PORT GPIOD
#define SSD1963_D13_PAD 8
#define SSD1963_D14_PORT GPIOD
#define SSD1963_D14_PAD 9
#define SSD1963_D15_PORT GPIOD
#define SSD1963_D15_PAD 10
#define SSD1963_CS_PORT GPIOD
#define SSD1963_CS_PAD 7
#define SSD1963_RS_PORT GPIOD
#define SSD1963_RS_PAD 11
#define SSD1963_RD_PORT GPIOD
#define SSD1963_RD_PAD 4
#define SSD1963_WR_PORT GPIOD
#define SSD1963_WR_PAD 5
#define SSD1963_RESET_PORT GPIOC
#define SSD1963_RESET_PAD 5
// Initialise all GPIO ports used by the SSD1963
#define _ssd1963_init_gpio(spd) \
do { \
palSetGroupMode( GPIOD , 0x0fb3 , 0 , \
PAL_MODE_OUTPUT_PUSHPULL | spd ); \
palSetGroupMode( GPIOC , 0x00e0 , 0 , \
PAL_MODE_OUTPUT_PUSHPULL | spd ); \
palSetGroupMode( GPIOE , 0xff80 , 0 , \
PAL_MODE_OUTPUT_PUSHPULL | spd ); \
} while ( 0 )
#define _ssd1963_set_reset \
palSetPad( GPIOC , 5 )
#define _ssd1963_clear_reset \
palClearPad( GPIOC , 5 )
#define _ssd1963_set_cs \
palSetPad( GPIOD , 7 )
#define _ssd1963_clear_cs \
palClearPad( GPIOD , 7 )
#define _ssd1963_set_rd \
palSetPad( GPIOD , 4 )
#define _ssd1963_clear_rd \
palClearPad( GPIOD , 4 )
#define _ssd1963_set_wr \
palSetPad( GPIOD , 5 )
#define _ssd1963_clear_wr \
palClearPad( GPIOD , 5 )
#define _ssd1963_set_rs \
palSetPad( GPIOD , 11 )
#define _ssd1963_clear_rs \
palClearPad( GPIOD , 11 )
// Write to the SSD1963's data ports
#define _ssd1963_write(in) \
do { \
palWritePort( GPIOD , ( palReadLatch( GPIOD ) & ~( 0x0703 ) ) \
| ( ( (in) >> 2 ) & 0x0003 ) \
| ( ( ( (in) >> 13 ) & 0x0007 ) << 8 ) ); \
palWritePort( GPIOC , ( palReadLatch( GPIOC ) & ~( 0x00c0 ) ) \
| ( ( (in) & 0x0003 ) << 6 ) ); \
palWritePort( GPIOE , ( palReadLatch( GPIOE ) & ~( 0xff80 ) ) \
| ( ( ( (in) >> 4 ) & 0x01ff ) << 7 ) ); \
} while ( 0 )
#endif //_H_PINS_SSD1963_STM32F4

View file

@ -14,3 +14,5 @@ Ok, anyways:
03-EXTIBlinky/ Same as above, using interrupts 03-EXTIBlinky/ Same as above, using interrupts
04-PokeScreen/ Same as above, controlled by poking a screen 04-PokeScreen/ Same as above, controlled by poking a screen
05-PWMLeds/ Flashing LEDs using PWM+TIM4 05-PWMLeds/ Flashing LEDs using PWM+TIM4
06-TouchScreen/ Reading data from the touchscreen
07-BitBangDisplay/ Bit-banging-based display access